Dynamic Where clause in sql with IN statement in it - sql

How do I write a query in SQL where when the string variable is not '' we include the WHERE clause and check where the ID exists in the list or not?
The following does not seem to work.
DECLARE #var varchar(20)
DECLARE #clause varchar(20)
DECLARE #sql varchar(20)
SET #var= '1,2,3'
IF #var <> ''
SET #clause=' WHERE ID IN ('+ #var + ')'
SET #sql='SELECT [ID]
,[SOURCE]
,[LAST_KEY]
FROM [oms].[dbo].[MIGRATION]'
EXEC (#sql + #clause)
Error Message:
Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'WHERE'.

Increase your #sql variable's length to MAX like
DECLARE #sql varchar(MAX)
You have defined 20 length which is not enough to store whole query in that variable. Also remove #clause variable and change your code like below. You can also print whole query by print #sql and check what is wrong in that.
DECLARE #var varchar(500)
DECLARE #sql varchar(MAX)
SET #var= '1,2,3'
SET #sql = 'SELECT [ID],
[SOURCE],
[LAST_KEY]
FROM [oms].[dbo].[MIGRATION]'
IF #var IS NOT NULL AND #var <> ''
BEGIN
SET #sql = #sql + ' WHERE ID IN ('+ #var + ')'
END
EXEC (#sql)

This issue is because of length for variable #sql. Please change it from #sql varchar(20) to #sql varchar(max) will resolve your issue.
Below is the code for the same
DECLARE #var varchar(20)
DECLARE #clause varchar(20)
DECLARE #sql varchar(max)
SET #var= '1,2,3'
IF #var <> ''
SET #clause=' WHERE ID IN ('+ #var + ')'
SET #sql='SELECT [ID]
,[SOURCE]
,[LAST_KEY]
FROM [oms].[dbo].[MIGRATION]'
EXEC (#sql + #clause)

Related

sql syntax error (incorrect syntax near =)

Hello I am having a problem here.
I wanted to read subjectname from a dynamic table name and the save it to a variable.
but i am getting an error
DECLARE #retval varchar(200)
DECLARE #sSQL nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
DECLARE #academicYear varchar(200) = '20212022';
Declare #subjectId varchar(200) = '202041962';
DECLARE #tablename nvarchar(50) = 'abc' + CAST(#academicyear As varchar)
DECLARE #CONDITION NVARCHAR(128)
SET #CONDITION = 'WHERE [subjectid] = 202041962'
SELECT #sSQL = N'SELECT #retvalOUT = [subjectname] FROM ' + #tablename + #CONDITION;
SET #ParmDefinition = N'#retvalOUT varchar OUTPUT';
EXEC sp_executesql #sSQL, #ParmDefinition, #retvalOUT=#retval OUTPUT;
SELECT #retval;
If you actually looked at the value of #sSQL eg by printing it, you'll note it contains FROM abc20212022WHERE, therefore,
you are not delimiting your table names - use quotename()
you need a space between your table name and the where
you should always specify a length for a varchar value (you don't need to cast a variable when concatenating two strings but you should be consistent with your use of [n]varchar)
using concat to concatenate strings is easier and safer

SQL add a variable to a query

How do I create variables that are specified once and then used in queries later in a script? These variables may be used multiple times in a query, and in multiple queries in a script. I use #x as such a variable in the examples below.
What I want to do is something like:
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name]
, ' + #x + ' as [TestCase]
From mytable'
Exec (#Query)
-- returns "Invalid column name 'test'"
Which returns the error mentioned above. I would like it to achieve the equivalent of:
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name]
, ''test'' as [TestCase]
From mytable'
Exec (#Query)
-- Returns e.g.
-- Name TestCase
-- Alice Test
-- Bob Test
I also note that the following doesn't work and returns the same error as the first:
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name]
, ' + 'test' + ' as [TestCase]
From mytable'
Exec (#Query)
-- returns "Invalid column name 'test'"
Based on the error and since I'm not trying to use the #x as a column name, but just as a variable, I assume I'm using an invalid implementation of a variable.
Since you're not trying to use a variable as a column name, you do not need to use dynamic SQL at all. (Which is a Good Thing(TM) since dynamic SQL should only be used with a great deal of caution due to it being a great attack surface.)
A simple:
declare #x nvarchar(40)
set #x = 'test'
select [Name], #x as TestCase
from mytable
will do.
That being said, if you have a use case for dynamic SQL (again the particular query in question here does not but perhaps an ad-hoc query is being passed in to the procedure), the thing to do would be to pass your variable as a parameter to the query via sp_executesql. This is akin to creating a stored procedure with parameters:
declare #x nvarchar(40)
declare #query nvarchar(1000)
set #x = 'test'
set #query = 'select [Name], #x as TestCase from mytable'
exec sp_executesql #query, N'#x nvarchar(1000)', #x
You were missing quotes. Thats it. Try below code.
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name]
, ''' + #x + ''' as [TestCase]
From mytable'
Exec (#Query)
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name],'++''''+#x+''''+ ' as [TestCase]
From mytable'
print #query
Output:
Select [Name],'test' as [TestCase]
From mytable

Can I use variable in condition statement as value with where condition that test that value

I have the following stored procedure:
ALTER proc [dbo].[insertperoll] #name nvarchar(50) , #snum int , #gnum int
as
DECLARE #value nvarchar(10)
SET #value = 's'+CONVERT(nvarchar(50),#snum)
DECLARE #sqlText nvarchar(1000);
DECLARE #sqlText2 nvarchar(1000);
DECLARE #sqlText3 nvarchar(1000);
declare #g nvarchar(50) = '''g1'''
SET #sqlText = N'SELECT ' + #value + N' FROM dbo.GrideBtable'
SET #sqlText2 = ' where Gnumber = '+#g --here is the problem it error invalid column name -- the #g is value from the table condition
set #sqlText3 = #sqlText+#sqlText2
Exec (#sqlText3) -- here how can i save the result of the exec into varibale
declare #sal nvarchar(50) = #sqlText3
insert employ (name,Snumber,Gnumber,Salary) values(#name,#snum,#gnum,#sal)
QUESTION: How to put in condition variable gets value from the table when i exec it it think that the #g is column but its not its a value from the table to test it so i display one value after the exec the other QUESTION is how to save the result from the exec in variable and then use that value
I'm using SQL Server 2008 (9.0 RTM)
This will be a stored procedure
Thanks in advance
Not sure why you would go through all the loops to insert into the table where you can have a simple insert query like ..
ALTER PROC dbo.[insertperoll] #name nvarchar(50) , #snum int , #gnum int
AS
insert employ (name, Snumber, Gnumber, Salary)
select #name
, #sum
, #gnum
, case when #snum = 1 then s1
when #snum = 2 then s2
when #snum = 3 then s3
when #snum = 4 then s4
end as Salary
from dbo.GrideBtable
where Gnumber = #gnum
If your intent is to have the proc retrieve a salary value from a column determined from the parameter snum and then make an insert into employ using the values passed as parameters and the salary retrieved I think you could refactor your procedure to this:
CREATE proc [dbo].[insertperoll] #name nvarchar(50) , #snum int , #gnum int AS
DECLARE #g NVARCHAR(50) = 'g1'
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'INSERT employ (name,Snumber,Gnumber,Salary) '
SET #sql += N'SELECT ' + QUOTENAME(#name, '''')
SET #sql += N', ' + CAST(#snum AS NVARCHAR(50))
SET #sql += N', ' + CAST(#gnum AS NVARCHAR(50))
SET #sql += N', s' + CAST(#snum AS NVARCHAR(50))
SET #sql += N' FROM dbo.GrideBtable'
SET #sql += N' WHERE Gnumber = ' + QUOTENAME(#g, '''')
EXEC (#sql)
Of course you could add the #g variable to the procedure parameters instead of having it hard coded in the procedure and call it as:
EXEC insertperoll #name='john', #snum=10, #gnum=100, #g='g1'
Sample SQL Fiddle (with some assumptions made about table structure)
You could do this using sp_executesql instead of exec() since this will allow you to use parameters, you can use an output parameter to get the value from the query:
DECLARE #SQL NVARCHAR(MAX) = N'SELECT #val = ' + CONVERT(NVARCHAR(10),#snum) +
N' FROM dbo.GrideBtable WHERE Gnumber = #G1';
DECLARE #val INT; -- NOT SURE OF DATATYPE REQUIRED
EXECUTE sp_executesql #SQL, N'#G1 VARCHAR(20), #val INT OUT', 'G1', #val OUT;

How to use Pass comma separated string in dynamic query in SQL

I have a function which will return integer values from comma delimited string , It takes two parameters (#string nvarchar(4000), #delimiter char(1)). So the problem is if I am using this function inside a dynamic query I am getting error , here is query
declare #ProductIDs varchar(11)
declare #SQL varchar(max)
set #ProductIDs='1,2,3,4'
declare #query varchar(max)
--set #query= #ProductIDs +','+#Delimiter
SELECT #SQL = 'SELECT val FROM dbo.[fnDelimitedStringToTable]('+ #ProductIDs +' , '','')'
Exec(#SQL)
I am getting error Procedure or function dbo.fnDelimitedStringToTable has too many arguments specified.
When you build a dynamic SQL like that, you need to wrap your parameter in double quote ''
declare #ProductIDs varchar(11)
declare #SQL varchar(max)
set #ProductIDs='1,2,3,4'
declare #query varchar(max)
--set #query= #ProductIDs +','+#Delimiter
SELECT #SQL = 'SELECT val FROM dbo.[fnDelimitedStringToTable]('''+ #ProductIDs +''' , '','')'
Exec(#SQL)
This way the SQL statement will be:
SELECT val FROM dbo.[fnDelimitedStringToTable]('1,2,3,4' , '','')
and not:
SELECT val FROM dbo.[fnDelimitedStringToTable](1,2,3,4 , '','')
Use sp_executesql instead. In this case you can pass arguments as parameters.
DECLARE #SQL nvarchar(max)
DECLARE #ParmDef nvarchar(1000)
DECLARE #ArgProductIDs nvarchar(100)
DECLARE #Arg2 nvarchar(100)
DECLARE #Arg3 nvarchar(100)
SET #SQL = N'SELECT val
FROM dbo.[fnDelimitedStringToTable](#ProductIDs, #Param2, #Param3)';
SET #ParmDef = N'#ProductIDs nvarchar(100),
#Param2 nvarchar(100),
#Param3 nvarchar(100)';
SET #Arg1 = N'1,2,3,4';
SET #Arg2 = N'';
SET #Arg3 = N'';
EXEC sp_executesql #SQL, #ParmDef,
#ProductIDs = #ArgProductIDs, #Param2 = #Arg2, , #Param3 = #Arg3

How to store results of dynamic SQL into a variable

is there a way to store the results of an exec statement in a varchar?
DECLARE #TableName varchar(100)
DECLARE #ExecStatement varchar(max)
DECLARE #PromotionXML varchar(max)
SET #TableName = 'Feeds'
Set #ExecStatement = (
'
SET #PromotionXML = (
SELECT
*
FROM
' + #TableName + ' for xml auto, elements
)'
)
exec #ExecStatement
select #PromotionXML
You need to use sp_executesql, not EXEC, since you need to treat the inner variable as an output parameter (which you can't do with EXEC). Also all of these parameters should be NVARCHAR, not VARCHAR (though I'm curious why you aren't returning the xml as XML).
DECLARE
#TableName NVARCHAR(512),
#sql NVARCHAR(MAX),
#xml NVARCHAR(MAX);
SET #TableName = N'dbo.Feeds';
SET #sql = N'SELECT #xml = CONVERT(NVARCHAR(MAX), (
SELECT * FROM ' + #TableName + ' FOR XML AUTO, ELEMENTS));';
EXEC sp_executesql #sql, N'#xml NVARCHAR(MAX) OUTPUT', #xml OUTPUT;
SELECT #xml;