我有以下两个表(在SQL Server 2017中):
部件
- 部件代码INT
- 激活BIT
- ...其他字段...
产品
- 零件代码VARCHAR(6)
- ...其他字段...
在“产品”表中,PartCode是6位数字或字母后跟5位数字。“部件”表仅涉及具有6位数字部件代码的部件。
此查询成功返回Products表中的数字部件代码列表:
SELECT CAST(PartCode AS INT) FROM Products WHERE ISNUMERIC(PartCode)=1
但是,一旦我将它嵌入到IN中,就像这样:
UPDATE Parts
SET IsActive=0
WHERE PartCode NOT IN (SELECT CAST(PartCode AS INT)
FROM Products
WHERE ISNUMERIC(PartCode)=1)
它将失败,并显示“将varchar值”K12345“转换为int数据类型时转换失败”。
我知道ISNUMERIC的奇怪行为(它返回1的意外值),但在本例中,SELECT ISNUMERIC('K12345')
如预期的那样为0。
既然ISNUMERIC正确地排除了SELECT中的K12345值,为什么它要尝试使用UPDATE强制转换它?它应该从结果集中排除(就像它自己运行SELECT时一样),因此不需要转换。为什么将SELECT放在IN中会使它的行为不同?
2条答案
按热度按时间dly7yett1#
除了显而易见的“修复数据库”之外,您可以通过使用EXISTS()来避免大多数问题。
这样你就可以把一个整数转换成一个字符串,而且它总是有效的,它还继续允许使用
Products.PartCode
上的任何索引。wljmcqd82#
在选择项中打勾:
它在您的版本中爆炸式增长的原因是优化器必须在计算
select
列表 * 之后 * 应用where
子句。