Difference in SQL queries with or without parameters - sql

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)

Related

Is it possible you instatiate a variable in SQL server using a select statement with another variable

I am attempting to DECLARE a variable then SET it's value using a secondary variable which has already had it's value set.
I have tried:
DECLARE #Type VARCHAR = 'Some unique text';
DECLARE #TypeId UNIQUEIDENTIFIER;
SET #TypeId =
(
SELECT Id
FROM Types
WHERE Name = #Type
)
select #TypeId
To no avail. The result of the final SELECT statement is null. The following works:
DECLARE #TypeId UNIQUEIDENTIFIER;
SET #TypeId =
(
SELECT Id
FROM Types
WHERE Name = 'Some unique text'
)
select #TypeId
but I have several tables linked via dependencies and to delete an entry I need to traverse the tables in the correct order pulling the correct Ids. It is likely I will need to do this frequently so I want to reduce the leg work and just enter the text once and the script do the rest.
Is the syntax wrong or is this not possible?
DECLARE #Type VARCHAR = 'Some unique text';
It seems like you try to configure the variable value to be 'Some unique text' but since the type of the variable is VARCHAR(1) then when you set the value the server implicitly CONVERT it to VARCHAR(1) which lead to trunctaing the string and using only the first character
DECLARE #Type VARCHAR = 'Some unique text';
SELECT #Type
GO -- result is "S" and not "Some unique text"
To clarify, using DECLARE #Type VARCHAR without explicitly set the length is translated into 'DECLARE #Type VARCHAR(1)'
As a result of this issue, your comparing of the value probably result with no rows since you compare "S" and not "Some unique text". Your sub query is the same as SELECT Id FROM Types WHERE Name = 'S'
Here is a simple illustration of the issue
------------ DDL+DML: Creating sample table with some data
DROP TABLE IF EXISTS t1, t2
GO
CREATE TABLE t1 (
ID int, [Name] NVARCHAR(100)
)
GO
INSERT t1 (ID, [Name]) Values
(1, 'Mobile '),
(2, 'TV '),
(3, 'Display')
GO
----------- Using VARCHAR without length returns nothing
DECLARE #Type VARCHAR = 'Mobile';
SELECT #Type
DECLARE #TypeId INT;
SET #TypeId =
(
SELECT Id FROM t1 WHERE Name = #Type
)
select #TypeId
----------- Using VARCHAR(100) works great
DECLARE #Type VARCHAR(100) = 'Mobile';
SELECT #Type
DECLARE #TypeId INT;
SET #TypeId =
(
SELECT Id FROM t1 WHERE Name = #Type
)
select #TypeId

Write an conditionally sentence from an Varchar in SQL

I am trying to execute this conditional statement from a string, but I always get errors.
Is there a way to CAST or CONVERT this varchar to a logical string?
I am using SQL Server 2000
Declare #myQuery varchar(100)
SET #myQuery= '3043=3043 OR ( 3043=97 AND 0=8065 ) OR 3043=1853 OR 3043=5749'
if(#myQuery)
select 'ok'
I want to execute this:
These conditions need to go in a where clause so they are properly interpreted. Something like:
declare #myquery varchar(100)
set #myquery = '3043 = 3043 or (3043 = 97 and 0=8065) or 3043 = 1853 or 3043 = 5749'
exec('select ''ok'' where ' + #myquery)
If you want to use it in IF condition, you need to set the flag using sp_executesql as below:
Declare #myQuery nvarchar(100)
Declare #flag tinyint
SET #myQuery= 'select #flag = 1 where 3043=3043 OR ( 3043=97 AND 0=8065 ) OR 3043=1853 OR 3043=5749'
exec sp_executesql #myQuery, N'#flag tinyint output', #flag = #flag output
if(#flag = 1)
select 'ok'

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

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

Substring in SQL with from a pattern

I am struggling to substring and get the values in SQL.
I am having a JSON String like the following:
DECLARE #string varchar(max)= '[{"CustomFieldId":18,"FieldName":"ABCD","FieldType":"freeText","FieldValue":null,"Details":null,"Value":null,"RelationTable":null,"Isisible":true,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"LoggedInUser":"TESTUSER"},{"CustomFieldId":19,"FieldName":"Workdomain","FieldType":"freeText","FieldValue":null,"Details":null,"Value":null,"RelationTable":null,"IsVisible":true,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"LoggedInUser":"149645"},{"CustomFieldId":20,"FieldName":"TEST1234","FieldType":"freeText","FieldValue":"Sometest","Details":null,"Value":null,"RelationTable":null,"IsVisible":false,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"_listlovFields":[],"org4Values":[],"LoggedInUser":"TESTUSER"}]'
or it can also be like this:
DECLARE #string varchar(max) = '[{"CustomFieldId":20,"FieldName":"TEST1234","FieldType":"freeText","FieldValue":"Sometest","Details":null,"Value":null,"RelationTable":null,"IsVisible":false,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"LoggedInUser":"TESTUSER"}]'
Now from any one of them I need to get the 'FieldValue' of a particular 'CustomFieldId' with a particular 'FieldName' and where the FieldValue starts with a particular string.
Like, I am going to get these:
declare #propName varchar(max) = 'Test1234',
#customFieldId varchar(max) = 20,
#value varchar(max) = 'Some'
So, in this particular case, I need to get the FieldValue of customfield with CustomFieldId:"20", FieldName":"TEST1234" and where FieldValue starts with 'Some'.
The output simply needs be the string 'Sometest' as this is the FieldValue of CustomFieldId:"20"
Any help in this would be highly appreciated.
this is quite easy to solve when you install regex functions on your sql server. I've included the link where you can find them.
https://www.simple-talk.com/sql/t-sql-programming/clr-assembly-regex-functions-for-sql-server-by-example/
declare #CustomFieldId nvarchar(50)= '20'
declare #FieldName nvarchar(50) = 'TEST1234'
declare #FieldValueStartsWith nvarchar(50) = 'Some'
declare #input nvarchar(500)
select #input = '[{"CustomFieldId":20,"FieldName":"TEST1234","FieldType":"freeText","FieldValue":"Sometest","Details":null,"Value":null,"RelationTable":null,"IsVisible":false,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"LoggedInUser":"TESTUSER"}]'
declare #result nvarchar(500)
declare #expression nvarchar(200) = '.*"CustomFieldId":' + #CustomFieldId + ',"FieldName":"' + #FieldName + '".*"FieldValue":("' + #FieldValueStartsWith + '\w+").*'
select #result = dbo.RegExReplaceX(#expression,#input,'$1',dbo.RegExOptionEnumeration(0,0,0,0,1,0,0,0,0)) -- OPTION = FOR CASE SENSITIVE
if #result = #input SELECT NULL ELSE SELECT #RESULT

SQL SP: Dynamic Query

I am trying get a col and value as a function parameter and planning to use them in a query.
Unfortunately, my value for #Col is being treated like a string and not a column identifier.
ie, if I specify name as a value for the #Col parameter, it will be treated like 'name' instead of name and hence, the call to the function always returns NULL as a result
Have you came across similar situations? Could you please recommand me a better way to deal with this situation?
Here is my Function for your reference:
CREATE FUNCTION [dbo].[FN_FindIdBy]
(
#Col NVARCHAR(255),
#Value NVARCHAR(255)
)
RETURNS INT
AS
BEGIN
DECLARE #Id INT = NULL
SET #Id = (SELECT ID FROM dbo.MYWORK WHERE (CONVERT(NVARCHAR(255), #Col) = #Value))
IF #Id IS NOT NULL RETURN #Id
RETURN NULL
END
Thanks a lot for looking into this.
The following works, but you have to use it as a procedure and create dynamic sql.
create table MYWORK (ID int identity, Name nvarchar(255))
insert into MYWORK(Name)
select 'a'
union select 'b'
union select 'c'
union select 'd'
union select 'e'
union select 'f'
CREATE procedure [dbo].[EPG_FN_FindIdBy]
#Col NVARCHAR(255),
#Value NVARCHAR(255)
AS
BEGIN
DECLARE #Id nvarchar(255)
, #ParmDefinition nvarchar(255)
, #sql nvarchar(max)
set #sql = N'SELECT #IdOUT = ID FROM dbo.MYWORK WHERE '+ #Col +' = ''' + #Value + ''''
set #ParmDefinition = N'#IdOUT nvarchar(255) OUTPUT'
PRINT #sql
EXECUTE sp_executesql #sql,#ParmDefinition, #IdOUT = #Id OUTPUT
SELECT #Id as ID
END
Run this and it'll return the matching row
Exec dbo.EPG_FN_FindIdBy #Col = 'Name', #Value = 'a'
And for a NULL
Exec dbo.EPG_FN_FindIdBy #Col = 'Name', #Value = 'g'
Yeah, there's almost always a better way to query than using dynamic SQL.
Check out this usage of the CASE operator.
SELECT id
FROM dbo.MYWORK
WHERE CASE #Col
WHEN 'a' THEN [a]
WHEN 'b' THEN [b]
WHEN 'c' THEN [c]
END = #Value
Where the table has columns [a], [b] and [c].