T-SQL :: Error converting data type varchar to numeric when changing 1 to 0.5 - sql

I'm writing a complex T-SQL query with CASE that will help me calculate how much time it will take me to migrate databases based on the size of each database:
SELECT
ProductVersion
,CompatibilityLevel
,convert(numeric(10,2), substring([Size], 1, (len([Size]) - 3))) as [Size in MB]
,CASE
when ProductVersion < '11%' THEN 1
when ProductVersion = NULL then 1
ELSE ''
END +
CASE
when CompatibilityLevel < '110' then 1
when CompatibilityLevel = NULL then 1
ELSE ''
END +
CASE
when convert(numeric(10,2), substring([Size], 1, (len([Size]) - 3))) < 100.00 THEN 1 -- Here is the problem
ELSE ''
END AS [Hours of work]
FROM MyDatabaseList
All good, it works when I set 1 hour of work for every database which has less then 100.00 MB.
Also all other values are summed and in the Hours of work column you can see numbers like 0, 1, 3, 2...
This means SQL Server is calculating values. All good.
But well, telling to my manager that I have to work 1 hour for a database that only has 100.00 MB of size is ridiculous.
Let's change the line:
when convert(numeric(10,2), substring([Size], 1, (len([Size]) - 3))) < 100.00 THEN 1
and let's put 0.5 instead of 1:
when convert(numeric(10,2), substring([Size], 1, (len([Size]) - 3))) < 100.00 THEN 0.5
...and bang - I get this error:
Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to numeric.
Questions:
Why this error now?
Why it was successfully calculating before and now needs a datatype somewhere?
What change do I have to add to my query?
Why it says on Line 1? The error must be on Line 16, right?

The error is telling you the conversion is happening in the statement that starts in line 1.
As for why, it's because '' cannot be converted to a numeric but it can be converted to an int.
SELECT CONVERT(decimal(2,1),'')
--Error converting data type varchar to numeric.
GO
SELECT CONVERT(int,'')
--
GO
You were previously converting it to an int (the literal 1 is an int). Get out of the habit of declaring '' for a number; it is by definition not a number, it is a zero length string. If you want zero, then use 0.

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]

When pass value of field name without unit of measure it give error so How to solve?

I work on SQL Server 2012 query - I get an error:
Invalid length parameter passed to the LEFT or SUBSTRING function.
Code:
SELECT
LEFT([Impedance], PATINDEX('%[^0-9.]%', [Impedance]) - 1) AS [Impedance],
RIGHT([Impedance], LEN([Impedance]) - PATINDEX('%[^0-9.]%', [Impedance]) + 1) AS [ImpedanceUnits]
FROM
##NewTable0
I have a column Impedance with values such as 50kg as example. It splits this values to 50 and kg without any issue.
Problem occurs when the column contains only 50, without any unit of measure.
In this case, I get an error:
Invalid length parameter passed to the LEFT or SUB STRING function.
How to solve this error please?
To summarize my issue : how to handle error when column impedance has a number only, such as 50 - to work without causing an error?
50kg is working fine
50 causes an error
Update: I don't have any issue on number with unit of measure as 50kg, I only have an issue when I have only a number, such as 50, without unit of measure.
This is my issue below I need to solve
SELECT
Impedacte = (CASE
WHEN PATINDEX('%[^0-9.]%', '50') > 0
THEN LEFT('50', PATINDEX('%[^0-9.]%', '50') - 1)
ELSE '50'
END),
ImpedanceUnits = (CASE
WHEN PATINDEX('%[^0-9.]%', '50') > 0
THEN RIGHT('50', (LEN('50') - PATINDEX('%[^0-9.]%', '50') + 1))
ELSE NULL
END)
Just add an extra character so the PATINDEX() returns an appropriate value:
LEFT([Impedance], PATINDEX('%[^0-9.]%', [Impedance] + ' ') - 1) AS [Impedance],

SQL Unable to Convert Varchar to Numeric - Conversion failed error

I need to convert serial numbers in a database table to show as numeric or int. I have attempted to convert them but it does not seem to like certain values like the following: 1.02253e+007. Getting an error stating:
Msg 245, Level 16, State 1, Line 2
Conversion failed when converting the varchar value '1.02253e+007' to
data type int.
Is there something I am leaving out? Any help much appreciated
SELECT [ID]
,[SalesOrder]
,[JobNumber]
,[StockCode]
,SerialNumber
,CONVERT(NUMERIC(16, 0), CAST(CASE
WHEN ISNUMERIC(SerialNumber) = 1 THEN
SerialNumber
ELSE 0
END AS FLOAT))
Receiving error:
Msg 245, Level 16, State 1, Line 2
Conversion failed when converting the varchar value '1.02253e+007' to data type int.
The case is returning an integer, which is your problem. You are doing lots of intermediate conversions that are not necessary. Just do:
(CASE WHEN ISNUMERIC(SerialNumber) = 1
THEN CONVERT(NUMERIC(16, 0), SerialNumber)
ELSE 0
END)
Or better yet:
COALESCE(TRY_CONVERT(NUMERIC(16, 0), SerialNumber), 0)
If you need to support exponential values (such as 1.02253e+007), then you do need the intermediate conversion to float:
TRY_CONVERT(NUMERIC(16, 0),
COALESCE(TRY_CONVERT(float, SerialNumber), 0)
)

Attempting to determine decimals places using CHARINDEX, getting: Error converting data type varchar to float

I use this piece of code all the time on many objects when trying to determine the number of decimals after the '.'. The target system I am moving data to can only handle 2 d.p. So we I find data with >2 d.p. I multiply by 10, 100, 1000 and also multiply the 'price per' field value by the same factor.
SELECT
HQPROD, [HQPR1],
Decimals = CASE Charindex('.', [HQPR1])
WHEN 0 THEN 0
ELSE LEN(CAST(CAST(REVERSE(CONVERT(VARCHAR(50), [HQPR1], 128)) AS FLOAT) AS BIGINT))
END
FROM
[SM_REP].[dbo].[BPCSF64_HQT]) EDP ON P.HQPROD = EDP.HQPROD
The column datatype I am working with is DECIMAL(15,5).
Sample data:
HQPROD HQPR1
--------------------------
47001-RM64 175.89900
47001-T06OX 5.84500
47002-20T 80.44700
47002-T24 98.10300
47002-T32 144.07000
47003-01 1.54000
47003-02 1.54000
47003-03 0.51000
Error message:
Error converting data type varchar to float.
SELECT
HQPR1,
Decimals =
CASE WHEN HQPR1 > 0 THEN
CASE Charindex('.', [HQPR1])
WHEN 0 THEN 0
ELSE LEN(CAST(CAST(REVERSE(CONVERT(VARCHAR(50), [HQPR1], 128)) AS FLOAT) AS BIGINT))
END
ELSE
CASE Charindex('.', [HQPR1])
WHEN 0 THEN 0
ELSE LEN(CAST(CAST(REVERSE( Stuff((CONVERT(VARCHAR(50), [HQPR1], 128)),1,1,'' )) AS FLOAT) AS BIGINT))
END
END
This will work also for negative numbers, which as sticky bit said,could be causing your error.

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)