SQL Server 2005视图值转换导致后续查询类型转换报错
问题原因
- 核心原因是SQL Server查询优化器不会强制按照你书写SQL的顺序执行操作。你视图里写的逻辑是先通过
ISNUMERIC(name) = 1过滤掉name非数值的行,再将name转为int,但优化器可能出于成本考量,把CONVERT(int, name)的计算下推到基表扫描阶段,先对所有行做类型转换,再执行过滤条件,碰到_1135see这类非数字值时就直接抛出转换错误。 - 次要原因是
ISNUMERIC()本身判定逻辑不严谨:只要字符串能被识别为任意SQL Server数值类型(包括money、float、科学计数法、带货币符号的字符串等)就会返回1,很多无法安全转换为int的字符串也会被它判定为数值,留下转换隐患。
SQL Server 2005环境下的正确修复方案
SQL Server 2005没有高版本自带的TRY_CONVERT容错转换函数,需要通过CASE表达式强制逻辑执行顺序——SQL Server官方保证CASE表达式的WHEN分支按书写顺序判定,只有条件成立时才会执行对应THEN块的计算,不会被优化器随意重排顺序。
修改后的视图定义如下:
ALTER VIEW dbo.DLS_VPBX_tenant AS SELECT custid, crid, tenantid, CONVERT(int, name) AS name, users, status, updated, mirror_exts, domesticdids, tollfreedids, faxdids, dids FROM DLS_PBX_tenant WHERE CASE WHEN ISNUMERIC(name) = 1 AND name NOT LIKE '%[^0-9]%' THEN 1 ELSE 0 END = 1
如果业务中name允许存储负整数,可以把判定条件调整为兼容负号的写法,避免合法负整数被过滤。
注意:不要试图通过嵌套子查询、加查询提示的方式固定执行顺序,这类写法没有官方执行逻辑保证,后续数据量变化、统计信息更新后还是可能出现同样的转换报错。
内容的提问来源于stack exchange,提问作者Sam Rozenfeld
相关产品推荐
相关产品推荐

