在转换为 int 的列上将 varchar 转换为 int 失败

Conversion failure varchar to int on a column cast as int

我创建了一个名为 vReceivedEmail 的视图,其中包含一个名为 RowPrimaryKeyValue 的 varchar 列。此列通常存储主键 id 值,例如 567781,但偶尔会有描述性文本 'Ad hoc message'.

我已将视图设置为仅显示包含主键值的记录,然后 CAST 将列显示为 int

SELECT      CAST(Email.RowPrimaryKeyValue as int)           as DetailID
FROM        MessageStore.dbo.Email Email
WHERE       ISNUMERIC(Email.RowPrimaryKeyValue) = 1

当我测试视图时,我只得到具有我预期的主键值的记录,当我在对象资源管理器中查看视图的列列表时,该列保存在 int数据类型。

然后我尝试在单独的查询中应用以下 WHERE 子句,引用我保存的视图:

SELECT      PotAcc.DetailID
FROM        PotentialAccounts PotAcc
WHERE       PotAcc.DetailID NOT IN (
                SELECT      RecEmail.DetailID
                FROM        vReceivedEmail  RecEmail
            )

...但我返回以下错误:

Conversion failed when converting the varchar value 'Ad hoc message' to data type int.

'Ad hoc message' 是我过滤并转换为 int 的列中的数据,但我不知道它是如何设法解决这个问题的,因为视图明确地将其过滤掉并将该列转换为 int。

Isnumeric() 可能是骗人的……但我敢打赌这是由于 SQL 服务器优化所致。尽管您的视图有效,但这并不意味着外部查询保证只返回 INT。而不是使用视图...使用 CTE 并尝试一下。而且因为你是2012年,这一切都可以按照SqlZim上面的解释来避免。

WITH CTE AS(
SELECT      CAST(Email.RowPrimaryKeyValue as int)           as DetailID
FROM        MessageStore.dbo.Email Email
WHERE       ISNUMERIC(Email.RowPrimaryKeyValue) = 1)


SELECT      PotAcc.DetailID
FROM        PotentialAccounts PotAcc
WHERE       PotAcc.DetailID NOT IN (
                SELECT      RecEmail.DetailID
                FROM        CTE RecEmail
            )

由于您使用的是 SQL Server 2012,使用 try_convert(int,RowPrimaryKeyValue) is not null 代替 isnumeric() 怎么样?

您的视图如下所示:

select try_convert(int, RowPrimaryKeyValue) as DetailID
from MessageStore.dbo.Email Email
where try_convert(int, RowPrimaryKeyValue) is not null

在 SQL Server 2012 及更高版本中:当转换失败而不是错误时,其中每一个都会 return null