【问题标题】:SQL HASHBYTES function returns weird output when used in CASE WHEN/IIFSQL HASHBYTES 函数在 CASE WHEN/IIF 中使用时返回奇怪的输出
【发布时间】:2018-05-08 18:45:08
【问题描述】:

我编写了一个存储过程,它对某个列的值进行哈希处理。我需要在 CASE WHEN 或 IIF 语句中使用此 HASHBYTES 函数,如下所示:

DECLARE @Hash varchar(255) = 'testvalue'
SELECT    IIF(1=1, HASHBYTES('SHA1',@Hash), @Hash)
SELECT CASE WHEN 1=1 THEN HASHBYTES('SHA1',@Hash) END  AS Hashcolumn

我无法理解为什么我会从上述查询中得到不同的输出?似乎每当我在 CASE WHEN / IIF 语句中添加 ELSE 时,它都会返回一串奇怪的字符(如上例中的ü<þ+OUL'RDOk{­\Ìø)。

谁能告诉我为什么会这样?我需要使用 CASE WHEN 或 IIF。

谢谢大家

【问题讨论】:

    标签: sql sql-server stored-procedures hashbytes


    【解决方案1】:

    IIF 从 true_value 和 false_value 中的类型返回具有 highest precedence 的数据类型。在这种情况下,它是@Hash1,即varchar(255),因此您的结果将转换为varchar(255)。见下文。

    DECLARE @Hash varchar(255) = 'testvalue'
    SELECT cast(HASHBYTES('SHA1',@Hash) as varchar(255))
    

    同样,CASE 的工作方式相同。但是,如果您不添加与数据类型冲突的ELSE 或另一个WHEN,它将起作用。这是因为隐含了ELSE NULL。即

    SELECT CASE WHEN 1=1 THEN HASHBYTES('SHA1',@Hash) END
    

    但是,如果您添加另一个检查,那么优先级就会生效,并且会被转换。

    SELECT CASE WHEN 1=1 THEN HASHBYTES('SHA1',@Hash) WHEN 1=2 THEN @Hash END AS Hashcolumn 
    SELECT CASE WHEN 1=1 THEN HASHBYTES('SHA1',@Hash) ELSE @Hash END AS Hashcolumn 
    

    【讨论】:

    • 感谢您的回复!我发了一条新评论,你能看一下吗?我还是觉得很奇怪。
    • 我已经回答了您最初的问题,但是您在下面回答中的 cmets 让我感到困惑。我不确定这里的最终目标是什么以及为什么需要IIFCASE。我认为你应该为你的新问题提出一个新问题。
    • 这个想法是,如果 1=1,我对列中的数据进行哈希处理(这当然是另一个条件,但没关系),否则只显示列中的默认记录,但我猜测这是不可能的,因为列中的默认记录始终是 varchar,如果我理解正确,它将被数据优先级否决。
    • 你的最后一句话是正确的。您可以通过其他方式执行此操作,但我需要知道真正的目的/用例,因为另一种解决方案可能不适用于您的简单示例。
    • 我对另一种方式非常感兴趣。基本上,存储过程的作用如下: 1. 批量插入 CSV 文件 2. 基于 CRLF 获取第一行并获取逗号分隔的标题 3. 从这些标题创建临时表 4. 散列 X 列中的数据(基于输入参数)。如果 csv 中的 columname = columname,则对该列中的数据进行哈希处理。否则只返回列值。这有任何意义吗?我真正需要的是一种绕过示例的方法,这正是问题所在。我需要散列或显示普通列数据(始终为 varchar)
    【解决方案2】:

    选择查询的输出是一个虚拟表。在关系数据库中,表的列被限制为单一数据类型。所以这里发生的是服务器引擎正在执行隐式转换以呈现单一类型,因此返回奇怪的字符。

    转换的性质正如@scsimon 所说,它遵循最高优先级顺序。

    以下查询应该会有所帮助。

    DECLARE @Hash varchar(255) = 'testvalue'
    SELECT    IIF(1=1, CONVERT(VARCHAR(255),HASHBYTES('SHA1',@Hash),2), @Hash)
    SELECT CASE WHEN 1=2 THEN CONVERT(VARCHAR(255),HASHBYTES('SHA1',@Hash),2) 
          ELSE @Hash END  AS Hashcolumn
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 2016-10-11
      • 1970-01-01
      相关资源
      最近更新 更多