Convert different scientific notations to numeric - sql

I have a table with a varchar field that contains values with the following structures:
1.69665589928627E-06
3.57807129940753E-07
4.77823428809643E-08
1.58324837684631E-12
1.57160684466362E-13
0.0062
10.1595896112714
0.0505828946151305
0.739
0
How to convert these values to Numeric(12,6)?
I tried using CAST:
SELECT CAST (NUM_AREA AS NUMERIC(12,6)) FROM APP
SELECT CAST(CAST(NUM_AREA AS FLOAT) AS NUMERIC(12,6)) FROM APP
But the following error is generated:
Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to numeric.

Being a nvarchar, I suspect you have some bogus data.
Use try_convert() which will return a NULL rather than throwing a error
Example or dbFiddle
Declare #YourTable Table ([Num_Area] nvarchar(50)) Insert Into #YourTable Values
('1.69665589928627E-06')
,('3.57807129940753E-07')
,('4.77823428809643E-08')
,('1.58324837684631E-12')
,('1.57160684466362E-13')
,('0.0062')
,('10.1595896112714')
,('0.0505828946151305')
,('0.739')
,('0')
,('Not A NUmber') -- WOULD THROW AN ERROR USING CONVERT or CAST
,('1.57160684466362E-55') -- REALLY SMALL NUMBER, YOU'LL JUST GET ZERO
Select *
,try_convert(numeric(12,6),try_convert(float,Num_Area))
from #YourTable
--**To Identify the Problem Rows**
Select *
From #YourTable
Where try_convert(float,Num_Area) is null
and Num_Area is not null
Results

Related

How to convert from nchar to decimal in SQL?

I have 2 tables(source and destination) which are respectively NOR_LABOR and ALL_LABOR_DETAILS. In the source table(NOR_LABOR) there is a column "feet_produced" with the data type "nchar(10)". In the destination table(ALL_LABOR_DETAILS) there's a column "labor_feet_produced" with the data type "decimal(18,4)". I want to convert the "feet_produced" from nchar(10) to decimal(18,4) and paste it in the "ALL_LABOR_DETAILS" table's "labor_feet_produced" column.
I have found a code regarding a simillar issue but did not do the exact as I need to do, following is that code snippet :
Select feet_produced AS feet_produced_s, CASE WHEN Isnumeric(feet_produced) = 1
THEN CONVERT(DECIMAL(18,2),feet_produced)
ELSE 0 END AS feet_produced
INTO [MES_DEV].[dbo].[ALL_LABOR_DETAILS]
from [dbo].[NOR_LABOR]
Thank you!
There are values that will test true for IS_NUMERIC, but will fail to convert to decimal.
Instead, use TRY_CONVERT which will return either the successfully-converted-to-decimal value, or a NULL when it fails. (You can then COALESCE to zero to get your desired result).
Here is a short example set of values, using TRY_CONVERT:
SELECT
TryConvert = COALESCE(TRY_CONVERT(decimal(18,4),TestValues),0)
FROM (
VALUES('10.6'),
('ten'),
('7d2'),
('10000000000'),
('10.00000001')
) AS x(TestValues);
The same set of values using your example code will throw an error:
SELECT
IsNumericCase = CASE
WHEN Isnumeric(TestValues) = 1
THEN CONVERT(DECIMAL(18,2),TestValues)
ELSE 0
END
FROM (
VALUES('10.6'),
('ten'),
('7d2'),
('10000000000'),
('10.00000001')
) AS x(TestValues);
This error is returned because 7d2 is numeric, but cannot be converted to decimal.
Msg 8114, Level 16, State 5, Line 14
Error converting data type varchar to numeric.
Im not sure what the issue is with the code that dose not work for you.
But here is how I would do it with a small change in the statement that you just post it.
insert into[MES_DEV].[dbo].[ALL_LABOR_DETAILS](labor_feet_produced)
select CONVERT(DECIMAL(18, 4), feet_produced) AS feet_produced_s from[dbo].[NOR_LABOR]

Error converting data type varchar to float in assigned column

Hey I am trying to convert the data type from varchar to float of the column name 'Identification'. Below are the queries that I have created and both are throwing the error
Select distinct Convert(float,(Replace([Identification], '-',''))) FROM [A]
where identification is NOT Null;
Select Cast(Replace([Identification], '-','') AS FLOAT) FROM [A]
where identification is NOT Null;
Error Msg:
Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to float.
Haaaz, try this:
CASE WHEN ISNUMERIC([Identification]) THEN CONVERT(float,
[Identification])
select cast('' as xml).value('xs:float(sql:column("val"))', 'float')
from (values ('a'),('b'), ('-123')) v(val);
CREATE TABLE ATest(Identification varchar(100));
INSERT INTO ATest(Identification)
VALUES('A'),('B'), ('A-B-123'), ('123-456'), ('1-1-1-1-1'),
('123-E10'), /*you might need to handle this type of values when scientific notation should NOT be converted to float...
....eg. just replace E with another letter*/
('------1------')
;
SELECT
Identification, ReplacedIdentification,
cast('' as xml).value('xs:float(sql:column("src.ReplacedIdentification"))', 'float') as ToFloatOrNull
FROM
(
Select [Identification], Replace([Identification], '-','') ReplacedIdentification
FROM [ATest]
WHERE[Identification] IS NOT Null
) as src
--use this to find Identification values which cannot be converted to float
--WHERE cast('' as xml).value('xs:float(sql:column("src.ReplacedIdentification"))', 'float') IS NULL;
DROP TABLE Atest;
GO

How to convert varchar(4) to float in SQL Server 2008?

I'm trying to convert my database fields from VARCHAR(4) to FLOAT. Some of the values in these fields might not be digits since these fields didn't have any validation prior. My main target is to convert any integer or decimal value in float format and save in new database field. For this process I use INSERT SELECT STATEMENT from old table into the new table. So far I have this line of code for my conversion:
CASE WHEN LEN(LTRIM(RTRIM(hs_td2))) <> 0 AND ISNUMERIC(hs_td2) = 1 THEN CAST(LTRIM(RTRIM(hs_td2)) AS float) ELSE NULL END AS hs_td2
First step I trim the value then check if it's numeric and then convert to float otherwise set to NULL. With the code above I'm getting this error message in Microsoft Studio:
Msg 8114, Level 16, State 5, Line 13
Error converting data type varchar to float.
Line 13th is beginning of my SELECT statement. Then I tried this conversion as well:
CASE WHEN LEN(LTRIM(RTRIM(hs_td2))) <> 0 AND ISNUMERIC(hs_td2) = 1 THEN CONVERT(FLOAT, LTRIM(RTRIM(hs_td2))) ELSE NULL END AS hs_td2
and I got the same error message. Values in my fields could be something like this:
10 or 5 or -10 or 0.9 or 11.6 or -11.89 and so on...
I'm wondering if isNumeric() is the best function that I should use and why my code produces the error message listed above?
If anyone can help please let me know. Thank you!
No, ISNUMERIC is not the best function to use.
Essentially, this question has been asked before, though not in this wording:
Try_Convert for SQL Server 2008 R2
The most upvoted answer recommends to cast to XML to use XML-specific casting function:
DECLARE #T TABLE (v varchar(4));
INSERT INTO #T (v) VALUES
('1g23'),
('-1.8'),
('11.6'),
('akjh'),
('.'),
('-'),
('$'),
('12,5');
select
cast('' as xml).value('sql:column("V") cast as xs:float ?', 'float') as new_v
from #T
I'll leave my first version of the answer below.
Most likely you are getting the conversion error because the server tries to run CAST(LTRIM(RTRIM(hs_td2)) AS float) for each row of the table, not only for those that are numeric.
This usually happens when you try to filter out non-numeric rows using the WHERE ISNUMERIC(...) = 1 filter. Technically it may happen in CASE expression as well.
That's why they added TRY_CONVERT in 2012.
I'd try to write my own user-defined function that uses TRY-CATCH and tries to convert the given value. Yes, it will be slow.
Having said that, the example below with CASE runs fine:
DECLARE #T TABLE (v varchar(4));
INSERT INTO #T (v) VALUES
('123'),
('-1.8'),
('11.6'),
('akjh'),
('123');
SELECT
CASE WHEN ISNUMERIC(v) = 1 THEN CAST(v AS float) ELSE NULL END AS new_v
FROM #T;
Result
+-------+
| new_v |
+-------+
| 123 |
| -1.8 |
| 11.6 |
| NULL |
| 123 |
+-------+
But, if I put a . or - or $ value, like so:
INSERT INTO #T (v) VALUES
('123'),
('-1.8'),
('11.6'),
('akjh'),
('$');
The query fails:
Error converting data type varchar to float.
There may be other special characters and their combinations that ISNUMERIC would not complain about. That's why I originally said that overall, ISNUMERIC is not the best function to use.
If it is a one-off conversion, you can try to build a LIKE expression to catch all special cases that are present in your data, but if you need a reliable generic solution, upgrade to 2012+ and use TRY_CONVERT or write your T-SQL UDF, or your CLR UDF.
Sqlxml has enough power to make magic. Of course, the performance is the problem. But still better, than million of conditions
DECLARE #T TABLE (v varchar(4));
INSERT INTO #T (v) VALUES
('123'),('-1.8'),('11.6'),('akjh'),('$'),('-.'),('-.1'),(NULL);
declare #Xml xml = (SELECT v FROM #T T for xml auto,elements);
select T.v.value('v[1]','varchar(4)') v, T.v.value('max(v[1])','float') converted_v
from #xml.nodes('/T') T(v);
It depends on the values in your varchar columns
ISNUMBER() for vaule such as '.' and '-' will return 1, however, it will failed when you CAST to FLOAT
ISNUMBER() for value such as '3D2' , '1e2' will return 1, and can be CAST to FLOAT, however, you may not want consider it as number.
You may try the following to convert
CASE WHEN
not LTRIM(RTRIM(hs_td2))like '%[^0-9.,-]%' -- Value only contains 0-9 . -
and LTRIM(RTRIM(hs_td2)) not like '.' -- can not be only .
and LTRIM(RTRIM(hs_td2)) not like '-' -- can not be only -
and isnumeric(LTRIM(RTRIM(hs_td2))) = 1
THEN CAST(LTRIM(RTRIM(hs_td2)) AS float)
ELSE NULL
END

Why am I unable to convert datatype to return blank cells for values of 0 or NULL?

I am currently trying to return '' for values that are either NULL or 0, but am unable to do so:
select isnull(cast(sec_column as varchar(10)),'')
sec_column is Numeric
The above produces the follow sql error:
"Arithmetic overflow error converting numeric to data type varchar"
Additionally, I have tried something simpler along the lines of an ISNULL to achieve this, but to no avail:
select isnull(sec_column,'')
I assume that I should be able to cast as a string value and return blank. Any insight into this would be much appreciated!
That error for the given code would indicate you need a larger varchar():
select isnull(cast(sec_column as varchar(39)),'')
declare #val numeric(38,2) = '123456789123456789123456789123456789.12'
/* works fine */
select convert(varchar(39),#val)
select convert(varchar(10),#val)
/* Arithmetic overflow error converting numeric to data type varchar. */
rextester demo: http://rextester.com/GMYUUN51608
Perhaps this can help.
Assuming sec_column is a numeric, and you want to show zeros and nulls as ""
select isnull(cast(nullif(sec_column,0) as varchar(10)),'')
Example
Declare #YourTable Table (sec_column int)
Insert Into #YourTable Values
(1)
,(null)
,(25)
,(0)
select *
,AsString = isnull(cast(nullif(sec_column,0) as varchar(10)),'')
From #YourTable
Returns
sec_column AsString
1 1
NULL
25 25
0

Error converting data type varchar to numeric -joining tables

I am not able to join two columns with different data types.
main_ref_id is char and person_id are numeric
Query:
select
main_ref_id
from
not
where
main_ref_type = 'P'
and convert(numeric(9, 0), main_ref_id) in (select cast(person_id as numeric)
from person_wo_memberships)
Error
Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to numeric.
Any help???
You have stated that main_ref_id is char, but you are trying to convert that into a numeric value. The error is self-explanatory.
Try converting person_id, which is numeric to char
select main_ref_id
from [not]
where main_ref_type='P' and
main_ref_id in
(select cast(person_id as varchar)
from person_wo_memberships )
Please define the length of varchar in the cast statement, to match the length of main_ref_id