need splitting a variable into 6 variables - SQL - sql

need help filling in the blanks i am struggling with splitting a variable into 6 variables.
DECLARE #item VARCHAR(MAX) = 'MG1111.TG2222.MW3333.JG4444.MG5555.MH6666'
DECLARE #item1 VARCHAR(MAX)
DECLARE #item2 VARCHAR(MAX)
DECLARE #item3 VARCHAR(MAX)
DECLARE #item4 VARCHAR(MAX)
DECLARE #item5 VARCHAR(MAX)
DECLARE #item6 VARCHAR(MAX)
set #item1 = (SUBSTRING( #item, 0, CHARINDEX('.', #item)))
set #item2 = (SUBSTRING(SUBSTRING( #item, CHARINDEX('.', #item)+1,LEN(#ITEM)),0,CHARINDEX('.', SUBSTRING( #item, CHARINDEX('.', #item)+1,LEN(#ITEM))) ))
set #item6 = (REVERSE(SUBSTRING( REVERSE(#ITEM), 0, CHARINDEX('.' , REVERSE(#ITEM)))))
print #item1
print #item2
print #item3
print #item4
print #item5
print #item6

Just about any String Parser will do. That said, I have one that will return (currently) up to 9 variables
Select #item1=Pos1
,#item2=Pos2
,#item3=Pos3
,#item4=Pos4
,#item5=Pos5
,#item6=Pos6
From [dbo].[udf-Str-Parse-Row](#Item,'.')
The UDF
CREATE FUNCTION [dbo].[udf-Str-Parse-Row] (#String varchar(max),#Delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse-Row]('Dog,Cat,House,Car',',')
-- Select * from [dbo].[udf-Str-Parse-Row]('John Cappelletti',' ')
-- Select * from [dbo].[udf-Str-Parse-Row]('id26,id46|id658,id967','|')
Returns Table
As
Return (
SELECT Pos1 = xDim.value('/x[1]','varchar(250)')
,Pos2 = xDim.value('/x[2]','varchar(250)')
,Pos3 = xDim.value('/x[3]','varchar(250)')
,Pos4 = xDim.value('/x[4]','varchar(250)')
,Pos5 = xDim.value('/x[5]','varchar(250)')
,Pos6 = xDim.value('/x[6]','varchar(250)')
,Pos7 = xDim.value('/x[7]','varchar(250)')
,Pos8 = xDim.value('/x[8]','varchar(250)')
,Pos9 = xDim.value('/x[9]','varchar(250)')
FROM (Select Cast('<x>' + Replace(#String,#Delimeter,'</x><x>')+'</x>' as XML) as xDim) A
)

Here is a simpler way using XML trick
DECLARE #item VARCHAR(max) = 'MG1111.TG2222.MW3333.JG4444.MG5555.MH6666'
DECLARE #item1 VARCHAR(max)
DECLARE #item2 VARCHAR(max)
DECLARE #item3 VARCHAR(max)
DECLARE #item4 VARCHAR(max)
DECLARE #item5 VARCHAR(max)
DECLARE #item6 VARCHAR(max);
WITH split_names
AS (SELECT CONVERT(XML, '<Names><name>' + Replace(#item, '.', '</name><name>') + '</name></Names>') AS xmlname)
SELECT #item1 = xmlname.value('/Names[1]/name[1]', 'varchar(50)'),
#item2 = xmlname.value('/Names[1]/name[2]', 'varchar(50)'),
#item3 = xmlname.value('/Names[1]/name[3]', 'varchar(50)'),
#item4 = xmlname.value('/Names[1]/name[4]', 'varchar(50)'),
#item5 = xmlname.value('/Names[1]/name[5]', 'varchar(50)'),
#item6 = xmlname.value('/Names[1]/name[6]', 'varchar(50)')
FROM split_names

Why not use this pattern?
set #item1 = SUBSTRING_INDEX( #item, '.', 1)
.
set #item3 = SUBSTRING_INDEX( SUBSTRING_INDEX( #item, '.', 2), '.', 1)
.
.
set #item6 = SUBSTRING_INDEX( #item, '.', -1)
I am assuming by 6 variables you mean each substring between the dots in #item is a separate "variable".

A more generic parser could be as follows. This one returns a row number and is not limited as to depth.
DECLARE #item VARCHAR(MAX) = 'MG1111.TG2222.MW3333.JG4444.MG5555.MH6666'
DECLARE #item1 VARCHAR(MAX)
DECLARE #item2 VARCHAR(MAX)
DECLARE #item3 VARCHAR(MAX)
DECLARE #item4 VARCHAR(MAX)
DECLARE #item5 VARCHAR(MAX)
DECLARE #item6 VARCHAR(MAX)
Select #item1=max(case when Key_PS=1 then Key_Value else '' end)
,#item2=max(case when Key_PS=2 then Key_Value else '' end)
,#item3=max(case when Key_PS=3 then Key_Value else '' end)
,#item4=max(case when Key_PS=4 then Key_Value else '' end)
,#item5=max(case when Key_PS=5 then Key_Value else '' end)
,#item6=max(case when Key_PS=6 then Key_Value else '' end)
From [dbo].[udf-Str-Parse](#Item,'.')
The UDF
CREATE FUNCTION [dbo].[udf-Str-Parse] (#String varchar(max),#Delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
-- Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
Returns #ReturnTable Table (Key_PS int IDENTITY(1,1), Key_Value varchar(max))
As
Begin
Declare #XML xml;Set #XML = Cast('<x>' + Replace(#String,#Delimeter,'</x><x>')+'</x>' as XML)
Insert Into #ReturnTable Select ltrim(rtrim(String.value('.', 'varchar(max)'))) FROM #XML.nodes('x') as T(String)
Return
End

Related

Aliasing column names dynamically in SQL Server

Providing separate aliasing values to each column dynamically. The number of values in #column_name1 and #aliasing_val can change as per requirements, so please provide a solution that can work for any number of values in the #column_name1 and #aliasing_val.
Declare #table_name1 NVARCHAR(250) = 'table1',
#column_name1 NVARCHAR(250) = 't1col1,t1col2,t1col3',
#aliasing_val NVARCHAR(250) = 'c1,c2,c3',
#SQLString nvarchar(max),
#SQLString2 nvarchar(max)
If ((#table_name1 IS NOT NULL AND LEN(#table_name1) !=0)
AND (#column_name1 IS NOT NULL AND LEN(#column_name1) !=0))
BEGIN
set #SQLString2 = 'SELECT '
Select #SQLString2 = #SQLString2 +
QUOTENAME(split.a.value('.', 'VARCHAR(100)')) + ' As '+aliasing_val+',
'
FROM (SELECT Cast ('<M>' + Replace(#column_name1, ',', '</M><M>')+ '</M>' AS XML) AS Data) AS A
CROSS apply data.nodes ('/M') AS Split(a);
Set #SQLString2 = LEFT(#SQLString2, LEN(#SQLString2) - 3)
END
print #SQLString2
Current output:
SELECT [t1col1] As c1,c2,c3,
[t1col2] As c1,c2,c3,
[t1col3] As c1,c2,c3
Expected output
SELECT [t1col1] As c1,
[t1col2] As c2,
[t1col3] As c3
This should do the job. You need to separate the comma-separated elements of each string out one at a time. This script loops through the items and maintains a pointer to the next item in the list. Then at each loop it extracts the item and adds it to the SQL:
Declare #table_name1 NVARCHAR(250) = 'table1',
#column_name1 NVARCHAR(250) = 't1col1,t1col2,t1col3',
#aliasing_val NVARCHAR(250) = 'c1,c2,c3',
#SQLString nvarchar(max),
#SQLString2 nvarchar(MAX),
#count [int],
#pos int,
#pos2 [int],
#delimiter varchar(1);
SET #delimiter = ',';
SET #pos = CHARINDEX(#delimiter, #aliasing_val, 1)
SET #pos2 = CHARINDEX(#delimiter, #column_name1, 1)
SET #aliasing_val = LTRIM(RTRIM(#aliasing_val)) + #delimiter
SET #column_name1 = LTRIM(RTRIM(#column_name1)) + #delimiter
SET #count = 0
IF ((#table_name1 IS NOT NULL AND LEN(#table_name1) !=0) AND (#column_name1 IS NOT NULL AND LEN(#column_name1) !=0))
BEGIN
SET #SQLString2 = 'SELECT '
IF REPLACE(#aliasing_val, #delimiter, '') <> '' -- make sure there are actually any delimited items in the list
BEGIN
WHILE #pos > 0
BEGIN
IF #count > 0 SET #SQLString2 = #SQLString2 + ','
SET #SQLString2 = #SQLString2 + LTRIM(RTRIM(LEFT(#column_name1, #pos2 - 1))) + ' As ' + LTRIM(RTRIM(LEFT(#aliasing_val, #pos - 1)))
SET #aliasing_val = RIGHT(#aliasing_val, LEN(#aliasing_val) - #pos) -- remove the item we just extracted from the list
SET #column_name1 = RIGHT(#column_name1, LEN(#column_name1) - #pos2) -- remove the item we just extracted from the list
SET #pos = CHARINDEX(#delimiter, #aliasing_val, 1) -- reset the position to point to the next delimiter
SET #pos2 = CHARINDEX(#delimiter, #column_name1, 1) -- reset the position to point to the next delimiter
SET #count = #count + 1
END
END
END
SELECT #SQLString2
You are at the right approach. Only thing you need to do is make two separate select statement for #column_name and #aliasing_val and join it using ROW_NUMBER() function and you got what you expect - Try this
IF ((#table_name1 IS NOT NULL AND LEN(#table_name1) !=0) AND (#column_name1 IS NOT NULL AND LEN(#column_name1) !=0))
BEGIN
SET #SQLString2 = 'SELECT '
SELECT #SQLString2 += tab.ColName + ' As '+ res.AliasName +','
FROM
(
SELECT QUOTENAME(split.a.value('.', 'VARCHAR(100)')) AS ColName, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNum
FROM
(
SELECT Cast ('<M>' + Replace(#column_name1, ',', '</M><M>')+ '</M>' AS XML) AS Data
) AS A
CROSS apply data.nodes ('/M') AS Split(a)
) tab
INNER JOIN
(
Select AliasSplit.c.value('.', 'varchar(100)') AS AliasName, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNum
FROM
(
SELECT Cast ('<A>' + Replace(#aliasing_val, ',', '</A><A>')+ '</A>' AS XML) AS AliasData
) AS A
CROSS apply AliasData.nodes ('/A') AS AliasSplit(c)
) res
ON tab.RowNum = res.RowNum
Set #SQLString2 = LEFT(#SQLString2, LEN(#SQLString2) - 1)
END
PRINT #SQLString2
Output
SELECT [t1col1] As c1,[t1col2] As c2,[t1col3] As c3

Split data from 2 symbols

have table
CREATE TABLE #tbl
(
id int identity(1,1),
obj_type int ,
obj_id nvarchar(50)
)
have data like : 153:0|114:0|147:0|148:0|152:0|155:0
want insert which data ise before " : " to obj_id , which data is next to " : " insert tu obj_type. it's must be like
id obj_type obj_id
1 0 153
2 0 114
3 0 147
4 0 148
5 0 152
6 0 155
How do it in stored procedure ? not function
declare #S varchar(100) = '153:0|114:0|147:0|148:0|152:0|155:0'
declare #xml xml
select #xml = '<item><value>'+replace(replace(#s, ':','</value><value>'), '|','</value></item><item><value>')+'</value></item>'
select N.value('value[1]', 'int') as obj_id,
N.value('value[2]', 'int') as obj_type
from #xml.nodes('item') as T(N)
SQL Fiddle
You can wait for some experts answer
till then you can give it one chance
insert into #tbl
SELECT LEFT(splitdata, CHARINDEX(':', splitdata) - 1) AS obj_id,
RIGHT(splitdata, CHARINDEX(':', REVERSE(splitdata)) - 1) AS obj_type from (select splitdatafrom fnSplitString(parameterName,'|')
now you can write stringsplit function like this
CREATE FUNCTION [dbo].[fnSplitString]
(
#string NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE #start INT, #end INT
SELECT #start = 1, #end = CHARINDEX(#delimiter, #string)
WHILE #start < LEN(#string) + 1 BEGIN
IF #end = 0
SET #end = LEN(#string) + 1
INSERT INTO #output (splitdata)
VALUES(SUBSTRING(#string, #start, #end - #start))
SET #start = #end + 1
SET #end = CHARINDEX(#delimiter, #string, #start)
END
RETURN
END
Another Solution :
Create FUNCTION [dbo].[SplitString]
(
#List NVARCHAR(MAX),
#Delim VARCHAR(255)
)
RETURNS TABLE
AS
RETURN ( SELECT [Value] FROM
(
SELECT
[Value] = LTRIM(RTRIM(SUBSTRING(#List, [Number],
CHARINDEX(#Delim, #List + #Delim, [Number]) - [Number])))
FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_objects) AS x
WHERE Number <= LEN(#List)
AND SUBSTRING(#Delim + #List, [Number], LEN(#Delim)) = #Delim
) AS y
);
taken form: T-SQL split string
And then select the values:
Declare
#Text varchar (100) = '153:0|114:0|147:0|148:0|152:0|155:0',
#Delim varchar(50) = ':0|'
select case when CHARINDEX(':0', Value) > 0 then Left(Value, Len(Value)-2) else Value End AS Result from dbo.SplitString(#Text, #Delim)
CREATE procedure [dbo].[Insert_procedure]
#inputString varchar(max)
AS
BEGIN
set #inputString ='2153:770|114:0|147:0|148:0|152:0|155:0' Declare #delimiter char(1) = '|' Declare #delimiter_Colon char(1) = ':'
DECLARE #chIndex int DECLARE #chIndex1 int DECLARE #item varchar(100)Declare #ReverseString varchar(max)
SELECT #ReverseString = Reverse(substring(reverse(#inputString), 1, 1))
IF(#ReverseString <> '|')
set #inputString = #inputString +'|'
WHILE CHARINDEX(#delimiter, #inputString, 0) <> 0
BEGIN
SET #chIndex = CHARINDEX(#delimiter, #inputString, 0)
SELECT #item = SUBSTRING(#inputString, 1, #chIndex - 1)
IF LEN(#item) > 0
BEGIN
set #chIndex1 = CHARINDEX(#delimiter_Colon, #item, 0)
Declare #obj_type int Declare #obj_id varchar(50)
SELECT #obj_id = SUBSTRING(#item, #chIndex1+1,len(#item)) SELECT #obj_type = SUBSTRING(#item,1,#chIndex1-1)
Insert into TEST(obj_type,obj_id) values (#obj_type,#obj_id)
END
SELECT #inputString = SUBSTRING(#inputString, #chIndex + 1, LEN(#inputString))
END
END

Looking for multiples substrings within a SQL string

I have several occurrences of differences strings in the columns, like this example
'dsasdasdsd'+'ewewewew'+'45454545'+(avg('uuuuuuu'))
I need to split this string into several columns with the substrings that are between
aphostropes
like this:
Column 1 = dsasdasdsd
Column 2 = ewewewew
Column 3 = 45454545
Column 4 = uuuuuuu
The numbers of apperances are random, thefore the length of the original column is also not fixed (from 50 char to > 1000)
DECLARE #InStr VarChar(1000) = '''dsasdasdsd''+''ewewewew''+''45454545''+(avg(''uuuuuuu''))'''
DECLARE #intStart INT = 0
DECLARE #intEnd INT = 1
DECLARE #ColNo INT = 1
DECLARE #MyString VARCHAR(2000)
DECLARE #SelectString VARCHAR(8000) = 'SELECT '
WHILE(#intStart < LEN(#InStr) )
BEGIN
SELECT #intStart = CHARINDEX(CHAR(39), #InStr, 0) + 1
SELECT #intEnd = CHARINDEX(CHAR(39), #InStr, #intStart)
SELECT #SelectString = #SelectString + CHAR(39) + SUBSTRING(#InStr, #intStart, #intEnd - #intStart) + CHAR(39) + ' As [Column ' + CAST(#ColNo As Varchar) + '],'
SELECT #InStr = SUBSTRING(#InStr, #intEnd + 1, LEN(#InStr)-#intEnd )
SET #ColNo = #ColNo +1
END
SELECT #SelectString = LEFT(#SelectString, Len(#SelectString) -1)
EXEC (#SelectString)
I have been playing with this and this does run but unfortunately I don't have time right now to carry on with it but maybe you can improve on this?
HTH
You can try this:
create table tSqlStrings (sText nvarchar(1000))
insert tSqlStrings values('''dsasdasdsd''+''ewewewew''+''45454545''+(avg(''uuuuuuu''))')
create table tResults (
sColumn1 nvarchar(1000)
,sColumn2 nvarchar(1000)
,sColumn3 nvarchar(1000)
,sColumn4 nvarchar(1000)
)
and
DELETE tResults
DECLARE #sText nvarchar(1000) = (
SELECT
sText
FROM
tSqlStrings
)
DECLARE #lBegin int = CHARINDEX('''',#sText)
DECLARE #lEnd int = charindex('''',
substring(#sText,
CHARINDEX('''',#sText)+1,
len(#sText)))
DECLARE #sText0 nvarchar(1000)
DECLARE #sColumn1 nvarchar(1000)
DECLARE #sColumn2 nvarchar(1000)
DECLARE #sColumn3 nvarchar(1000)
DECLARE #sColumn4 nvarchar(1000)
DECLARE #iCnt int = 1
while #iCnt<=4
--(0<len(#sText) and 0<#lBegin and 0<#lEnd)
BEGIN
SET #sText0 = substring(#sText,#lBegin+1,#lEnd-2)
IF #iCnt=1 begin SET #sColumn1=#sText0 end
IF #iCnt=2 begin SET #sColumn2=#sText0 end
IF #iCnt=3 begin SET #sColumn3=#sText0 end
IF #iCnt=4 begin SET #sColumn4=#sText0 end
set #sText = substring(#sText,#lBegin + #lEnd+2,len(#sText))
SET #lBegin = CHARINDEX('''',#sText)
SET #lEnd = charindex('''',
substring(#sText,
CHARINDEX('''',#sText)+1,
len(#sText)))
SET #iCnt = #iCnt+1
END
INSERT
tResults (sColumn1,sColumn2,sColumn3,sColumn4)
VALUES (#sColumn1,#sColumn2,#sColumn3,#sColumn4)
SELECT * FROM tResults
on sql fiddle
You will be able to achieve this using CHARINDEX() and SUBSTRING()
Following example shows for splitting to 2 columns. When it has more columns, query will be get little more complicated. However, you can follow this to build your query.
SELECT OriginalColumn
, SUBSTRING(OriginalColumn, 1,CHARINDEX('x',OriginalColumn,1)-1) AS Column1
, SUBSTRING(OriginalColumn, CHARINDEX('x',OriginalColumn,1) + 1 ,CHARINDEX('x',OriginalColumn,CHARINDEX('x',OriginalColumn,1)-1)) AS Column2
FROM YourTable
I have used "x" as the delimiter in the example. Following is a sample result
try this:
declare #delim char
set #delim = ''''
declare #str nvarchar(max)
declare #substr nvarchar(max)
declare #newstr nvarchar(max)
declare #tmpTable table (partStrings nvarchar(max))
declare #count int
set #count = 0
select #str = <***Your String***>
while(charindex(#delim,#str) != 0)
begin
set #count = #count + 1
Select #substr = substring(#str,1,charindex(#delim,#str)-1)
if((#count % 2) = 0)
begin
insert into #tmpTable values(#substr)
end
Set #newstr = substring(#str,charindex(#delim,#str)+1,len(#str)-charindex(#delim,#str))
set #str = #newstr
end
select partStrings from #tmpTable

How to pass Concatenation String in IN SQL value

how to pass the concatenation String into SQL SELECT IN () ?
DECLARE #NextString NVARCHAR(40)
DECLARE #Pos INT
DECLARE #NextPos INT
DECLARE #String NVARCHAR(40)
DECLARE #Delimiter NVARCHAR(40)
SET #String ='1,2'
SET #Delimiter = ','
SET #String = #String + #Delimiter
SET #Pos = charindex(#Delimiter,#String)
WHILE (#pos <> 0)
BEGIN
SET #NextString = substring(#String,1,#Pos - 1)
SELECT #NextString -- Show Results
SET #String = substring(#String,#pos+1,len(#String))
SET #pos = charindex(#Delimiter,#String)
SELECT ADRESSE, AGENCE, AUTRE_REF, CHAUFFEUR, CODE_CLIENT, CODE_DEST, CODE_MAG, CP, CREE_PAR, DATE_CLOTUR, DATE_CREE, DATE_MODIF, EMAIL, ENLEV_CREMB, ENLEV_DECL, ENLEV_UNITE, FACTURATION, FAX, INSEE, LIVRS_EXPRS, LIVRS_SAMD, LIVRS_SIGN, MODAL_MODE, MODAL_PORT, MODAL_SPEC, MODIF_PAR, NBR_COLIS, NO_ORDRE, OBS, PAYS, POID, POID_COR, REF_EXPED, RS_NOM, SIRET, STATUT_ORDRE, TEL, TRANSPORTEUR, VILLE FROM ORDRE WHERE (STATUT_ORDRE = 2) AND (TRANSPORTEUR IN (#NextString))
END
i tried with this, but in not work exactly what i expected.
Thanks you in advance,
Stev
if you know how many parameters in #NextString, you can use
TRANSPORTEUR IN (#parm1,#parm2,#parm3......)
OR you need to use the exec to execute the sql
declare #sql varchar(max)
set #sql='SELECT ADRESSE, AGENCE, AUTRE_REF,
CHAUFFEUR, CODE_CLIENT, CODE_DEST,
CODE_MAG, CP, CREE_PAR, DATE_CLOTUR,
DATE_CREE, DATE_MODIF, EMAIL,
ENLEV_CREMB, ENLEV_DECL, ENLEV_UNITE, FACTURATION,
FAX, INSEE, LIVRS_EXPRS, LIVRS_SAMD, LIVRS_SIGN,
MODAL_MODE, MODAL_PORT, MODAL_SPEC, MODIF_PAR, NBR_COLIS,
NO_ORDRE, OBS, PAYS, POID, POID_COR, REF_EXPED, RS_NOM, SIRET, STATUT_ORDRE, TEL, TRANSPORTEUR, VILLE FROM ORDRE WHERE (STATUT_ORDRE = 2) AND (TRANSPORTEUR IN (' + #NextString + '))'
exec (#sql)
and you should set the #NextString as '''p1'',''p2'',''p3'''
==================================================================================
update on 11-Jan-2013
create the spiting function
CREATE FUNCTION [dbo].[udf_Split]
( #Words nvarchar(MAX)
, #splitStr varchar(50)
)
RETURNS #Result_Table TABLE
(
[word] nvarchar(max) NULL
)
BEGIN
Declare #TempStr nvarchar(MAX)
WHILE (CHARINDEX(#splitStr,#Words)>0)
BEGIN
Set #TempStr=SUBSTRING(#Words,1,CHARINDEX(#splitStr,#Words)-1)
Insert into #Result_Table (word) Values (rtrim(ltrim(#TempStr)))
Set #Words = REPLACE(#Words,#TempStr+#splitStr,'')
END
IF(LEN(RTRIM(LTRIM(#Words)))>0 And CHARINDEX(#splitStr,RTRIM(LTRIM(#Words)))=0)
Begin
Set #TempStr=#Words
Insert into #Result_Table (word) Values (rtrim(ltrim(#TempStr)))
End
RETURN
END
then using join instead of using in
SELECT ADRESSE,
AGENCE,
AUTRE_REF,
CHAUFFEUR,
CODE_CLIENT,
CODE_DEST,
CODE_MAG,
CP,
CREE_PAR,
DATE_CLOTUR,
DATE_CREE,
DATE_MODIF,
EMAIL,
ENLEV_CREMB,
ENLEV_DECL,
ENLEV_UNITE,
FACTURATION,
FAX,
INSEE,
LIVRS_EXPRS,
LIVRS_SAMD,
LIVRS_SIGN,
MODAL_MODE,
MODAL_PORT,
MODAL_SPEC,
MODIF_PAR,
NBR_COLIS,
NO_ORDRE,
OBS,
PAYS,
POID,
POID_COR,
REF_EXPED,
RS_NOM,
SIRET,
STATUT_ORDRE,
TEL,
TRANSPORTEUR,
VILLE
FROM ORDRE a
INNER JOIN udf_split(#NextString, ',') b
ON b.word = a.TRANSPORTEUR
WHERE (STATUT_ORDRE = 2)

Split value pairs and a create table using UDF

I've been trying to write a Table-Valued function that takes value pairs as a parameter and return a table with two columns.
Below is the function signature I am trying to do.
FUNCTION [dbo].[ValuePairParser]( #DelimitedValuePairs VARCHAR(MAX),
#Delimiter CHAR(1),
#ValuePairDelimiter CHAR(1) )
RETURNS #ValuePairTable
TABLE ( Id INT, Code INT )
I want to call the method like below
#ValuePairs VARCHAR(MAX) = '1:1, 1:2, 1:4, 2:3, 1000:230, 130:120,'
ValuePairParser (#ValuePairs, ',', ':')
Can you see any nice way to split above ValuePairs sting and create a table with two columns?
CREATE FUNCTION [dbo].[SplitWithPairs]
(
#List NVARCHAR(MAX),
#MajorDelimiter VARCHAR(3) = ',',
#MinorDelimiter VARCHAR(3) = ':'
)
RETURNS #Items TABLE
(
Position INT IDENTITY(1,1) NOT NULL,
LeftItem INT NOT NULL,
RightItem INT NOT NULL
)
AS
BEGIN
DECLARE
#Item NVARCHAR(MAX),
#LeftItem NVARCHAR(MAX),
#RightItem NVARCHAR(MAX),
#Pos INT;
SELECT
#List = #List + ' ',
#MajorDelimiter = LTRIM(RTRIM(#MajorDelimiter)),
#MinorDelimiter = LTRIM(RTRIM(#MinorDelimiter));
WHILE LEN(#List) > 0
BEGIN
SET #Pos = CHARINDEX(#MajorDelimiter, #List);
IF #Pos = 0
SET #Pos = LEN(#List) + LEN(#MajorDelimiter);
SELECT
#Item = LTRIM(RTRIM(LEFT(#List, #Pos - 1))),
#LeftItem = LTRIM(RTRIM(LEFT(#Item,
CHARINDEX(#MinorDelimiter, #Item) - 1))),
#RightItem = LTRIM(RTRIM(SUBSTRING(#Item,
CHARINDEX(#MinorDelimiter, #Item)
+ LEN(#MinorDelimiter), LEN(#Item))));
INSERT #Items(LeftItem, RightItem)
SELECT #LeftItem, #RightItem;
SET #List = SUBSTRING(#List,
#Pos + LEN(#MajorDelimiter), DATALENGTH(#List));
END
RETURN;
END
GO
DECLARE #ValuePairs VARCHAR(MAX) = '1:1, 1:2, 1:4, 2:3,1000:230, 130:120,';
SELECT LeftItem, RightItem
FROM dbo.SplitWithPairs(#ValuePairs, ',', ':')
ORDER BY Position;
GO
create function ValuePairParser(#DelimitedValuePairs varchar(MAX),
#Delimiter char(1),
#ValuePairDelimiter char(1))
returns #ValuePairTable table(Id int, Code int) as
begin
with Split(ValuePair, Rest) as
(
select left(#DelimitedValuePairs, charindex(#Delimiter, #DelimitedValuePairs)-1),
stuff(#DelimitedValuePairs, 1, charindex(#Delimiter, #DelimitedValuePairs), '')
where charindex(#Delimiter, #DelimitedValuePairs) > 0
union all
select left(Rest, charindex(#Delimiter, Rest)-1),
stuff(Rest, 1, charindex(#Delimiter, Rest), '')
from Split
where charindex(#Delimiter, Rest) > 0
)
insert into #ValuePairTable
select left(ValuePair, charindex(#ValuePairDelimiter, ValuePair)-1),
stuff(ValuePair, 1, charindex(#ValuePairDelimiter, ValuePair), '')
from Split
option (maxrecursion 0)
return
end