为什么IsNull(LTrim(RTrim(Lower(null))), - 1)是*?

MNV*_*NVR 10 sql t-sql sql-server-2008

今天我在工作场所测试了一些东西并遇到了这个问题

情况1:

Declare @a nvarchar(20)
Set @a = null
Select IsNull(LTrim(RTrim(Lower(@a))), -1)
Run Code Online (Sandbox Code Playgroud)

案例2:

Select IsNull(LTrim(RTrim(Lower(null))), -1)
Run Code Online (Sandbox Code Playgroud)

案例1中的结果是-1*在案例2中我在两种情况下都期望相同的结果.任何原因?

Aar*_*and 13

如果没有数据类型声明,则在这种情况下,null将声明为varchar(1).您可以通过在#temp表中选择结果来观察:

Select IsNull(LTrim(RTrim(Lower(null))), -1) as x INTO #x;
EXEC tempdb..sp_help '#x';
Run Code Online (Sandbox Code Playgroud)

在结果中你会看到:

Column_name   Type      Length
-----------   -------   ------
x             varchar   1
Run Code Online (Sandbox Code Playgroud)

因为-1不能适合varchar(1),所以你得到*作为输出.这类似于:

SELECT CONVERT(VARCHAR(1), -1);
Run Code Online (Sandbox Code Playgroud)

如果你想折叠成一个字符串,那么我建议将整数用单引号括起来,这样就不会出现因整数< - >字符串转换引起的混淆:

SELECT CONVERT(VARCHAR(1), '-1'); -- yields "-"
SELECT CONVERT(VARCHAR(30), '-1'); -- yields "-1"
Run Code Online (Sandbox Code Playgroud)

我不会对SQL Server如何处理显式提供的"值"做任何假设null,特别是当复杂表达式使得难以预测哪些评估规则可能胜过数据类型优先级时.