TSQL CASE意外地处理了多个THEN语句

Bil*_*ill 2 sql t-sql sql-server case

我有一个简单的SQL CASE语句,我试图解释变量的数据类型,然后将其转换为所述格式.我有以下样本:

  DECLARE @P1 varchar(10) = '2';

  SELECT CASE 1 
    WHEN ISNUMERIC(@P1) THEN (CAST(@P1 AS INT)) 
    WHEN ISDATE(@P1) THEN (CAST(@P1 AS DateTime)) 
    ELSE 'N' END AS Test2P1
Run Code Online (Sandbox Code Playgroud)

我希望它返回一个2的整数值.但是,这就是我得到的.

Test2P1

1900-01-03 00:00:00.000

但是,如果我修改代码只显示一个字符而不是CASTING变量,我得到一个不同的结果:

  DECLARE @P1 varchar(10) = '2';


  SELECT CASE 1 
    WHEN ISNUMERIC(@P1) THEN 'I' 
    WHEN ISDATE(@P1) THEN 'D'
    ELSE 'N' END AS Test2P1
Run Code Online (Sandbox Code Playgroud)

然后我得到了一个结果:我

进一步采取这个实验,如果我让第一个测试返回'I'但是输出日期,那么我得到一个错误:

  DECLARE @P1 varchar(10) = '2';

  SELECT CASE 1 
    WHEN ISNUMERIC(@P1) THEN 'I'
    WHEN ISDATE(@P1) THEN (CAST(@P1 AS DateTime)) 
    ELSE 'N' END AS Test2P1

Msg 241, Level 16, State 1, Line 3
Conversion failed when converting date and/or time from character string.
Run Code Online (Sandbox Code Playgroud)

似乎SQL正在评估THEN语句的多个实例.但是,ISDATE表达式不返回true.我很难过.

在我的研究中,我遇到了这篇文章[SQL性能](https://sqlperformance.com/2014/06/t-sql-queries/dirty-secrets-of-the-case-expression)他在这说了什么文章完全有道理.但我不知道在这种情况下它适用于哪里,因为我永远不会改变变量的值.

我还在COALESCE()中包装了我的CASE语句,但似乎没有帮助.我不会期望它,但我发现有多篇文章将此作为类似问题的解决方案.这似乎是一个非常简单的CASE声明,但我不知道我哪里出错了.任何帮助是极大的赞赏.

squ*_*man 6

DateTimeSQL Server中的数据类型优先级高于INT,因此您的整个CASE将被强制转换为DATETIME.您只能在一列中返回单个数据类型的数据,因此需要数据类型优先级.

是显示优先级的MSDN文章.