SELECT 在查询中不存在的行上引发 CAST 错误

Posted

技术标签:

【中文标题】SELECT 在查询中不存在的行上引发 CAST 错误【英文标题】:SELECT throwing an CAST error on a row that does not exist in query 【发布时间】:2021-02-16 18:27:14 【问题描述】:

我遇到了引发 CAST 错误的 SELECT 问题,但仅当 CAST 位于 WHERE 子句中时。我已将问题归结为以下示例 SQL。

CREATE TABLE dbo.CastTest (
[WhatIsThis] nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL)
GO
INSERT INTO dbo.CastTest (WhatIsThis) VALUES ('NotANumber');
INSERT INTO dbo.CastTest (WhatIsThis) VALUES ('11');
INSERT INTO dbo.CastTest (WhatIsThis) VALUES ('4');
SELECT *, CAST(WhatIsThis AS INT) ANumber 
    FROM (
        SELECT * FROM dbo.CastTest WHERE ISNUMERIC(WhatIsThis)=1
        ) OnlyNumbers
      -- WHERE CAST(WhatIsThis AS INT)>10

上面的代码有效,将 NVARCHAR 为 CAST 的两行返回为数字,并排除它不是数字的另一行。但是,一旦您取消注释 WHERE 子句,您就会得到以下内容;

将 nvarchar 值“NotANumber”转换为数据类型 int 时转换失败。

为什么 CAST 在它不应该看到的行上失败了?我该怎么做才能避免这个错误?

【问题讨论】:

用您正在使用的数据库标记您的问题。 【参考方案1】:

请勿将isnumeric() 用于此目的。 SQL 通常不保证子句的求值顺序。这包括子查询和 CTE。这些操作都可以重新排列(而且经常如此)。

改为使用try_convert()try_cast() 进行显式 转换:

SELECT *, TRY_CAST(WhatIsThis AS INT) as ANumber 
FROM (SELECT *
      FROM dbo.CastTest
      WHERE TRY_CONVERT(int, WhatIsThis) IS NOT NULL
     ) OnlyNumbers

【讨论】:

以上是关于SELECT 在查询中不存在的行上引发 CAST 错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥 UPDATE 在不相关的行上阻止 SELECT?

表中不存在的行

即使 sql developer 中不存在数据,也返回给定员工的行

shell脚本,awk在需要的行上打打印空行。

MS Access中的VBA中不接受变量名称

添加查询中不存在的列