查询存在一些问题,但导致错误的主要问题相当简单:您的条件是在进行比较之前field_name > 100.00
没有将字段转换为数字类型。VARCHAR
将其更改为CONVERT(DECIMAL(38, 18), [field_name])
将修复您看到的错误。
运行以下一次以查看它是否有效,然后取消注释该AND [field_name] > 100.00
行并再次运行,您将收到您所看到的有关“将 varchar 转换为数据类型数字的算术溢出错误”的错误:
DECLARE @table_name TABLE (field_name VARCHAR(50) NOT NULL);
INSERT INTO @table_name (field_name) VALUES ('1234.5678');
INSERT INTO @table_name (field_name) VALUES ('12.78');
INSERT INTO @table_name (field_name) VALUES ('s');
INSERT INTO @table_name (field_name) VALUES ('2015-01-30');
INSERT INTO @table_name (field_name) VALUES ('51234.5678');
INSERT INTO @table_name (field_name) VALUES ('987651234.56789124');
SELECT field_name
FROM @table_name
WHERE ISNUMERIC([field_name]) = 1
AND [field_name] IN (
SELECT CAST([field_name] AS DECIMAL)
FROM @table_name
WHERE ISNUMERIC([field_name]) = 1
AND [field_name] NOT LIKE '%,%'
AND [field_name] NOT LIKE '%-%'
AND [field_name] != '.'
-- AND [field_name] > 100.00
AND CONVERT(DECIMAL(38, 18), [field_name]) > 100.00
);
但是,仍然存在一些问题:
- 如问题所示,子查询返回转换值列表没有意义。查询可能已被更改以在此处发布,因此在其真实形式中更有意义,但不需要子查询并且无论如何也无济于事。
CAST
toDECIMAL
没有指定精度和比例。默认值分别为 18 和 0。意思是,您将字符串转换为DECIMAL(18, 0)
. 这在这里似乎没有任何影响,但最好指定值。运行SELECT CAST('123.456' AS DECIMAL)
将返回123
。
- 您实际上不需要过滤掉带有逗号的值,因为它们可以被删除,从而为您留下一个可以转换的值。当然,除非你有一些像
12,34,56,78
. 但如果它们是有效数字,例如1,234.56
,那么您可以使用REPLACE([field_name], ',', '')
将以下两行添加到上面示例顶部的 INSERT将出错:
INSERT INTO @table_name (field_name) VALUES ('1,234.5678');
INSERT INTO @table_name (field_name) VALUES ('.');
所有这些都可以通过执行以下操作来处理(将上面的查询替换为下面的查询,但保留DECLARE
and INSERT
s):
SELECT field_name, CAST([field_name] AS DECIMAL(38, 18)) AS [DecimalValue]
FROM @table_name
WHERE ISNUMERIC(field_name) = 1
AND field_name NOT LIKE '%,%'
AND field_name NOT LIKE '%-%'
AND field_name <> '.'
AND CONVERT(DECIMAL(38, 18), REPLACE([field_name], ',', '')) > 100.00;