Sounds like, because you have numeric data stored in a string column, you have bad data. One way to identify it is:
SELECT key_column, ORIGBAL
FROM dbo.tablename
WHERE ORIGBAL LIKE '%[^-.0-9]%';
Fix that data (it may contain commas, but probably the damage is worse than that, like some values with completely non-numeric data - otherwise cast to MONEY should have worked). If you find that a lot of rows contain commas then you can simply run an update:
UPDATE dbo.tablename SET ORIGBAL = REPLACE(ORIGBAL, ',', '');
Then run the above query again. If no rows are returned, now you can convert to "normal" numeric types instead of MONEY or FLOAT which really should be reserved for very specific scenarios IMHO.
Without fixing the data, you can make your life more complicated by using a CASE expression in all of your queries:
SELECT key_column, CONVERT(DECIMAL(12,2), CASE
WHEN ORIGBAL LIKE '%[^-.0-9]%' THEN ORIGBAL END
FROM dbo.tablename
...
This will yield NULL values instead of bad, non-numeric values. However it could still fail, e.g. that expression will pass for 0.0.0.44.02 which obviously can't be converted to a decimal. As an example:
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;
Results:
bob needs correcting
0.0.0.44.02 all good
32500.40 all good
To identify cases with multiple decimal points, you could do:
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;
Results:
bob needs correcting
0.0.0.44.02 needs correcting
32500.40 all good
You still may have values that exceed the eventual convert, e.g. '12345678901234.56' is too big for DECIMAL(12,2).
In SQL Server 2012, you will have shorthand for the above expression:
SELECT key_column, TRY_CONVERT(DECIMAL(12,2), ORIGBAL)
FROM dbo.tablename
...
...which will yield NULL values even for more complex values like 0.0.0.44.02.
sql server 2008 - Convert NVARCHAR to MONEY or FLOAT format - Stack Overflow
sql - Data conversion Nvarchar to Money - Stack Overflow
nvarchar to money - SQL Server Forums
Error converting data type nvarchar to numeric
Videos
Sounds like, because you have numeric data stored in a string column, you have bad data. One way to identify it is:
SELECT key_column, ORIGBAL
FROM dbo.tablename
WHERE ORIGBAL LIKE '%[^-.0-9]%';
Fix that data (it may contain commas, but probably the damage is worse than that, like some values with completely non-numeric data - otherwise cast to MONEY should have worked). If you find that a lot of rows contain commas then you can simply run an update:
UPDATE dbo.tablename SET ORIGBAL = REPLACE(ORIGBAL, ',', '');
Then run the above query again. If no rows are returned, now you can convert to "normal" numeric types instead of MONEY or FLOAT which really should be reserved for very specific scenarios IMHO.
Without fixing the data, you can make your life more complicated by using a CASE expression in all of your queries:
SELECT key_column, CONVERT(DECIMAL(12,2), CASE
WHEN ORIGBAL LIKE '%[^-.0-9]%' THEN ORIGBAL END
FROM dbo.tablename
...
This will yield NULL values instead of bad, non-numeric values. However it could still fail, e.g. that expression will pass for 0.0.0.44.02 which obviously can't be converted to a decimal. As an example:
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;
Results:
bob needs correcting
0.0.0.44.02 all good
32500.40 all good
To identify cases with multiple decimal points, you could do:
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;
Results:
bob needs correcting
0.0.0.44.02 needs correcting
32500.40 all good
You still may have values that exceed the eventual convert, e.g. '12345678901234.56' is too big for DECIMAL(12,2).
In SQL Server 2012, you will have shorthand for the above expression:
SELECT key_column, TRY_CONVERT(DECIMAL(12,2), ORIGBAL)
FROM dbo.tablename
...
...which will yield NULL values even for more complex values like 0.0.0.44.02.
CAST doesn't react well to commas and dollar signs. You might have better luck with CONVERT...
SELECT CONVERT(money, '$1,123.45')
If you have to have it in decimal, convert to money and then decimal...
SELECT CAST(CONVERT(money, '$1,123.45') AS decimal(12,2))
I have three tables. I am doing a join on the first 2 and then adding the third with a union. when I run the first 2 I don't get an error, and when I run the third I don't get an error either. Its only when I try to do the union that I get this error message: "SQL Error [8114] [S0005]: Error converting data type nvarchar to numeric."
The data types in joined tables 1 and 2 are the same data types as table 3. Is there a value somewhere that is causing this problem? Why am I only getting the error when trying to do the union? What is a good and fast way to find the cause of the error? Thanks
You might need to revise the data in the column, but anyway you can do one of the following:-
1- check if it is numeric then convert it else put another value like 0
Select COLUMNA AS COLUMNA_s, CASE WHEN Isnumeric(COLUMNA) = 1
THEN CONVERT(DECIMAL(18,2),COLUMNA)
ELSE 0 END AS COLUMNA
2- select only numeric values from the column
SELECT COLUMNA AS COLUMNA_s ,CONVERT(DECIMAL(18,2),COLUMNA) AS COLUMNA
where Isnumeric(COLUMNA) = 1
In case of float values with characters 'e' '+' it errors out if we try to convert in decimal. ('2.81104e+006'). It still pass ISNUMERIC test.
SELECT ISNUMERIC('2.81104e+006')
returns 1.
SELECT convert(decimal(15,2), '2.81104e+006')
returns
error: Error converting data type varchar to numeric.
And
SELECT try_convert(decimal(15,2), '2.81104e+006')
returns NULL.
SELECT convert(float, '2.81104e+006')
returns the correct value 2811040.