2

我编写了一个存储过程,对某个列的值进行哈希处理。我需要在 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。

多谢你们

4

2 回答 2

5

IIF返回true_value 和 false_value 中的类型中优先级最高的数据类型。在这种情况下,@Hash1就是varchar(255)这样,您的结果将被强制转换为varchar(255). 见下文。

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

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

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 
于 2018-05-08T18:49:34.100 回答
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
于 2018-05-08T19:10:32.917 回答