SQL: Split comma separated string list with a query? - sql

Here is my table structure:
id PaymentCond
1 ZBE1, AP1, LST2, CC1
2 VB3, CC1, ZBE1
I need to split the column PaymentCond, and would love to do that with a simple sql query since I have no clue how to use functions and would love to keep it all simple.
Here is what I already found:
SELECT id,
Substring(PaymentConditions, 1, Charindex(',', PaymentConditions)-1) as COND_1,
Substring(PaymentConditions, Charindex(',', PaymentConditions)+1, LEN(ANGEBOT.STDTXT)) as COND_2
from Payment
WHERE id = '1'
But this only outputs
id COND_1 COND_2
1 ZBE1 AP1, LST2, CC1
Is there a way to split everything from PaymentConditions to COND_1, COND_2, COND_3 and so on?
Thanks in advance.

first create function to split values
create function [dbo].[udf_splitstring] (#tokens varchar(max),
#delimiter varchar(5))
returns #split table (
token varchar(200) not null )
as
begin
declare #list xml
select #list = cast('<a>'
+ replace(#tokens, #delimiter, '</a><a>')
+ '</a>' as xml)
insert into #split
(token)
select ltrim(t.value('.', 'varchar(200)')) as data
from #list.nodes('/a') as x(t)
return
end
CREATE TABLE #Table1
([id] int, [PaymentCond] varchar(20))
;
INSERT INTO #Table1
([id], [PaymentCond])
VALUES
(1, 'ZBE1, AP1, LST2, CC1'),
(2, 'VB3, CC1, ZBE1')
;
select id, token FROM #Table1 as t1
CROSS APPLY [dbo].UDF_SPLITSTRING([PaymentCond],',') as t2
output
id token
1 ZBE1
1 AP1
1 LST2
1 CC1
2 VB3
2 CC1
2 ZBE1

declare #SchoolYearList nvarchar(max)='2014,2015,2016'
declare #start int=1
declare #length int=4
create table #TempFY(SchoolYear int)
while #start<len(#SchoolYearList)
BEGIN
Insert into #TempFY
select SUBSTRING(#SchoolYearList,#start,#length)
set #start=#start+5
END
Select SchoolYear from #TempFY

There is a new table-valued function in SQL Server STRING_SPLIT:
DECLARE #tags NVARCHAR(400) = 'aaaa,bbb,,cc,d'
SELECT *
FROM STRING_SPLIT(#tags, ',')
You will get:
But be careful its availability in your DB: The STRING_SPLIT function is available only under compatibility level 130

Related

How to get only Capital letters from given value

I have a table it contains ID, Description and code columns. I need to fill code column using description column. Sample Description is "Investigations and Remedial Measures" so my code should be "IRM".
Note: Is there any words like "and/for/to/in" avoid it
This code may help you..
declare #input as varchar(1000) -- Choose the appropriate size
declare #output as varchar(1000) -- Choose the appropriate size
select #input = 'Investigations and Remedial Measures', #output = ''
declare #i int
select #i = 0
while #i < len(#input)
begin
select #i = #i + 1
select #output = #output + case when unicode(substring(#input, #i, 1))between 65
and 90 then substring(#input, #i, 1) else '' end
end
SELECT #output
Personally I would do this with an inline table-valued function
On SQL Server 2017 or better, or Azure SQL Database:
CREATE OR ALTER FUNCTION dbo.ExtractUpperCase(#s nvarchar(4000))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
WITH s(s) AS (SELECT 1 UNION ALL SELECT s+1 FROM s WHERE s < LEN(#s))
SELECT TOP (3) value = STRING_AGG(SUBSTRING(#s,s,1),'')
WITHIN GROUP (ORDER BY s.s)
FROM s WHERE ASCII(SUBSTRING(#s,s,1)) BETWEEN 65 AND 90
);
GO
On SQL Server 2016 or older:
CREATE FUNCTION dbo.ExtractUpperCase(#s nvarchar(4000))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
WITH s(s) AS (SELECT 1 UNION ALL SELECT s+1 FROM s WHERE s < LEN(#s))
SELECT value = (SELECT TOP (3) v = SUBSTRING(#s,s,1) FROM s
WHERE ASCII(SUBSTRING(#s,s,1)) BETWEEN 65 AND 90
ORDER BY s.s FOR XML PATH(''),
TYPE).value(N'./text()[1]',N'nvarchar(4000)')
);
GO
In either case:
CREATE TABLE #x(id int, name nvarchar(4000));
INSERT #x(id, name) VALUES
(1, N'Belo Horizonte Orange'),
(2, N'São Paulo Lala'),
(3, N'Ferraz de Vasconcelos Toranto');
SELECT id, f.value FROM #x AS x
CROSS APPLY dbo.ExtractUpperCase(x.name) AS f
ORDER BY id OPTION (MAXRECURSION 4000);
Results:
id name
---- ----
1 BHO
2 SPL
3 SVT
The OPTION (MAXRECURSION 4000) is only necessary if your strings can be longer than 100 characters.

Sql table comma separated values contain any of variable values checking

I have a variable #a='1,2,3,4' and a table that contain a column B that contain comma separated values.
How can I check that column B values contain any of the #a variable values?
You need to implement a function for splitting the values. There are a lot of variations, you can use this:
CREATE FUNCTION [dbo].[fn_Analysis_ConvertCsvListToNVarCharTableWithOrder](#List nvarchar(max), #Delimiter nvarchar(10) = ',')
RETURNS #result TABLE
(
[Value] nvarchar(max),
[SortOrder] bigint NOT NULL
)
AS
BEGIN
IF #Delimiter is null
BEGIN
SET #Delimiter = ','
END
DECLARE #XML xml = N'<r><![CDATA[' + REPLACE(#List, #Delimiter, ']]></r><r><![CDATA[') + ']]></r>'
DECLARE #BufTable TABLE (Value nvarchar(max), SortOrder bigint NOT NULL IDENTITY(1, 1) PRIMARY KEY)
INSERT INTO #BufTable (Value)
SELECT Tbl.Col.value('.', 'nvarchar(max)')
FROM #xml.nodes('//r') Tbl(Col)
OPTION (OPTIMIZE FOR (#xml = NULL))
INSERT INTO #result (Value, SortOrder)
SELECT Value, SortOrder
FROM #BufTable
RETURN
END
Having such function, its pretty easy:
DECLARE #DataSource TABLE
(
[column] VARCHAR(1024)
);
DECLARE #column VARCHAR(1024) = '1,2,3,4';
INSERT INTO #DataSource ([column])
VALUES ('100,200,300')
,('100,1,500')
,('1,2,3,500')
,('200')
,('33,32,31,4,30');
SELECT DISTINCT [column]
FROM #DataSource
CROSS APPLY [dbo].[fn_Analysis_ConvertCsvListToNVarCharTableWithOrder] ([column], ',') DSV
INNER JOIN [dbo].[fn_Analysis_ConvertCsvListToNVarCharTableWithOrder] (#column, ',') FV
ON DSV.[Value] = FV.[Value];
Using CROSS APPLY we are splitting the values for each column. Then we are splitting the filtering values and performing INNER JOIN in order to match only the rows having a value contained in the filter value. After that, we need a DISTINCT because column value may contains many values from the filter.
A t-sql string "splitter" is what you need but I would NOT use the mTVF recommended above as it is extremely inefficient and will kill parallelism. An inline table valued function (iTVF) is what you want for splitting strings.
I would suggest using delimitedSplit8k or delimitedSplit8k_lead which will perform ~30-90 times faster; or STRING_SPLIT if you're on SQL 2016+ and only need the value which will be several hundred times faster. Note this performance test:
-- sample data
declare #rows int = 10000;
if object_id('tempdb..#strings') is not null drop table #strings;
select top (#rows)
someid = identity(int,1,1),
somestring = replace(right(left(cast(newid() as varchar(36)), 27),21),'-',',')
into #strings
from sys.all_columns a, sys.all_columns b;
-- Performance test
set nocount on;
print 'fn_Analysis_ConvertCsvListToNVarCharTableWithOrder'+char(10)+replicate('-',50);
go
declare #st datetime = getdate(), #item varchar(10);
select #item = [value]
from #strings t
cross apply dbo.fn_Analysis_ConvertCsvListToNVarCharTableWithOrder(t.somestring,',');
print datediff(ms,#st,getdate());
go 5
print 'delimitedSplit8K (serial)'+char(10)+replicate('-',50);
go
declare #st datetime = getdate(), #item varchar(10);
select #item = item
from #strings t
cross apply dbo.DelimitedSplit8K(t.somestring,',')
option (maxdop 1);
print datediff(ms,#st,getdate());
go 5
print 'delimitedSplit8K (parallel)'+char(10)+replicate('-',50);
go
declare #st datetime = getdate(), #item varchar(10);
select #item = item
from #strings t
cross apply dbo.DelimitedSplit8K(t.somestring,',')
option (recompile, querytraceon 8649);
print datediff(ms,#st,getdate());
go 5
Results
fn_Analysis_ConvertCsvListToNVarCharTableWithOrder
--------------------------------------------------
Beginning execution loop
4183
4274
4536
4294
4406
Batch execution completed 5 times.
delimitedSplit8K (serial)
--------------------------------------------------
Beginning execution loop
50
50
50
54
53
Batch execution completed 5 times.
delimitedSplit8K (parallel)
--------------------------------------------------
Beginning execution loop
133
134
133
140
136
Batch execution completed 5 times.
How you could use to solve your problem
declare #sometable table(someid int identity, someNbr tinyint);
insert #sometable values (1),(3),(6),(12),(7),(15),(19);
declare #searchstring varchar(1000) = '1,2,3,4,19';
select someid, someNbr
from #sometable t
cross apply dbo.DelimitedSplit8K(#searchstring,',') s
where t.someNbr = s.Item;
Results
someid someNbr
----------- -------
1 1
2 3
7 19

t-sql find specific value with a csv string

I need some on help a SQL Query. I have a column with values stored as comma separated values.
I need to write a query which finds the 3rd delimited item within each value in the column.
Is this possible to do this in a Select statement?
ex: ColumnValue: josh,Reg01,False,a0-t0,22/09/2010
So I will need to get the 3rd value (i.e.) False from the above string.
Yes.
Where #s is your string...
select
SUBSTRING (#s,
CHARINDEX(',',#s,CHARINDEX(',',#s)+1)+1,
CHARINDEX(',',#s,CHARINDEX(',',#s,CHARINDEX(',',#s)+1)+1)
-CHARINDEX(',',#s,CHARINDEX(',',#s)+1)-1)
Or more generically...
;with cte as
(
select 1 as Item, 1 as Start, CHARINDEX(',',#s, 1) as Split
union all
select cte.Item+1, cte.Split+1, nullif(CHARINDEX(',',#s, cte.Split+1),0) as Split
from cte
where cte.Split<>0
)
select SUBSTRING(#s, start,isnull(split,len(#s)+1)-start)
from cte
where Item = 3
Now store your data properly :)
Try this (assuming SQL Server 2005+)
DECLARE #t TABLE(ColumnValue VARCHAR(50))
INSERT INTO #t(ColumnValue) SELECT 'josh,Reg01,False,a0-t0,22/09/2010'
INSERT INTO #t(ColumnValue) SELECT 'mango,apple,bannana,grapes'
INSERT INTO #t(ColumnValue) SELECT 'stackoverflow'
SELECT ThirdValue = splitdata
FROM(
SELECT
Rn = ROW_NUMBER() OVER(PARTITION BY ColumnValue ORDER BY (SELECT 1))
,X.ColumnValue
,Y.splitdata
FROM
(
SELECT *,
CAST('<X>'+REPLACE(F.ColumnValue,',','</X><X>')+'</X>' AS XML) AS xmlfilter FROM #t F
)X
CROSS APPLY
(
SELECT fdata.D.value('.','varchar(50)') AS splitdata
FROM X.xmlfilter.nodes('X') as fdata(D)
) Y
)X WHERE X.Rn = 3
//Result
ThirdValue
False
bannana
Also it is not very clear from your question as what version of SQL Server you are using. In case you are using SQL SERVER 2000, you can go ahead with the below approach.
Step 1: Create a number table
CREATE TABLE dbo.Numbers
(
N INT NOT NULL PRIMARY KEY
);
GO
DECLARE #rows AS INT;
SET #rows = 1;
INSERT INTO dbo.Numbers VALUES(1);
WHILE(#rows <= 10000)
BEGIN
INSERT INTO dbo.Numbers SELECT N + #rows FROM dbo.Numbers;
SET #rows = #rows * 2;
END
Step 2: Apply the query below
DECLARE #t TABLE(ColumnValue VARCHAR(50))
INSERT INTO #t(ColumnValue) SELECT 'josh,Reg01,False,a0-t0,22/09/2010'
INSERT INTO #t(ColumnValue) SELECT 'mango,apple,bannana,grapes'
INSERT INTO #t(ColumnValue) SELECT 'stackoverflow'
--Declare a table variable to put the identity column and store the indermediate results
DECLARE #tempT TABLE(Id INT IDENTITY,ColumnValue VARCHAR(50),SplitData VARCHAR(50))
-- Insert the records into the table variable
INSERT INTO #tempT
SELECT
ColumnValue
,SUBSTRING(ColumnValue, Numbers.N,CHARINDEX(',', ColumnValue + ',', Numbers.N) - Numbers.N) AS splitdata
FROM #t
JOIN Numbers ON Numbers.N <= DATALENGTH(ColumnValue) + 1
AND SUBSTRING(',' + ColumnValue, Numbers.N, 1) = ','
--Project the filtered records
SELECT ThirdValue = X.splitdata
FROM
--The co-related subquery does the ROW_NUMBER() OVER(PARTITION BY ColumnValue)
(SELECT
Rn = (SELECT COUNT(*)
FROM #tempT t2
WHERE t2.ColumnValue=t1.ColumnValue
AND t2.Id<=t1.Id)
,t1.ColumnValue
,t1.splitdata
FROM #tempT t1)X
WHERE X.Rn =3
-- Result
ThirdValue
False
bannana
Also you can use Master..spt_Values for your number table
DECLARE #t TABLE(ColumnValue VARCHAR(50))
INSERT INTO #t(ColumnValue) SELECT 'josh,Reg01,False,a0-t0,22/09/2010'
INSERT INTO #t(ColumnValue) SELECT 'mango,apple,bannana,grapes'
INSERT INTO #t(ColumnValue) SELECT 'stackoverflow'
--Declare a table variable to put the identity column and store the indermediate results
DECLARE #tempT TABLE(Id INT IDENTITY,ColumnValue VARCHAR(50),SplitData VARCHAR(50))
-- Insert the records into the table variable
INSERT INTO #tempT
SELECT
ColumnValue
,SUBSTRING(ColumnValue, Number ,CHARINDEX(',', ColumnValue + ',', Number ) - Number) AS splitdata
FROM #t
JOIN master..spt_values ON Number <= DATALENGTH(ColumnValue) + 1 AND type='P'
AND SUBSTRING(',' + ColumnValue, Number , 1) = ','
--Project the filtered records
SELECT ThirdValue = X.splitdata
FROM
--The co-related subquery does the ROW_NUMBER() OVER(PARTITION BY ColumnValue)
(SELECT
Rn = (SELECT COUNT(*)
FROM #tempT t2
WHERE t2.ColumnValue=t1.ColumnValue
AND t2.Id<=t1.Id)
,t1.ColumnValue
,t1.splitdata
FROM #tempT t1)X
WHERE X.Rn =3
You can read about this from
1) What is the purpose of system table table master..spt_values and what are the meanings of its values?
2) Why (and how) to split column using master..spt_values?
You really need something like String.Split(',')(2) which unfortunately dos not exist in SQL but this may be helpful to you
You can make some test with this solution and the other ones but, I believe that using XML in such situations almost always gives to you best performance and insure less coding:
DECLARE #InPutCSV NVARCHAR(2000)= 'josh,Reg01,False,a0-t0,22/09/2010'
DECLARE #ValueIndexToGet INT=3
DECLARE #XML XML = CAST ('<d>' + REPLACE(#InPutCSV, ',', '</d><d>') + '</d>' AS XML);
WITH CTE(RecordNumber,Value) AS
(
SELECT ROW_NUMBER() OVER(ORDER BY T.v.value('.', 'NVARCHAR(100)') DESC) AS RecordNumber
,T.v.value('.', 'NVARCHAR(100)') AS Value
FROM #XML.nodes('/d') AS T(v)
)
SELECT Value
FROM CTE WHERE RecordNumber=#ValueIndexToGet
I can confirm that it takes 1 seconds to get value from CSV string with 100 000 values.

SQL Query Substring Query

I have a database column in a SQL Server 2008 database that contains VARCHAR data composed of four elements separated by an underscore; for example:
01_1234_ABC_TESTFOO
02_2234_YES_FOO
03_77653234_NO_BAR
04_10922234_BLUE_TESTBAR
05_8372_SKY_FOOBAR
I need a query to return the first three elements for each row as separate columns. I have managed to separate out the first two elements with the following code:
SELECT DISTINCT SUBSTRING(BarType, 1, CHARINDEX('_', BarType) - 1) as element1,
SUBSTRING(BarType,CHARINDEX('_',BarType)+1,
CHARINDEX('_', SUBSTRING(BarType,CHARINDEX('_',BarType)+1,LEN(BarType)))-1) as element2
FROM dbo.TestDataFoo
This returns:
element1 element2
01 1234
02 2234
03 77653234
04 10922234
05 8372
Could someone help me to get the third element of the data please? I'd also be interested to learn of any alternate methods for dealing with this.
See below for code to generate test data.
CREATE TABLE TestDataFoo (
id int PRIMARY KEY IDENTITY,
DateFoo datetime NOT NULL,
BarType varchar(50) NOT NULL)
INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '01_1234_ABC_TESTFOO')
INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '02_2234_YES_FOO')
INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '03_77653234_NO_BAR')
INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '04_10922234_BLUE_TESTBAR')
INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '05_8372_SKY_FOOBAR')
Thanks
Nimi
Edit: Ideally, I'd like to achieve this without using a function but any solutions welcome!
;with cte as
(
select cast('<r><i>'+replace(BarType,'_','</i><i>')+'</i></r>' as xml) as xmlcol
from TestDataFoo
)
select
r.value('i[1]', 'varchar(50)') as element1,
r.value('i[2]', 'varchar(50)') as element2,
r.value('i[3]', 'varchar(50)') as element3
from cte
cross apply xmlcol.nodes('r') r(r)
Here's a handy function that I think would do the trick.
create function [dbo].[fn_split]
(
#String nvarchar (4000)
,#Delimiter nvarchar (10)= ','
)
returns #ValueTable table ([Value] nvarchar(4000))
as
/******************************************************************************
** name: fn_split
** desc: splits a delimited list into a table
** select * from dbo.fn_split('01_1234_ABC_TESTFOO', '_')
*******************************************************************************/
begin
declare #NextString nvarchar(4000)
declare #Pos int
declare #NextPos int
declare #CommaCheck nvarchar(1)
--Initialize
set #NextString = ''
set #CommaCheck = right(#String,1)
--Check for trailing Comma, if not exists, INSERT
--if (#CommaCheck <> #Delimiter )
set #String = #String + #Delimiter
--Get position of first Comma
set #Pos = charindex(#Delimiter,#String)
set #NextPos = 1
--Loop while there is still a comma in the String of levels
while (#pos <> 0)
begin
set #NextString = substring(#String,1,#Pos - 1)
insert into #ValueTable ( [Value]) Values (#NextString)
set #String = substring(#String,#pos +1,len(#String))
set #NextPos = #Pos
set #pos = charindex(#Delimiter,#String)
end
return
end
GO
Just use the old PARSENAME trick:
SQL
SELECT
PARSENAME(REPLACE(MEGASTRING,'_','.'),4) AS COL1,
PARSENAME(REPLACE(MEGASTRING,'_','.'),3) AS COL2,
PARSENAME(REPLACE(MEGASTRING,'_','.'),2) AS COL3,
PARSENAME(REPLACE(MEGASTRING,'_','.'),1) AS COL4
FROM (
SELECT '01_1234_ABC_TESTFOO' AS MEGASTRING
UNION ALL SELECT '02_2234_YES_FOO' AS MEGASTRING
UNION ALL SELECT '03_77653234_NO_BAR' AS MEGASTRING
UNION ALL SELECT '04_10922234_BLUE_TESTBAR' AS MEGASTRING
UNION ALL SELECT '05_8372_SKY_FOOBAR' AS MEGASTRING
) data
Results
COL1 COL2 COL3 COL4
01 1234 ABC TESTFOO
02 2234 YES FOO
03 77653234 NO BAR
04 10922234 BLUE TESTBAR
05 8372 SKY FOOBAR

Comma-separated value insertion In SQL Server 2005

How can I insert values from a comma-separated input parameter with a stored procedure?
For example:
exec StoredProcedure Name 17,'127,204,110,198',7,'162,170,163,170'
you can see that I have two comma-separated value lists in the parameter list. Both will have the same number of values: if the first has 5 comma-separated values, then the second one also has 5 comma-separated values.
127 and 162 are related
204 and 170 are related
...and same for the others.
How can I insert these two values?
One comma-separated value is inserted, but how do I insert two?
Have a lok at something like (Full Example)
DECLARE #Inserts TABLE(
ID INT,
Val1 INT,
Val2 INT,
Val3 INT
)
DECLARE #Param1 INT,
#Param2 VARCHAR(100),
#Param3 INT,
#Param4 VARCHAR(100)
SELECT #Param1 = 17,
#Param2 = '127,204,110,198',
#Param3 = 7,
#Param4 = '162,170,163,170'
DECLARE #Table1 TABLE(
ID INT IDENTITY(1,1),
Val INT
)
DECLARE #Table2 TABLE(
ID INT IDENTITY(1,1),
Val INT
)
DECLARE #textXML XML
SELECT #textXML = CAST('<d>' + REPLACE(#Param2, ',', '</d><d>') + '</d>' AS XML)
INSERT INTO #Table1
SELECT T.split.value('.', 'nvarchar(max)') AS data
FROM #textXML.nodes('/d') T(split)
SELECT #textXML = CAST('<d>' + REPLACE(#Param4, ',', '</d><d>') + '</d>' AS XML)
INSERT INTO #Table2
SELECT T.split.value('.', 'nvarchar(max)') AS data
FROM #textXML.nodes('/d') T(split)
INSERT INTO #Inserts
SELECT #Param1,
t1.Val,
#Param3,
t2.Val
FROM #Table1 t1 INNER JOIN
#Table2 t2 ON t1.ID = t2.ID
SELECT *
FROM #Inserts
You need a way to split and process the string in TSQL, there are many ways to do this. This article covers the PROs and CONs of just about every method:
"Arrays and Lists in SQL Server 2005 and Beyond, When Table Value Parameters Do Not Cut it" by Erland Sommarskog
You need to create a split function. This is how a split function can be used:
SELECT
*
FROM YourTable y
INNER JOIN dbo.yourSplitFunction(#Parameter) s ON y.ID=s.Value
I prefer the number table approach to split a string in TSQL but there are numerous ways to split strings in SQL Server, see the previous link, which explains the PROs and CONs of each.
For the Numbers Table method to work, you need to do this one time table setup, which will create a table Numbers that contains rows from 1 to 10,000:
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
Once the Numbers table is set up, create this split function:
CREATE FUNCTION [dbo].[FN_ListToTableRows]
(
#SplitOn char(1) --REQUIRED, the character to split the #List string on
,#List varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN
(
----------------
--SINGLE QUERY-- --this will return empty rows, and row numbers
----------------
SELECT
ROW_NUMBER() OVER(ORDER BY number) AS RowNumber
,LTRIM(RTRIM(SUBSTRING(ListValue, number+1, CHARINDEX(#SplitOn, ListValue, number+1)-number - 1))) AS ListValue
FROM (
SELECT #SplitOn + #List + #SplitOn AS ListValue
) AS InnerQuery
INNER JOIN Numbers n ON n.Number < LEN(InnerQuery.ListValue)
WHERE SUBSTRING(ListValue, number, 1) = #SplitOn
);
GO
You can now easily split a CSV string into a table and join on it. To accomplish your task, set up a test table to insert into:
create table YourTable (col1 int, col2 int)
then create your procedure:
CREATE PROCEDURE StoredProcedureName
(
#Params1 int
,#Array1 varchar(8000)
,#Params2 int
,#Array2 varchar(8000)
)
AS
INSERT INTO YourTable
(col1, col2)
SELECT
a1.ListValue, a2.ListValue
FROM dbo.FN_ListToTableRows(',',#Array1) a1
INNER JOIN dbo.FN_ListToTableRows(',',#Array2) a2 ON a1.RowNumber=a2.RowNumber
GO
test it out:
exec StoredProcedureName 17,'127,204,110,198',7,'162,170,163,170'
select * from YourTable
OUTPUT:
(4 row(s) affected)
col1 col2
----------- -----------
127 162
204 170
110 163
198 170
(4 row(s) affected)
This may not be an answer to your question... But I thought of letting you know that there is a better way to pass related values (Table Format) to a stored procedure... XML... You can build the XML string in your app (just as regular string) and pass it on to the stored procedure as a parameter... You can then use the following syntax to get it into a table. Hope this helps... In this way you can pass an entire table as parameter to stored procedure...
--Parameters
#param1 int,
#Budgets xml,
#Param2 int
-- #Budgets = '<Values><Row><Val1>127</Val1><Val2>162</Val2></Row> <Row><Val1>204</Val1><Val2>170</Val2></Row></Values>'
SELECT #param1 as Param1,
x.query('Val1').value('.','int') as val1,
#param3 as Param3,
x.query('Val2').value('.','int') as val1,
into #NewTable
FROM #Budgets.nodes('/Values/Row') x1(x)