SQL - Why can't I compare varchar to varchar(15)? - sql

Can anyone explain to me why the following returns 'Not equal'?
DECLARE #X15 varchar(15) = 'ABC'
DECLARE #X varchar = #X15
SELECT CASE WHEN #X = #X15 THEN 'Equal' ELSE 'Not equal' END
I must be missing something obvious.

If you print out #X you'll see the problem:
DECLARE #X15 varchar(15) = 'ABC'
DECLARE #X varchar = #X15
SELECT LEN(#X), #X, CASE WHEN #X = #X15 THEN 'Equal' ELSE 'Not equal' END
If you don't specify a length for varchar it defaults to 1 character so your #X variable can only hold the first character of #X15.

The default value of n is 1 for the char and varchar data types when they are used in variable declaration.
Ex:-
DECLARE #myVariable AS varchar = 'abc';
DECLARE #myNextVariable AS char = 'abc';
DECLARE #myVariableWithLength AS varchar(15) = 'abc';
--The following returns 1
SELECT DATALENGTH(#myVariable), DATALENGTH(#myNextVariable),DATALENGTH(#myVariableWithLength);
GO

Related

Convert from bigint to varchar without leading 0?

I need to use a bigint value as part of a string construction, but I can't figure out how to get from bigint to to varchar without having a leading 0
declare #a bigint = 167830720612159876
select convert(varchar(32), convert(varbinary, #a), 2)
This gives me 02544126B47C5184, but I want `2544126B47C5184'
Basically I want the conversion from bigint to varbinary to omit the leading 0 so that it is left out of the string representation.
Try this:
create function dbo.BigintToHex(#X bigint)
returns varchar(20) as
begin
declare #H varchar(20) = ''
declare #D varchar(16) = '0123456789ABCDEF'
if #X = 0
set #H = '0'
if #X < 0
set #H = '-' + dbo.BigintToHex(-#X)
else
while #X > 0
begin
set #H = SUBSTRING(#D,#X % 16+1,1) + #H
set #X = #X / 16
end
return #H
end
go
select dbo.BigintToHex(-167830720612159876)

Parsing/Conversion issue in sql server 2012?

I am getting error while executing below query in sql server 2012:
DECLARE #Id NVARCHAR(max) = 2147483648
DECLARE #Result BIGINT = 0
IF (
#Id = 0
OR #Id = ''
)
BEGIN
SET #Result = NULL
END
ELSE
BEGIN
SET #Result = convert(bigint,#id)
END
Output:
Msg 248, Level 16, State 1, Line 3 The conversion of the nvarchar
value '2147483648' overflowed an int column.
Can someone suggest me why it is happening ?
Thanks in advance
Converting 0 to bigint will work because by default 0 will be treated as INT
DECLARE #Id NVARCHAR(max) = 2147483648
DECLARE #Result BIGINT = 0
IF ( #Id = cast(0 as bigint) -- or = '0'
OR #Id = '' )
BEGIN
SET #Result = NULL
END
ELSE
BEGIN
SET #Result = CONVERT(BIGINT, #id)
END
You have to use '' when setting #id = '0' in following:
DECLARE #Id NVARCHAR(max) = 2147483648
DECLARE #Result BIGINT = 0
IF (
#Id = '0'
OR #Id = ''
)
BEGIN
SET #Result = NULL
END
ELSE
BEGIN
SET #Result = convert(bigint,#id)
END
When you compare varchar with int. varchar is converted to int before comparison.
When an operator combines two expressions of different data types, the
rules for data type precedence specify that the data type with the
lower precedence is converted to the data type with the higher
precedence. If the conversion is not a supported implicit conversion,
an error is returned.
When #ID (= '2147483648') converted to int it exceeds the max limit of int. hence you got the error;
int
-2^31 (-2,147,483,648) to 2^31-1 (2,147,483,647) 4 Bytes
Solution:
Convert to both to varchar
IF (#Id = '0' OR #Id = '' )
Convert #Id to bigint.
IF ( convert(bigint, #Id) = 0 OR #Id = '' )

Difference in SQL queries with or without parameters

Can anyone tell me what the difference (besides the obvious) is between these two queries:
1)
declare #coy_oid varchar
declare #field_name varchar
set #coy_oid = '10'
set #field_name = 'ResultReason'
SELECT OID, POSITION, DESCRIPTION, FIELD_NAME
FROM T_FIELD_TEXT_CHOICES
WHERE COY_OID = #coy_oid AND FIELD_NAME = #field_name
2)
declare #coy_oid varchar
declare #field_name varchar
set #coy_oid = '10'
set #field_name = 'ResultReason'
SELECT OID, POSITION, DESCRIPTION, FIELD_NAME
FROM T_FIELD_TEXT_CHOICES
WHERE COY_OID = #coy_oid AND FIELD_NAME = 'ResultReason'
The first one returns nothing and the second returns the expected results. I am sure it has to do with the FIELD_NAME being a variable, but I don't know why.
Guess I should add this is SQL Server 2008 R2, but maybe it doesn't matter.
You're variables are declared as varchar. That's a single character, so in the first query you're comparing with 'R'. You probably meant to use something like varchar(100)...
varchar is the equivalent of varchar(1)
To see this consider
DECLARE #v1 VARCHAR
SET #v1 = '12345'
DECLARE #v2 VARCHAR (5)
SET #v2 = '12345'
SELECT #v1 AS v1, #v2 AS v2
which returns
'1' for v1
'12345' for v2
Solution:
declare #coy_oid varchar(100)
declare #field_name varchar(100)

SQL syntax for a function

I have the following code, syntax somewhere is not correct,
CREATE FUNCTION [dbo].[Greeting](#Name [varchar])
RETURNS [int] AS
BEGIN
Declare #Gender varchar
Declare #Greeting varchar
select #Gender = Gender from [NameData].[dbo].[Names] where Name = #Name
select #Greeting = (case when #Gender = 'Female' then 'Ms.' else 'Mr.');
RETURN #Greeting
END
GO
The error I'm getting is:
Incorrect syntax near ')'.
Anyone can help?
Thanks
You are missing the end to your case statement. Probably more importantly, you are not using length specifications for varchar. In SQL Server always use length specifications. The default value depends on the context -- and in this context, the value is 1, which will produce incorrect results.
You should also end your statements with semicolons. And, fix the return value, because you do not seem to be returning an integer. So:
CREATE FUNCTION [dbo].[Greeting](
#Name varchar(255)
)
RETURNS varchar(255) AS
BEGIN
Declare #Gender varchar(255);
Declare #Greeting varchar(255);
select #Gender = Gender from [NameData].[dbo].[Names] where Name = #Name ;
select #Greeting = (case when #Gender = 'Female' then 'Ms.' else 'Mr.' end);
RETURN #Greeting;
END;
You do realize that all unrecognized names will be given a "greeting" of "Mr.". I assume that is intentional. Also, the function can be simplified, but I'm following your original logic as much as possible.
You have
RETURNS [int]
but are trying to return #Greeting which is declared a varchar
And also missing end for case statement.
You missed END in your case statement:
CREATE FUNCTION [dbo].[Greeting] (#Name [varchar(255)])
RETURNS [int] --also this will need to be changed to varchar()
AS
BEGIN
DECLARE #Gender VARCHAR(255) --added varchar length
DECLARE #Greeting VARCHAR(255) --added varchar length
SELECT #Gender = Gender
FROM [NameData].[dbo].[Names]
WHERE NAME = #Name
SELECT #Greeting = (
CASE
WHEN #Gender = 'Female'
THEN 'Ms.'
ELSE 'Mr.'
END --added this
);
RETURN #Greeting
END
GO

SQL 2005 - Variant Parameter Question

I am working on a function that will be used by no less than 10 SProc's, and will probably grow once it is ironed out.
Problem i am running into is that i do not want to develop a function for each Data Type, which is why the SQL_VARIANT data type is looking pretty convenient for the action. I know is can do the ISNULL check on the data type but i also want to check to see if the Value being passed is a valid Number but the ISNUMERIC function does not work with SQL_VARIANT and I'm not too sure about the SQL_VARIANT_PROPERTY function.
Code so far:
CREATE FUNCTION dbo.mpt_Format_Number
(
#value SQL_VARIANT
, #money BIT
)
RETURNS VARCHAR
AS
BEGIN
--Check for NULL value
IF ISNULL(#value) BEGIN
-- Value IS NULL, return NULL
RETURN NULL
END ELSE BEGIN
-- Value is NOT NULL
DECLARE #TMP VARCHAR
END
END
CREATE FUNCTION dbo.mpt_Format_Number
(
#value SQL_VARIANT
, #money BIT
)
RETURNS VARCHAR
AS
BEGIN
--Check for NULL value
IF #value is null
-- Value IS NULL, return NULL
RETURN NULL
ELSE
BEGIN
-- Value is NOT NULL
if isnumeric(convert(varchar(max), #value)) = 1 RETURN 'Y' -- is valid number
--DECLARE #TMP VARCHAR
END
return 'N' --is not valid number
END
You can always test the property type with this syntax. Should be easy to incooperate in your function.
declare #t SQL_VARIANT
set #t = '3'
select SQL_VARIANT_PROPERTY(#t, 'basetype')
Result:
varchar
As a final implementation here is the full function as it was used.
ALTER FUNCTION [dbo].[_mpt_Format_Number]
(
#value SQL_VARIANT
, #money BIT = 0
)
RETURNS VARCHAR(max)
AS
BEGIN
DECLARE #ret VARCHAR(MAX)
--Check for NULL value
IF #value IS NULL BEGIN
-- Value IS NULL, return NULL
SET #ret = 'NULL'
END ELSE BEGIN
-- Value is NOT NULL
--Check for Numeric Value
IF ISNUMERIC(CONVERT(VARCHAR, #value)) = 0 BEGIN
--Value is NOT a Number, return NULL
SET #ret = 'NULL'
END ELSE BEGIN
--Value IS a Number
declare #isNeg BIT
declare #tmp varchar(max)
set #tmp = convert(varchar(max), round(cast(#value as money), 0), 1)
--Check if value is negative
if #value < 0 begin
--Value is Negative
set #isNeg = 1
--Remove the negative sign
set #tmp = replace(#tmp, '-', '')
end
--Remove the decimal plus any digits to the right of the decimal
set #tmp = left(#tmp ,len(#tmp) - 3)
--Is money set to True
if #money = 1 begin
--Pre-pend the dollar sign to value
set #tmp = '$' + #tmp
end
--Is isNeg set to True
if #isNeg = 1 begin
--Encapsulate the value with parenthesis
set #tmp = '(' + #tmp + ')'
end
SET #ret = #tmp
END
END
RETURN #ret
END