听起来,因为您将数字数据存储在字符串列中,所以您的数据不正确。识别它的一种方法是:
SELECT key_column, ORIGBAL
FROM dbo.tablename
WHERE ORIGBAL LIKE '%[^-.0-9]%';
修复该数据(它可能包含逗号,但可能造成的损害比这更糟,例如某些具有完全非数字数据的值 - 否则MONEY
应该可以使用)。如果您发现很多行包含逗号,那么您可以简单地运行更新:
UPDATE dbo.tablename SET ORIGBAL = REPLACE(ORIGBAL, ',', '');
然后再次运行上述查询。如果没有返回任何行,现在您可以转换为“普通”数字类型,而不是MONEY
或者FLOAT
确实应该为非常具体的场景保留,恕我直言。
在不修复数据的情况下,您可以通过在所有查询中使用CASE
表达式来使您的生活更加复杂:
SELECT key_column, CONVERT(DECIMAL(12,2), CASE
WHEN ORIGBAL LIKE '%[^-.0-9]%' THEN ORIGBAL END
FROM dbo.tablename
...
这将产生NULL
值而不是错误的非数字值。但是它仍然可能失败,例如该表达式将通过0.0.0.44.02
显然无法转换为小数。举个例子:
DECLARE @x TABLE(ORIGBAL NVARCHAR(255));
INSERT @x VALUES('bob'),('0.0.0.44.02'),('32500.40');
SELECT ORIGBAL, [status] = CASE WHEN ORIGBAL LIKE '%[^.0-9]%'
THEN 'needs correcting' ELSE 'all good' END
FROM @x;
结果:
bob needs correcting
0.0.0.44.02 all good
32500.40 all good
要识别具有多个小数点的情况,您可以执行以下操作:
SELECT ORIGBAL, [status] = CASE WHEN ORIGBAL LIKE '%[^.0-9]%'
OR LEN(ORIGBAL)-LEN(REPLACE(ORIGBAL,'.','')) > 1
THEN 'needs correcting' ELSE 'all good' END
FROM @x;
结果:
bob needs correcting
0.0.0.44.02 needs correcting
32500.40 all good
您仍然可能有超过最终转换的值,例如'12345678901234.56'
对于DECIMAL(12,2)
.
在 SQL Server 2012 中,您将获得上述表达式的简写:
SELECT key_column, TRY_CONVERT(DECIMAL(12,2), ORIGBAL)
FROM dbo.tablename
...
...即使对于更复杂NULL
的值(例如0.0.0.44.02
.