Error in Converting nvarchar to int - sql

I have one table #DateDay_temp in which there is a column ExtraAdultPrice of type NVARCHAR(20). When I am trying to run this statement in a stored procedure
DECLARE #ExtraAdultPAX DECIMAL(10,2)
SELECT
#ExtraAdultPAX = SUM(CAST((CASE ISNULL(ExtraAdultPrice, '')
WHEN '' THEN 0
ELSE ExtraAdultPrice END) AS DECIMAL(10,2)))
FROM #DateDay_temp;
When I am passing the value 54.56 in the ExtraAdultPrice" column, I get the error
Conversion failed when converting the nvarchar value '54.56' to data
type int.
Help would be appreciated.

Most likely this error happens because of the fact you have a 0 in your CASE statement; therefore, the "type" of the CASE statement is decided to be an INT - which is completely wrong here....
Try this instead:
SELECT
#ExtraAdultPAX = SUM(CAST((CASE ISNULL(ExtraAdultPrice, '')
WHEN '' THEN 0.00 <<== use "0.00" instead of just "0" !!
ELSE ExtraAdultPrice
END) AS DECIMAL(10,2)))
FROM
#DateDay_temp;
Now, everything should be DECIMAL(10,2) and there shouldn't be any attempt to convert your values to an INT

54.56 isn't an int because of the decimal point.

Related

Why is SQL Server trying to convert my nvarchar(20) datatype to an int?

I'm getting the "conversion" error in a SQL Select query.
The error is:
Msg 248, Level 16, State 1, Line 6
The conversion of the nvarchar value '7000952682' overflowed an int column.
Problem is, there are no int columns in my table!
Here is the table structure:
Here is the query:
If I set the value of #SU to NULL, then it does return all rows as expected. When the value is set to the string value of '7000952682' I get the error.
Why is SQL Server trying to convert the nvarchar value to an int?
All branches of a CASE expression have to have the same type. In this case (no pun intended), it looks like SQL Server is using an integer type and doing an implicit cast of SU to integer. The problem is that the max value for an integer in SQL Server is roughly 2.1 billion, and the example you gave is using the value 7000952682, hence the overflow.
You have two options here. You could make everything varchar:
CASE WHEN #SU IS NULL OR #SU = '' THEN '1' ELSE [SU] END
Or, you could make everything numeric, using a type that won't overflow, e.g.
CASE WHEN #SU IS NULL OR #SU = ''
THEN CAST(1 AS numeric(20, 6))
ELSE CAST([SU] AS numeric(20, 6)) END
As a side note, you could write the first part of your CASE expression more succinctly using COALESCE:
CASE WHEN COALESCE(#SU, '') = '' THEN '1' ELSE [SU] END
Don't use case in the where clause. The logic is more simply and accurately expressed as:
where (#su is null or #su = '' or #su = su)

SQL "select case" gives unexpected output

For the love of god can someone please explain me what is going on here.
I am working on some stored procedure bug fixes, after a lot of struggle, I was able to find out where this strange bug is happening so I've made a simple example for the sake of demonstration.
Case 1
DECLARE #test VARCHAR(45) ='0001'
SELECT CASE 0
WHEN -1 THEN ''
WHEN 0 THEN #test
WHEN 1 THEN 12345
END AS 'output'
Case 2
DECLARE #test VARCHAR(45) ='0001'
SELECT CASE 0
WHEN -1 THEN ''
WHEN 0 THEN #test
END AS 'output'
Case 1: output is 1
Case 2: output is 0001 as expected
What happened to the zeros?
strangely it only removes zeros before the number (no matter what number comes at the end), for example DECLARE #test VARCHAR(45) ='1000' works fine, as far case is concerned it is clear that case is zero, if I remove WHEN 0 THEN #test output is null as expected.
Done some research, found only this.
I am using SQL SERVER RC1 2017 as well as SQL SMS.
Thank you for your time.
The difference here is that you have mutliple data types in your THEN/ELSE expressions. In your "CASE 1" you have both int and and varchar datatypes.
int has a higher Data type precedence (Transact-SQL) than a varchar, so the values are returned as an int.
Use the same datatype through out, and this works as you want it to:
DECLARE #test VARCHAR(45) ='0001';
SELECT CASE 0 WHEN -1 THEN ''
WHEN 0 THEN #test
WHEN 1 THEN '12345' --Note that the value in contained in single quotes
END AS [output];
This is because of data type precedence.
The CASE expression documentation says about the returned data type:
Returns the highest precedence type from the set of types in
result_expressions and the optional else_result_expression
Meaning it looks every set of types in the result expressions. Since you have one where the returned data is an INT, then the result of the whole CASE expression is INT (since it has a higher precedence than VARCHAR)
This is happening because the type of the value returned in your last case statement is numeric, so try to change it to
DECLARE #test VARCHAR(45) ='0001'
SELECT CASE 0
WHEN -1 THEN ''
WHEN 0 THEN #test
WHEN 1 THEN '12345'
END AS 'output'

how to convert id datatype in sql server

I have data like
id
27.45
29.1
27.45
21.95
18.1
51.75
0
21.45
41.94
21.95
32.95
My query is
SUM(CASE WHEN ab.dates BETWEEN bc.fst_sales_date AND BC.[WEEK4] THEN
[salesval] -- my initial try
ELSE 0 END) week4_qtyvalues
facing error
Conversion failed when converting the nvarchar value '41.94' to data
type int.
I have checked
SUM(CASE WHEN ab.dates BETWEEN bc.fst_sales_date AND BC.[WEEK4] THEN
CONVERT(float,[salesval]) -- this is what I've tried
ELSE 0 end) week4_qtyvalues
and
SUM(CASE WHEN ab.dates between bc.fst_sales_date AND BC.[WEEK4] THEN
CAST([salesval]AS int) -- this is what I've tried
ELSE 0 END) week4_qtyvalues
Regardless of my tries , I'm still facing the same error.
DECLARE #t TABLE (id VARCHAR(10))
INSERT INTO #t (id)
VALUES
('27.45'),('29.1'),('27.45'),('21.95'),('18.1'),
('51.75'),('0'),('21.45'),('41.94'),('21.95'),('32.95')
SELECT SUM(CASE WHEN id IS NOT NULL THEN CAST(id AS FLOAT) ELSE 0 END)
FROM #t
That is happening because you have a nvarchar and not a float number to cast to int. You should first cast the [salesval] to float and after that cast it to int. Something like this:
CAST(CAST([salesval] AS float) AS INT)
Because of the way SQL Server handles statements with multiple data types mixed together, it'll still try to take your salesval field and treat it as an int.
So, firstly, try casting the 0 as well.
And secondly, you almost certainly don't want to use float - it's for scientific calculations that need its huge range only and isn't precise. Try decimal instead.

Conversion failed when converting the varchar value 645.00 to data type int

I am working on a SQL Query which performs some division operation on a column which is of type decimal(18,4) and should return a value of type decimal but for some reasons, It is giving me an error
Conversion failed when converting the varchar value 645.00 to data type int
I am not making any conversion to the value and yet I have no idea why that is trying to convert it to int.
My query part is as follows
CASE WHEN co.RequestID IS NOT NULL THEN cd.ConsDetQty/1000 WHEN nis.[867_key] IS NOT NULL
THEN q.Quantity/1000 ELSE q2.Quantity/1000 END AS 'Quantity'
May I know if I am wrong anywhere?
TRY THIS
CASE WHEN co.RequestID IS NOT NULL THEN CONVERT(DECIMAL(18,4),cd.ConsDetQty)/1000
WHEN nis.[867_key] IS NOT NULL THEN CONVERT(DECIMIAL(18,4),q.Quantity/1000
ELSE CONVERT(DECIMAL(18,4),q2.Quantity)/1000
END AS 'Quantity'
Your case statement is:
(CASE WHEN co.RequestID IS NOT NULL
THEN cd.ConsDetQty/1000
WHEN nis.[867_key] IS NOT NULL
THEN q.Quantity/1000
ELSE q2.Quantity/1000
END) AS Quantity
For this code to generate an error like that, cd.ConsDetQty, q.Quantity, or q2.Quantity is stored as a string rather than a number. You should fix the column, but you can quickly fix the query by doing:
(CASE WHEN co.RequestID IS NOT NULL
THEN cd.ConsDetQty/1000.0
WHEN nis.[867_key] IS NOT NULL
THEN q.Quantity/1000.0
ELSE q2.Quantity/1000.0
END) AS Quantity
That is a "quick-and-dirty" fix. I do not recommend having implicit conversions in real code. Better to do:
(CASE WHEN co.RequestID IS NOT NULL
THEN cast(cd.ConsDetQty as float)/1000.0
WHEN nis.[867_key] IS NOT NULL
THEN cast(q.Quantity as float)/1000.0
ELSE cast(q2.Quantity as float)/1000.0
END) AS Quantity

why does my nested case statement return a character set mismatch?

I've been building a fairly simple update statement that includes a nested case statement to determine the update value. Column description is the same nvarchar(32) For both fields.
code below
UPDATE TableA t
SET t.Last_Col =
( CASE WHEN t.First_Col = 'ItemOne'
THEN 'anItemOne'
WHEN t.First_Col = 'ItemTwo'
THEN CASE WHEN t.Second_Col = 'ItemTwo_A'
THEN 'aSecondItem_A'
ELSE 'aSecondItem'
END
ELSE 'NoItem'
END
);
That code works but when I try to use t.First_Col in place of string 'NoItem' I get the character set mismatch.
ELSE t.First_Col
END
);
doesn't work. t.First_Col and t.Last_Col are both nvarchar2(32) and I've been trying to work with a cast which I think shouldn't be needed anyway.
ELSE CAST(t.First_Col AS NVARCHAR2(32))
END );
Any hints or advice are greatly appreciated.
As always thanks in advance.
The type of a case statement is determined by the first clause in it. In this case, the first clause is a varchar string rather than an nvarchar.
Try this:
UPDATE TableA t
SET t.Last_Col = (CASE WHEN t.First_Col = N'ItemOne'
THEN N'anItemOne'
WHEN t.First_Col = N'ItemTwo'
THEN (CASE WHEN t.Second_Col = N'ItemTwo_A'
THEN N'aSecondItem_A'
ELSE N'aSecondItem'
END)
ELSE N'NoItem'
END );
It looks like the character set mismatch is between the options for the CASE statement to return.
Working
'anItemOne' varchar
'aSecondItem_A' varchar
'aSecondItem' varchar
'NoItem' varchar
Not Working
'anItemOne' varchar
'aSecondItem_A' varchar
'aSecondItem' varchar
t.First_Col nvarchar
Fix
Try making your return options nvarchars (ie N'anItemOne') and then it should be fine with t.First_Col.
N'anItemOne' nvarchar
N'aSecondItem_A' nvarchar
N'aSecondItem' nvarchar
t.First_Col nvarchar