加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

tsql – SQL无效转换返回null而不是抛出错误

发布时间:2020-12-12 06:55:39 所属栏目:MsSql教程 来源:网络整理
导读:我有一个带varchar列的表,我想找到与某个数字匹配的值.因此,我们可以说该列包含以下条目(现实生活中除了数百万行): 1234567890122345678345623 45713?200123456789012 所以我决定我想要所有数字上的行123456789012写一个看起来像这样的语句: SELECT * FROM
我有一个带varchar列的表,我想找到与某个数字匹配的值.因此,我们可以说该列包含以下条目(现实生活中除了数百万行):
123456789012
2345678
3456
23 45
713?2
00123456789012

所以我决定我想要所有数字上的行123456789012写一个看起来像这样的语句:

SELECT * FROM MyTable WHERE CAST(MyColumn as bigint) = 123456789012

它应该返回第一行和最后一行,但整个查询会爆炸,因为它无法将“23 45”和“713?2”转换为bigint.

是否有另一种方法来进行转换,为无法转换的值返回NULL?

解决方法

SQL Server不保证布尔运算符短路,请参见 On SQL Server boolean operator short-circuit.所以使用ISNUMERIC(…)和CAST(…)的所有解决方案都存在根本缺陷(它们可能有效,但是嘿可以随意依赖生成的计划失败).一个更好的解决方案是使用CASE,正如托马斯建议的那样:CASE ISNUMERIC(…)1,那么CAST(…)ELSE NULL END.但是,正如gbn所指出的那样,ISNUMERIC在识别“数字”意味着什么以及许多人希望它返回0并返回1的情况下非常挑剔.因此将CASE与LIKE混合:
CASE WHEN MyRow NOT LIKE '%[^0-9]%' THEN CAST(MyRow as bigint) ELSE NULL END

但真正的问题是,如果你有数百万行,你必须像这样搜索它们,你总是会端对端扫描,因为表达式不具备SARG能力(无论我们如何重写它).这里真正的问题是数据纯度,应该在适当的级别解决数据填充的问题.另一件需要考虑的事情是,是否可以使用此表达式创建一个持久的计算列,并在其上创建一个消除NULL的过滤索引(即非数字).这会加速一些事情.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读