使用带有 ISNUMERIC 的派生表进行查询会导致转换失败(varchar 到 int)
Posted
技术标签:
【中文标题】使用带有 ISNUMERIC 的派生表进行查询会导致转换失败(varchar 到 int)【英文标题】:Query using a derived table with ISNUMERIC results in conversion failure (varchar to int) 【发布时间】:2012-02-28 10:17:33 【问题描述】:这是一个示例查询:
DECLARE @table table (loc varchar(10))
INSERT INTO @table VALUES
('134a'), ('123'), ('abc'), ('124')
SELECT *
FROM (
SELECT * FROM @table WHERE ISNUMERIC(loc) = 1
) as a
WHERE CAST(loc as INT) BETWEEN 100 AND 200
如果我有一些 varchar 值并且我在查询的派生表中使用 ISNUMERIC
将它们限制为数值,为什么会导致转换错误?:
将 varchar 值“134a”转换为数据类型 int 时转换失败。
有没有办法解决这个问题?
【问题讨论】:
SQL Server 2008: Error converting data type nvarchar to float的可能重复 澄清一下:你有那个约束作为子查询并不重要。 SQL Server 解开它,因为它很容易。 @GSerg 你能详细说明“因为它很容易做到”吗? SQL Server 在执行前分析查询以构建执行计划。这个过程相当深刻和美好。可以展开和展平的东西通常是。这包括子查询和引用视图,以及内联表值函数。因此,请参阅链接的问题以了解解决方法。 @GSerg 谢谢,CASE
表达式可能是最简单的解决方法。
【参考方案1】:
WHERE
子句首先执行。试试:
DECLARE @table table (loc varchar(10))
INSERT INTO @table VALUES
('134a'), ('123'), ('abc'), ('124')
SELECT *
FROM (
SELECT * FROM @table
) as a
WHERE ISNUMERIC(loc) = 1 and CAST(loc as INT) BETWEEN 100 AND 200
【讨论】:
有什么方法可以确保ISNUMERIC(loc)
会在CAST(loc as INT) BETWEEN 100 AND 200
之前执行?
SQL Server 保证相同优先级的运算符将从左到右计算,但不保证布尔表达式的短路计算。此外,似乎行为在不同的上下文中可能会有所不同,例如IF
、CASE
和 WHERE
。我希望我能引用一个权威的参考资料来解决这个问题。或者他们会像其他一些语言一样支持显式的AND_THEN
和OR_ELSE
运算符。以上是关于使用带有 ISNUMERIC 的派生表进行查询会导致转换失败(varchar 到 int)的主要内容,如果未能解决你的问题,请参考以下文章