sql server stored procedure IN parameter - sql-server-2008

In SQL Server, I am passing String as parameter :
#Param1 = Test,Test1,Test2
I am formatting it to:
#Param1 = 'Test','Test1','Test2'
When I am trying to use this in SELECT statement with IN parameter, it is not returning any data
SELECT * FROM TABLE1 where COLUMN1 IN (#Param1)
What is the correct syntax?

As pointed out already in the comments by marc_s, IN requires a list of values not simply one variable.
But you could provide those values in a SELECT from a simple table variable like this:
DECLARE #Param1 TABLE (Value NVARCHAR(255));
INSERT INTO #Param1 (Value)
SELECT 'Test1'
UNION
SELECT 'Test2'
UNION
SELECT 'Test3'
SELECT
*
FROM TABLE1
WHERE
COLUMN1 IN
(SELECT Value FROM #Param1)

I wish there were array vars like that! :-)
But you can convert it to a table using a function, and then use the table with your IN clause as you're attempting.
Here is how that would look:
DECLARE #Param1 nvarchar(max)
SET #Param1 = 'Test,Test1,Test2'
SELECT *
FROM myTable
WHERE myField In (Select ParsedString From dbo.ParseStringList(#Param1))
And here is (at least one way to write) the function:
CREATE Function [dbo].[ParseStringList] (#StringArray nvarchar(max) )
Returns #tbl_string Table (ParsedString nvarchar(max)) As
BEGIN
DECLARE #end Int,
#start Int
SET #stringArray = #StringArray + ','
SET #start=1
SET #end=1
WHILE #end<Len(#StringArray)
BEGIN
SET #end = CharIndex(',', #StringArray, #end)
INSERT INTO #tbl_string
SELECT
Substring(#StringArray, #start, #end-#start)
SET #start=#end+1
SET #end = #end+1
END
RETURN
END

Related

Loop through a split string variable to insert rows in a stored procedure in SQL Server 2008

I am working on SQL Server 2008 to create a stored procedure that:
takes a string variable like this: '1,2,3'
splits the string using a table-valued function to get each value separately
and then inserts each value into a new row in a table
What I am trying to do is something like this:
WHILE (select vlaue FROM dbo.SplitString('1,2,3',',')) has rows
insert into TableName (col1,col2) values (col1Data, value)
I am having a hard time trying to find the right syntax for this.
I use this Table-valued function:
CREATE FUNCTION [dbo].[Split] (#sep char(1), #s varchar(512))
RETURNS table
AS
RETURN (
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(#sep, #s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(#sep, #s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT pn,
SUBSTRING(#s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
FROM Pieces
)
GO
Which takes a string with a separator and returns a table with two columns the first returns a 1-based position and the second the element at that position in the string:
Usage:
SELECT * FROM dbo.Split(',', '1,2,3')
Returns:
pn s
1 1
2 2
3 3
To Insert results into a table:
INSERT INTO TableName (Col1)
SELECT S FROM dbo.Split(',', '1,2,3)
For your specific example change your syntax to be:
insert into TableName (col1,col2)
select col1Data, value FROM dbo.SplitString('1,2,3',',')
The typical INSERT INTO ... SELECT ... should do:
INSERT INTO TableName (col1,col2)
SELECT #col1Data,value FROM dbo.SplitString('1,2,3',','))
If someone else is looking for this, I was about to make a split function as several answers mentioned but noticed there's a built-in function that does this already.
string_split was added in MSSQL 2016.
INSERT INTO Project.FormDropdownAnswers (FkTableId, CreatedBy, CreatedDate)
SELECT 123, TRY_CAST(value AS INT), #username, getdate()
FROM string_split('44,45,46,47,55',',')
https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql
CREATE TABLE tablename
(
id SMALLINT ,
value INT
)
INSERT INTO tablename ( id, value )
SELECT * FROM dbo.Split('1,2,3',',')
try this....
If need to use as variables there is 2 nice options:
Procedure MF_SPLIT
CREATE PROC [MF_SPLIT] (#ELS NVARCHAR(MAX)=NULL OUTPUT, #RET NVARCHAR(MAX)=NULL OUTPUT, #PROC NVARCHAR(MAX)=NULL) AS BEGIN
IF #ELS IS NULL BEGIN
PRINT ' #ELS
List of elements in string (OUTPUT)
#RET
Next return (OUTPUT)
#PROC
NULL = '','', content to do split
Example:
DECLARE #NAMES VARCHAR(100) = ''ERICK,DE,VATHAIRE''
DECLARE #N VARCHAR(100)
WHILE #NAMES IS NOT NULL BEGIN
EXEC MF_SPLIT #NAMES OUTPUT, #N OUTPUT
SELECT List = #NAMES, ActiveWord = #N
END'
RETURN
END
SET #PROC = ISNULL(#PROC, ',')
IF CHARINDEX(#PROC, #ELS) = 0 BEGIN
SELECT #RET = #ELS, #ELS = NULL
RETURN
END
SELECT
#RET = LEFT(#ELS, CHARINDEX(#PROC, #ELS) - 1)
, #ELS = STUFF(#ELS, 1, LEN(#RET) + 1, '')
END
Usage:
DECLARE #NAMES VARCHAR(100) = '1,2,3'
DECLARE #N VARCHAR(100)
WHILE #NAMES IS NOT NULL BEGIN
EXEC MF_SPLIT #NAMES OUTPUT, #N OUTPUT
SELECT List = #NAMES, ActiveWord = #N
END
Procedure MF_SPLIT_DO (Depends of MF_SPLIT), less sintax to use BUT the code will be in a string and use default variable "#X"
CREATE PROC MF_SPLIT_DO (#ARR NVARCHAR(MAX), #DO NVARCHAR(MAX)) AS BEGIN
--Less sintax
DECLARE #X NVARCHAR(MAX)
WHILE #ARR IS NOT NULL BEGIN
EXEC MF_SPLIT #ARR OUT, #X OUT
EXEC SP_EXECUTESQL #DO, N'#X NVARCHAR(MAX)', #X
END
END
Usage:
EXEC MF_SPLIT_DO '1,2,3', 'SELECT #X'

GROUP CONCAT REPLACE sep strings

I am using the below statement to pull a unique value off a table from a field that is separated with "|". It looks like this: "40|180|408|360|40|1s66|80|59" My problem is that I can't seem to get this statement to allow me to pull a primary key field, id, and assign it to each unique item from the field string so I can actually use it later. Ideally, ID # 27 should be assigned to each of the values on this temp table from "40|180|408|360|40|1s66|80|59". Can anyone help with the below statement to allow me to insert and assign field id to this from table BlogImageBundle?
CREATE TEMPORARY TABLE test (postId INT(11), val CHAR(255));
SET #S1 = CONCAT("INSERT INTO test (val) VALUES ('",REPLACE((SELECT GROUP_CONCAT( DISTINCT `images`)
AS data FROM `BlogImageBundle`), "|", "'),('"),"');");
PREPARE stmt1 FROM #s1;
EXECUTE stmt1;
SELECT DISTINCT(val) FROM test;
This works but ONLY for one record. You will need to add another while loop that keeps track of the rowcount to deal with multiple records : http://sqlfiddle.com/#!6/d62f7/1
CREATE TABLE #Test
(
ID INT,
Initial VARCHAR(MAX)
)
CREATE TABLE #Test2
(
ID INT,
Final VARCHAR(MAX)
)
INSERT INTO #Test VALUES(27,'40|180|408|360|40|1s66|80|59')
DECLARE #String VARCHAR(MAX)
SET #string = (SELECT Initial FROM #Test)
DECLARE #StringInput VARCHAR(MAX)
SET #stringInput = (SELECT Initial FROM #Test)
WHILE LEN(#StringInput) > 0
BEGIN
SET #String = LEFT(#StringInput,ISNULL(NULLIF(CHARINDEX('|', #StringInput) - 1, -1),LEN(#StringInput)))
SET #StringInput = SUBSTRING(#StringInput,ISNULL(NULLIF(CHARINDEX('|', #StringInput), 0),LEN(#StringInput)) + 1, LEN(#StringInput))
INSERT INTO #Test2 (ID, Final)
SELECT ID,#string FROM #Test
END

SQL Server - comparing two variables

I wish to compare a variable #a containing an entire column of a table with another variable containing a single value. Is it possible?
create procedure pc1(#var int)
as begin
declare #a int
select #a=id from tb1
while(if exists(#var=#a))
begin
select * from tb1 where id=#var
end
return
end
There is no direct way but you can do this thing in following way.
declare #a int
Set #a = 1
if exists(
select #a as ID
Intersect
Select ID
from tbl
)
Print('Hello')

store SQL variable from INSERT query FROM clause result column

This is probably trivial to most of you, but I haven't been writing stored procedures for very long (6 months only). I'd like to be able to set the variable #testid based on one of the columns being used for an INSERT query. How can I do this?
DECLARE #testid INT;
INSERT INTO [exporttestresultreport] (
[testid],
[othercolumn]
)
SELECT
[testid], -- <======= how can I set my variable based on this column?
[othercolumn]
FROM
[exporttestresultreport] e
WHERE
[exporttestresultreportid] = #exporttestresultreportid
DECLARE #testid INT;
DECLARE #test TABLE (testid int);
INSERT INTO [exporttestresultreport] (
[testid],
[othercolumn]
)
OUTPUT INSERTED.testID INTO #test
SELECT
[testid], -- <======= how can I set my variable based on this column?
[othercolumn]
FROM
[exporttestresultreport] e
WHERE
[exporttestresultreportid] = #exporttestresultreportid;
SELECT #testid = testid FROM #test;
An INSERT..SELECT.. is inherently multirow so it doesn't make semse to allow assigning a value to a scalar variable: what row should be used for the value?
DECLARE #testid INT;
DECLARE #t TABLE(t INT);
INSERT exporttestresultreport
(
testid, othercolumn
)
OUTPUT INSERTED.testid INTO #t
SELECT testid, othercolumn
FROM
[exporttestresultreport] e
WHERE
[exporttestresultreportid] = #exporttestresultreportid;
SELECT #testid = t FROM #t;
-- not sure what you want to do if there are multiple rows in the insert

Dynamic insert into variable table statement SQL Server

I have a variable table:
DECLARE #A_Table TABLE(ID INT, att1 VARCHAR(100), att2 nvarchar(200))
I want to make dynamic sql, so I insert into this table some data (all inside a loop):
WHILE (#i <= 100) BEGIN
SELECT #other_att = NAME FROM #other_Table where ID = #i;
SET #sql = 'INSERT ' + #A_Table+ '(ID,att1,att2) SELECT '+CAST(#i AS VARCHAR)+' , '''+ #other_att+''', SUM('+ #other_att') FROM '+ #EVEN_OTHER_Table;
EXEC (#sql);
END
sql every time would look like:
INSERT INTO #A_Table SELECT 1 , 'subject', SUM(subject)
INSERT INTO #A_Table SELECT 2 , 'age', SUM(age)
INSERT INTO #A_Table SELECT 3 , 'sex', SUM(sex)....
AND after executing this :
SO I will get:
#A_Table:
id att1 att2
1 subject 4.3
2 age 4.5
3 sex 4.1
but I get an error:
Msg 137, Level 16, State 1, Line 48
Must declare the scalar variable "#A_Table".
SO what is it the syntax to insert dynamically into a variable table?
Ok I have understood it.
You could use the INSERT ... EXEC syntax to insert the data returned by the dynamic SELECT. Of course, you would then need to remove the INSERT part from the dynamic statement.
WHILE (#i <= 100) BEGIN
SELECT #other_att = NAME FROM #other_Table where ID = #i;
SET #sql = 'SELECT '+CAST(#i AS VARCHAR)+' , ''' + #other_att+''', SUM('+ #other_att + ') FROM '+ #EVEN_OTHER_Table;
INSERT INTO #A_Table (ID,att1,att2)
EXEC (#sql);
END
You have a table variable, not a variable that contains the table name.
So you would need the following.
WHILE (#i <= 100) BEGIN
SELECT #other_att = NAME FROM #other_Table where ID = #i;
SET #sql = 'INSERT INTO #A_Table (ID,att1,att2) SELECT '+CAST(#i AS VARCHAR)+' , '''+ #other_att+''', SUM('+ #other_att') FROM #EVEN_OTHER_Table';
EXEC (#sql);
END
You would also need to declare the table variable as a statement inside the #sql variable, and execute your declare table and inserts together, or use a local/global temporary table.
With a local temporary table (stored in the tempdb) you could do something like this.
CREATE TABLE #testtbl (ID INT);
EXEC ('INSERT INTO #testtbl VALUES (1)');
SELECT * FROM #testtbl
DROP TABLE #testtbl
Some good info about temporary tables in BOL
http://msdn.microsoft.com/en-us/library/ms174979.aspx - quite far down the page
And the table type.
http://msdn.microsoft.com/en-us/library/ms175010.aspx
Your EXEC statement occurs in a different context and is therefore unaware of any variables created in your original context.
To create dynamic insert query it is really a task, I also struggle to find it ,finally I have tried in the following way and it's successfully working. Please find the code below.
CREATE PROCEDURE [dbo].[InsertTodaysData] (#tbl varchar(50),#Days int,
#MDate varchar(50), #EValue varchar(50), #Speed varchar(50),
#Totalreturn varchar(50),#Closingv varchar(50), #TotalReturnV varchar(50))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #SQLQuery varchar(2000)
-- Insert statements for procedure here
set #SQLQuery = 'INSERT INTO '+#tbl+' (ID,MDate,EValue,Speed,TotalReturnRatio,ClosingValue,
TotalReturnValue) VALUES ('+#Days+','''+#MDate+''', '+#EValue+', '+#Speed+',
'+#Totalreturn+', '+#Closingv+', '+#TotalReturnV+')'
EXECUTE(#SQLQuery)
END
Hope this will help you..