Ahm*_*yed 3 sql-server sql-server-2008-r2
我有一个简单的 SQL 语句(在从 2000 升级到 2008 R2 的 SQL Server 上执行):
SELECT TOP (1)
DocNox = CONVERT(integer, SUBSTRING(DocNo, 2, LEN(DocNo)-1)
FROM Tbl1
WHERE
Fld1 = 19
AND Fld2 = 1
AND Fld3 = 1
AND DocNo NOT LIKE '%-%'
ORDER BY
CONVERT(integer, SUBSTRING(DocNo, 2, LEN(DocNo)-1) DESC;
Run Code Online (Sandbox Code Playgroud)
示例数据(Serial 是一IDENTITY
列)
Serial DocNo Fld1 Fld2 Fld3
211 A1 19 1 1
212 A2 19 1 1
213 A003 19 1 1
214 X1-C1-1 20 1 1
Run Code Online (Sandbox Code Playgroud)
执行查询会产生以下错误消息:
Error converting nvarchar value '1-C1-1' to a column of data type int.
这是出乎意料的,因为包含该值的行应该WHERE
在SELECT
和/或ORDER BY
子句中的转换之前被子句过滤掉。
我注意到以下更改可以防止错误发生:
WHERE Fld1 = 19
TOP (1)
ORDER BY
ORDER BY
为不同的列(例如串行)但是在以下情况下仍然会出现错误:
我还对防止错误的统计数据进行了更改,但我不记得我做了什么。
任何人都可以解释这里发生了什么吗?
这是正常的。T-SQL 通常不指定评估顺序。直觉上,您会首先评估 where 子句,但情况并非必须如此。SQL Server 决定反对完全有效的那个。
目前,SQL Server 没有提供 100% 确定永远不会遇到此问题的构造。不过有一个 99% 确定的技术:在任何危险的东西周围包裹一个 case 表达式:
case when DonNo like '%-%' then (/* convert */) end
Run Code Online (Sandbox Code Playgroud)
除了在 Microsoft Connect 上记录的极少数极端情况外,这几乎总是有效。我现在手头没有它们。
归档时间: |
|
查看次数: |
209 次 |
最近记录: |