Error Converting Data type nvarcar to float - sql

Here is the query I am trying to run...
SELECT *,STUFF(PartNumber,1,3,'')
FROM [devbivarcom].[Products].[Products]
ORDER BY CAST(STUFF(PartNumber,1,3,'')AS FLOAT)
Any ideas on why I might be receiving the error?
Thanks

You are receiving an error because the characters you are converting are not a floating point number. You can do:
SELECT *, STUFF(PartNumber,1,3,'')
FROM [devbivarcom].[Products].[Products]
ORDER BY (case when isnumeric(STUFF(PartNumber,1,3,'')) = 1
then CAST(STUFF(PartNumber,1,3,'')AS FLOAT)
end);
If you want to find the offending values, do:
SELECT *, STUFF(PartNumber,1,3,'')
FROM [devbivarcom].[Products].[Products]
WHERE isnumeric(STUFF(PartNumber,1,3,'')) = 0 and PartNumber is not null;
EDIT:
isnumeric() is known to have some problems in identifying values. For instance, it identifies '.' as valid when that string doesn't convert correctly. For most purposes, it is sufficient. You can enhance it with other conditions, such as:
AND (<col> <> '.')

Related

REPLACE to just have a number causing conversion failure

I'm trying to do a count to see how many fields in column value are > 10:
SELECT
COUNT(CASE WHEN t.value > 10)
THEN 1
ELSE NULL
END
FROM table t
WHERE t.DATE = '2017-01-01'
However, the column has a few custom entries like +15 or >14.0, so I added the following:
SELECT
COUNT(CASE WHEN value LIKE '>%'
and Replace(value, '>', '') > 10)
FROM table t
WHERE t.DATE = '2017-01-01'
However, after doing that, I get the following error:
Conversion failed when converting the varchar value '>14.0' to data
type int. Warning: Null value is eliminated by an aggregate or other
SET operation.
Seeing I have no access to rewrite the database with an UPDATE, does anyone have a workaround solution?
You could fix this, either by simply changing 10 to 10.0:
SELECT CASE WHEN '14.0' > 10.0 THEN 1 ELSE 0 END
This will cause the implicit conversion of '14.0' to decimal rather than int, which works, or you explicitly convert it:
SELECT CASE WHEN CONVERT(DECIMAL(14, 2), '14.0') > 10 THEN 1 ELSE 0 END
If it were me however, and I was not in a position to update the data, and do something a bit left field, like use a numeric data type to store numbers, I would ignore these values completely, and simply use TRY_CONVERT to avoid the conversion errors:
SELECT
COUNT(CASE WHEN TRY_CONVERT(DECIMAL(14, 2), value) > 10 THEN 1 END)
It is a varchar column, so the possibilities of what nonsense could be in there are endless, you might get a query that works now by replacing > and +, but then what about when someone puts in <, or ends up with a space in between like + 14, or something completely random like 'aaaa', where does it end?
It would be helpful to see the table and sample data, but it sounds like you have strings that are numbers and a sign.
You can cast it to convert the data since you are mixing and matching data types.
SELECT
COUNT(CASE WHEN CAST(value AS VARCHAR(10)) LIKE '>%'
and CAST(Replace(value, '>', '') AS your_num_datatype_here) > 10)

Convert exponential to number in sql

I have a large amount of card tokens (16 digits) uploaded from xml file to sql-server. The problem is I see them as expression, sample below:
3.3733E+15
3.3737E+15
3.3737E+15
3.3737E+15
3.37391E+15
3.37391E+15
3.37398E+15
3.37453E+15
3.37468E+15
3.37468E+15
3.3747E+15
3.37486E+15
3.37486E+15
3.37567E+15
3.3759E+15
3.3759E+15
Any suggestion to change them to a 16 digit number? I have tried to change the data type, but got error"Conversion failed when converting the varchar value '3.37201E+15' to data type int"
Thanks for help!
Edit:
#X.L.Ant see my code below. I create this table from another one, which is just purely inserted from xml file. Is this may cause an error because some rows are empty in column TOKEN?
CREATE TABLE MULTICURRENCY_CHECK
(
TOKEN varchar(255)
)
/*Merges all card tokens into 1 column, as in xml they are spread across different columns*/
INSERT INTO MULTICURRENCY_CHECK
(
TOKEN
)
SELECT no FROM gpstransactionsnew2
UNION ALL
SELECT no19 FROM gpstransactionsnew2
UNION ALL
SELECT no68 FROM gpstransactionsnew2
UNION ALL
SELECT no93 FROM gpstransactionsnew2
UNION ALL
SELECT no107 FROM gpstransactionsnew2
UNION ALL
SELECT no121 FROM gpstransactionsnew2
SELECT REPLACE(TOKEN, 'OW1', ' ')
FROM MULTICURRENCY_CHECK
/*Converts exponential expression to number*/
SELECT CONVERT(numeric(16,0), CAST(TOKEN AS FLOAT))
FROM MULTICURRENCY_CHECK
Try to cast your string to float before converting it :
SELECT CONVERT(numeric(16,0), CAST(TOKEN AS FLOAT))
FROM MULTICURRENCY_CHECK
See this fiddle.
I don't know what's the format of those numbers in your XML source, but with the data you provide, you'll end up with 33733 for instance followed by a bunch of zeroes. If you have a bigger precision in your XML, maybe you should tweak your importing settings to keep this precision instead of trying to deal with that in the DB.
EDIT:
Try testing your strings with ISNUMERIC to avoid the casting errors you're getting. Adding a raw output of your column will allow you to check which value fails to convert (i.e. converts to 0).
SELECT TOKEN,
CONVERT(NUMERIC(16, 0), CAST(CASE
WHEN ISNUMERIC(TOKEN) = 1
THEN TOKEN
ELSE 0
END AS FLOAT))
FROM MULTICURRENCY_CHECK
For SQL Server 2012+, use TRY_CONVERT().
The use of ISNUMERIC() in xlecoustillier's edited answer does not protect against conversion failures.
Given the following scenario:
CREATE TABLE test(a varchar(100));
insert into test values ('3.3733E+15'),
('3.3737E+15'),
('3.37391E+30'), --fails conversion. included to demonstrate the nature of TRY_CONVERT().
('3.37398E+15'),
('3.37453E+15'),
('3.37468E+15'),
('3.3747E+15'),
('3.37486E+15'),
('3.37567E+15'),
('3.3759E+15');
SELECT TRY_CONVERT(numeric(16,0), CAST(a AS FLOAT))
FROM test
Results in only valid converted values:
---------------------------------------
3373300000000000
NULL
3373910000000000
3373980000000000
3374530000000000
3374680000000000
3374700000000000
3374860000000000
3375670000000000
3375900000000000
However:
SELECT a,
CONVERT(NUMERIC(16, 0), CAST(CASE
WHEN ISNUMERIC(a) = 1
THEN a
ELSE 0
END AS FLOAT))
FROM test
Fails with:
Conversion failed when converting the varchar value '3.3733E+15' to
data type int.
The issue is that all values in the 'a' column return 1 when passed to the ISNUMERIC() function.
SELECT CASE WHEN ISNUMERIC(a) = 1 THEN 'Yes' ELSE 'No' END as IsValueNumeric
FROM test
Try it on SQLFiddle and/or compare with xlecoustillier's sqlfiddle
SELECT colmn_name || '' FROM table_name
This should work.

Sum of data in varchar column

i have to sum element in a column(SCENARIO1) that is varchar and contain data like (1,920, 270.00, 0, NULL) but when i try to convert data into int or decimal i get this error :
"he command is wrong when converting value "4582014,00" to int type"
here is my request :
select sum( convert( int, SCENARIO1) )
from Mnt_Scenario_Exercice where code_pere='00000000'
any help please
try this
select sum(cast(replace(SCENARIO1, ',', '.') as decimal(29, 10)))
from Mnt_Scenario_Exercice
where code_pere = '00000000';
If you couldn't convert your '4582014,00' into decimal, there's a chance you have different decimal separator on your server. You could look what it is or just try '.'
4582014,00 should be a decimal
try this (I assume that youre query is working) and changed convert(int into decimal)
select sum(convert(decimal(20,2),replace(SCENARIO1, ',', '.'))) from Mnt_Scenario_Exercice where code_pere='00000000'
The problem is due to the fact that the sum function isn't decoding SCENARIO1 as containing a CSV list of numbers. The way the sum function is usually used is to sum a lot of numbers drawn from multiple rows, where each row provides one number.
Try doing it in two steps. In step 1 convert the table into first normal form perhaps by UNPIVOTING. The 1NF table will have one number per row, and will contain more rows than the initial table.
The second step is to compute the sum. If you want more than one sum in the result, use GROUP BY to create groups, and then select a sum(somecolumn). This will yield one sum for each group.
Try this, I haven't got a way to test yet, but I will test and replace if incorrect.
SELECT sum(CAST (replace(SCENARIO1, ',', '') AS INT))
FROM Mnt_Scenario_Exercice
WHERE code_pere = '00000000';
EDIT: You can use a numeric for the cast if you need 4582014,00 to be 4582014.00
SELECT sum(CAST (replace(SCENARIO1, ',', '.') AS NUMERIC(10,2)))
FROM Mnt_Scenario_Exercice
WHERE code_pere = '00000000';

select case statement error in mssql

SELECT top 1
case
when VR = -99999.99
then 0
else cast((VR*1.732) as decimal(38,3))
end
FROM pseb.dbo.datasource
where FeederID=5003
order by datetime desc
The above query is working fine, but I need to return varchar value '--' instead of returning 0
if I do like that
SELECT top 1
case
when VR = -99999.99
then '--'
else cast((VR*1.732) as decimal(38,3))
end
FROM pseb.dbo.datasource
where FeederID=5003
order by datetime desc
means it returns the following error:
Msg 8114, Level 16, State 5, Line 1 Error converting data type varchar
to numeric.
please help me to solve it
The problem is that you are returning two different data types from the same column. The rule with SQL Server that numeric types take precedence over string types, i.e. in a situation like yours a string gets converted to a number, not the other way around.
So to solve this you can cast your number to a string.
One option is to do something like this:
SELECT top 1
case when VR = -99999.99 then '--'
else
cast
(
cast((VR*1.732) as decimal(38,3)
)
as varchar(50))
end
FROM pseb.dbo.datasource where FeederID=5003 order by datetime desc

SQL IsNumeric not working

The reserve column is a varchar, to perform sums on it I want to cast it to a deciaml.
But the SQL below gives me an error
select
cast(Reserve as decimal)
from MyReserves
Error converting data type varchar to numeric.
I added the isnumeric and not null to try and avoid this error but it still persists, any ideas why?
select
cast(Reserve as decimal)
from MyReserves
where isnumeric(Reserve ) = 1
and MyReserves is not null
See here: CAST and IsNumeric
Try this:
WHERE IsNumeric(Reserve + '.0e0') = 1 AND reserve IS NOT NULL
UPDATE
Default of decimal is (18,0), so
declare #i nvarchar(100)='12121212121211212122121'--length is>18
SELECT ISNUMERIC(#i) --gives 1
SELECT CAST(#i as decimal)--throws an error
Gosh, nobody seems to have explained this correctly. SQL is a descriptive language. It does not specify the order of operations.
The problem that you are (well, were) having is that the where does not do the filtering before the conversion takes place. Order of operations, though, is guaranteed for a case statement. So, the following will work:
select cast(case when isnumeric(Reserve) = 1 then Reserve end as decimal)
from MyReserves
where isnumeric(Reserve ) = 1 and MyReserves is not null
The issue has nothing to do with the particular numeric format you are converting to or with the isnumeric() function. It is simply that the ordering of operations is not guaranteed.
It seems that isnumeric has some Problems:
http://www.sqlhacks.com/Retrieve/Isnumeric-problems
(via internet archive)
According to that Link you can solve it like that:
select
cast(Reserve as decimal)
from MyReserves
where MyReserves is not null
and MyReserves * 1 = MyReserves
Use try_cast (sql 2012)
select
try_cast(Reserve as decimal)
from MyReserves
IsNumeric is a problem child -- SQL 2012 and later has TRY_CAST and TRY_CONVERT
If you're on an earlier version then you can write a function that'll convert to a decimal (or NULL if it won't convert). This uses the XML conversion functions that don't throw errors when the number won't fit ;)
-- Create function to convert a varchar to a decimal (returns null if it fails)
IF EXISTS( SELECT * FROM sys.objects WHERE object_id = OBJECT_ID( N'[dbo].[ToDecimal]' ) AND type IN( N'FN',N'IF',N'TF',N'FS',N'FT' ))
DROP FUNCTION [dbo].[ToDecimal];
GO
CREATE FUNCTION ToDecimal
(
#Value VARCHAR(MAX)
)
RETURNS DECIMAL(18,8)
AS
BEGIN
-- Uses XML/XPath to convert #Value to Decimal because it returns NULL it doesn't cast correctly
DECLARE #ValueAsXml XML
SELECT #ValueAsXml = Col FROM (SELECT (SELECT #Value as Value FOR XMl RAW, ELEMENTS) AS Col) AS test
DECLARE #Result DECIMAL(38,10)
-- XML/XPath will return NULL if the VARCHAR can't be converted to a DECIMAL(38,10)
SET #Result = #ValueAsXml.value('(/row/Value)[1] cast as xs:decimal?', 'DECIMAL(38,10)')
RETURN CASE -- Check if the number is within the range for a DECIMAL(18,8)
WHEN #Result >= -999999999999999999.99999999 AND #Result <= 999999999999999999.99999999
THEN CONVERT(DECIMAL(18,8),#Result)
ELSE
NULL
END
END
Then just change your query to:
select dbo.ToDecimal(Reserve) from MyReserves
isnumeric is not 100% reliable in SQL - see this question Why does ISNUMERIC('.') return 1?
I would guess that you have value in the reserve column that passes the isnumeric test but will not cast to decimal.
Just a heads up on isnumeric; if the string contains some numbers and an 'E' followed by some numbers, this is viewed as an exponent. Example, select isnumeric('123E0') returns 1.
I had this same problem and it turned out to be scientific notation such as '1.72918E-13' To find this just do where Reserve LIKE '%E%'. Try bypassing these and see if it works. You'll have to write code to convert these to something usable or reformat your source file so it doesn't store any numbers using scientific notation.
IsNumeric is possibly not ideal in your scenario as from the highlighted Note on this MSDN page it says "ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($)."
Also there is a nice article here which further discusses ISNUMERIC.
Try (for example):
select
cast(Reserve as decimal(10,2))
from MyReserves
Numeric/Decimal generally want a precision an scale.
I am also facing this issue and I solved by below method. I am sharing this because it may helpful to some one.
declare #g varchar (50)
set #g=char(10)
select isnumeric(#g),#g, isnumeric(replace(replace(#g,char(13),char(10)),char(10),''))