查詢有幾個問題,但是導致錯誤的主要問題很簡單:在進行比較之前,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
至DECIMAL
未指定精確度和比例。默認值分別爲18和0。意思是說,你正在將這些字符串轉換成DECIMAL(18, 0)
。這似乎沒有任何影響,但最好指定值。運行SELECT CAST('123.456' AS DECIMAL)
將返回123
。
- 你真的不需要需要來過濾掉逗號,因爲這些值可以被刪除,給你一個可以轉換的值。當然,除非你有一些代碼,如
12,34,56,78
。但是,如果它們是有效的號碼,如1,234.56
,那麼你可以使用REPLACE([field_name], ',', '')
在該示例的頂部添加以下兩行對與插入片段上述將錯誤:
INSERT INTO @table_name (field_name) VALUES ('1,234.5678');
INSERT INTO @table_name (field_name) VALUES ('.');
所有這些都可以通過執行以下操作來完成(將上面的查詢替換爲下面的查詢,但保留DECLARE
和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;