Difference in the checksum SQL statements - sql

What is the difference between the 2 different statements below? Please explain the output.
SELECT CHECKSUM(CONVERT(NVARCHAR,30))
Result : 51136012
DECLARE #AA NVARCHAR
SET #AA= CONVERT(NVARCHAR,30)
SELECT CHECKSUM(#AA)
Result: 38

The default lengths are different. In the first, it is something like 32. But when you do:
declare #aa nvarchar;
The default length is 1. So, the second is only using the first character.
In SQL Server, always use lengths with the varchar() types:
SELECT CHECKSUM(CONVERT(NVARCHAR(255), 30))
DECLARE #AA NVARCHAR(255);
SET #AA= CONVERT(NVARCHAR(255), 30);
SELECT CHECKSUM(#AA);

Related

Rounding a decimal value with dynamic variable

I need to round a value of a column in table A based on another column in table B in a SQL function.
DECLARE #currencyround INT
SELECT #currencyround = ISNULL(currencyround, 2)
FROM dbo.PRTL_currencySettings
When I put value of #currencyround directly in the query like the following, it's working fine:
SELECT
CAST(POS.BALANCE AS DECIMAL(18, 2)) AS DBAmount
FROM
dbo.POS_SALES POS
When I put value of #currencyround like the following, it's showing error:
Incorrect syntax near '#currencyround'.
SELECT
CAST(POS.BALANCE AS DECIMAL(18, #currencyround)) AS DBAmount
FROM
dbo.POS_SALES POS
If you need specific metadata you could use dynamic SQL:
DECLARE #currencyround int;
SELECT #currencyround=ISNULL(currencyround,2) FROM dbo.PRTL_currencySettings;
DECLARE #sql NVARCHAR(MAX) =
N'select CAST(POS.BALANCE AS DECIMAL(18,<currencyround>)) AS DBAmount
FROM dbo.POS_SALES POS';
SET #sql = REPLACE(#sql, '<currencyround>', #currencyround);
EXEC(#sql);
But personally I would not write such code. I would rather format the number in the application layer.
What do you not understand? Type definitions don't allow variables. You could do this with dynamic SQL but that seems like overkill.
If you care about what how the variable is output, use str() or format() to create the format that you want.
If you need to round the values, then how about this:
ROUND(POS.BALANCE, #currencyround)

CAST always returns 1

I'm executing this TSQL Code:
DECLARE #myString varchar;
SET #myString = '123.0'
SELECT CAST(#myString as decimal(25,10))
But I keep getting 1.00000 as an result
Changing myString to '123' doesn't change that.
Any advise on what I'm doing wrong is appreciated.
Thanks in advance!
ALWAYS use length when using varchar() (and related types) in MySQL. The default is 1 in this context. So this fixes your problem:
DECLARE #myString varchar(255);
SET #myString = '123.0';
SELECT CAST(#myString as decimal(25,10));
You are getting 1, because your code is interpreted as
DECLARE #myString varchar(1);
SET #myString = '123.0';
SELECT CAST(#myString as decimal(25,10));
The documentation is not shy about this:
When n is not specified in a data definition or variable declaration
statement, the default length is 1. When n is not specified when using
the CAST and CONVERT functions, the default length is 30.
You are missing the varchar declareation
DECLARE #myString varchar(10);
SET #myString = '123.0'
SELECT CAST(#myString as decimal(25,10))

Extracting nvarchar value from XML in T-SQL: only one character returned

In my T-SQL procedure I'm trying to extract a string value from the XML node using the .value() method, like this:
declare #criteria xml;
set #criteria = N'<criterion id="DocName"><value>abcd</value></criterion>';
declare #val nvarchar;
set #val = #criteria.value('(criterion[#id="DocName"]/value)[1]', 'nvarchar');
select #val;
I expected to get 'abcd' as a result, but I surprisingly got just 'a'.
So, the value method returns only the 1st character of the string. Can anybody tell me, what am I doing wrong? Thanks a lot.
P.S. I'm using MS SQL Server 2012
Don't use nvarchar without size. From documentation:
When n is not specified in a data definition or variable declaration
statement, the default length is 1. When n is not specified with the
CAST function, the default length is 30.
If you don't know exact length, you always can use nvarchar(max):
declare #criteria xml;
set #criteria = N'<criterion id="DocName"><value>abcd</value></criterion>';
declare #val nvarchar(max);
set #val = #criteria.value('(criterion[#id="DocName"]/value)[1]', 'nvarchar(max)');
select #val;
sql fiddle demo

SQL Server : How to use variables? [duplicate]

This question already has an answer here:
Varchar variable is not working in WHERE clause
(1 answer)
Closed 8 years ago.
I am trying the following query and it works as I expect it to
SELECT RIGHT('0000' + CAST(MAX(party_id)+1 AS VARCHAR(4)),4) FROM PARTY
The result is:
0147
But when I execute the following query so that I can store this value in a variable
DECLARE #pid varchar;
SELECT #pid = RIGHT('0000' + CAST(MAX(party_id)+1 AS VARCHAR(4)),4) FROM PARTY
SELECT #pid as party_id
it doesn't return 0147 as in the above query, instead what it returns is
0
Can anyone please tell me what I am doing wrong here?
You should always define a length when you declare a varchar !!
This
DECLARE #pid varchar;
gives you a varchar of exactly ONE character length!!
Use
DECLARE #pid varchar(20);
and your problem is solved ...
Yo have not declared size of varchar that is why it is truncating.
Set size sufficiently large to store result.
DECLARE #pid varchar(10);
SELECT #pid = RIGHT('0000' + CAST(MAX(party_id)+1 AS VARCHAR(4)),4) FROM PARTY
SELECT #pid as party_id
From SQL Server MSDN
varchar [ ( n | max ) ]
Variable-length, non-Unicode string data. n
defines the string length and can be a value from 1 through 8,000. max
indicates that the maximum storage size is 2^31-1 bytes (2 GB). The
storage size is the actual length of the data entered + 2 bytes. The
ISO synonyms for varchar are char varying or character varying.
When n is not specified in a data definition or variable declaration
statement, the default length is 1.
DECLARE #pid varchar; implies a varchar of length 1.
Try DECLARE #pid varchar(4);

Cannot cast nvarchar to float

I have a weird problem.
In my query I select 5 columns which two of them are nvarchar in the form of numeric (only contains number and precision point), and other three are uniqueIdentifier and nvarchar.
I want to cast these two columns to Float in my select statement but I'm getting an error
Cannot cast nvarchar to float.
I checked the format of all these values many many times. Trust me, they are fine.
But when I just select these two columns and cast them to float the query runs successfully.
I appreciate any help on this subject.
I can paste the query here too. but the whole query is more then 100 lines and this will be frustrating to write and read!
Definitely going to need more info from you before answering. Can you post some of your code (or a small reproduction of your issue)? Perhaps your table definition as well?
Since all of the values are numeric, why leave the column as an nvarchar?
Finally, does any of your data contain a dollar sign ($)?
This works:
DECLARE #Text nvarchar(100)
SET #Text = '1234.567'
SELECT CONVERT(float, #Text) AS ColumnValue
So does this:
DECLARE #Text nvarchar(100)
SET #Text = ' 1234.567 '
SELECT CONVERT(float, #Text) AS ColumnValue
But this does not:
DECLARE #Text nvarchar(100)
SET #Text = '$1234.567'
SELECT CONVERT(float, #Text) AS ColumnValue
Not sure without seeing your query, but I think this should work:
SELECT CONVERT(Float(2), LTRIM(RTRIM(<nVarchar Column>))) AS Amount FROM ......