I've got some data in the following format:
-1,-1,-1,-1,701,-1,-1,-1,-1,-1,304,390,403,435,438,439,442,455
I need to insert it into a temp table like this:
CREATE TABLE #TEMP
(
Node int
)
So that I can use it in a comparison with data in another table.
The data above represents separate rows of the "Node" column.
Is there an easy way to insert this data, all in one command?
Also, the data will actually being coming in as seen, as a string... so I need to be able to just concat it into the SQL query string. I can obviously modify it first if needed.
Try something like
CREATE TABLE #TEMP
(
Node int
)
DECLARE #textXML XML
DECLARE #data NVARCHAR(MAX),
#delimiter NVARCHAR(5)
SELECT #data = '-1,-1,-1,-1,701,-1,-1,-1,-1,-1,304,390,403,435,438,439,442,455 ',
#delimiter = ','
SELECT #textXML = CAST('<d>' + REPLACE(#data, #delimiter, '</d><d>') + '</d>' AS XML)
INSERT INTO #TEMP
SELECT T.split.value('.', 'nvarchar(max)') AS data
FROM #textXML.nodes('/d') T(split)
SELECT * FROM #TEMP
DROP TABLE #TEMP
You can create a query dynamically like this:
declare #sql varchar(1000)
set #sql = 'insert into #TEMP select ' + replace(#values, ',', ' union all select ')
exec #sql
As always when creating queries dynamically, you have to be careful so that you only use trusted data.
I would create a function that would return a table variable and then join that function into the select
Use:
select * from myTable a
inner join dbo.buildTableFromCSV('1,2,3') on a.id = b.theData
Here is my function for doing this
CREATE FUNCTION [dbo].[buildTableFromCSV] ( #csvString varchar(8000) ) RETURNS #myTable TABLE (ID int identity (1,1), theData varchar(100))
AS BEGIN
DECLARE #startPos Int -- position to chop next block of chars from
DECLARE #currentPos Int -- position to current character we're examining
DECLARE #strLen Int
DECLARE #c char(1) -- current subString
-- variable initalization
-- -------------------------------------------------------------------------------------------------------------------------------------------------
SELECT #csvString = #csvString + ','
SELECT #startPos = 1
SELECT #currentPos = 1
SELECT #strLen = Len(#csvString)
-- loop over string and build temp table
-- -------------------------------------------------------------------------------------------------------------------------------------------------
WHILE #currentPos <= #strLen BEGIN
SET #c = SUBSTRING(#csvString, #currentPos, 1 )
IF ( #c = ',' ) BEGIN
IF ( #currentPos - #startPos > 0 ) BEGIN
INSERT
INTO #myTable ( theData )
VALUES ( CAST( SUBSTRING ( #csvString, #startPos, #currentPos - #startPos) AS varchar ) )
END
ELSE
begin
INSERT
INTO #myTable ( theData )
VALUES ( null )
end
SELECT #startPos = #currentPos + 1
END
SET #currentPos = #currentPos + 1
END
delete from #myTable where theData is null
return
END
Related
i'm trying to split this string "1,1_5,2_3,4" first on '_' and then split the sub string on ',' so it will be like "1,1_5,2_3,4" split-ed on '_' first so it will give this sub string "1,1" then this sub string split-ed on ',' and then insert the split-ed sub string "1 1" into temp table like this
INSERT INTO [dbo].[TEST] ([X],[Y])
VALUES (#X,#Y)
i did this with only split on one delimiter ',' like this
first i create a table Split function
ALTER FUNCTION [dbo].[Split]
(
-- Add the parameters for the function here
#RowData nvarchar(2000),
#SplitOn nvarchar(5)
)
RETURNS #RtnValue table
(
Id int identity(1,1),
Data nvarchar(100)
)
AS
BEGIN
-- Declare the return variable here
Declare #Cnt int
Set #cnt = 1
While(charindex(#SplitOn,#RowData) > 0)
Begin
Insert Into #RtnValue (data)
Select
Data = ltrim(RTRIM(SUBSTRING(#RowData,1,CHARINDEX(#SplitOn,#RowData)-1)))
set #RowData = SUBSTRING(#RowData,CHARINDEX(#SplitOn,#RowData)+1,len(#RowData))
set #Cnt = #Cnt + 1
End
insert into #RtnValue(data)
select Data = ltrim(RTRIM(#RowData))
RETURN
END
then i create this stored procedure
ALTER PROCEDURE [dbo].[uspTest]
-- Add the parameters for the stored procedure here
#StringOFXIDs nvarchar(2000)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #SOMETABLE TABLE(ID INT IDENTITY(1,1) UNIQUE, XID INT);
DECLARE #XCOUNT INT;
DECLARE #XCURRENT INT;
DECLARE #XCOUNTER INT = 1;
-- Insert statements for procedure here
INSERT INTO #SOMETABLE([XID])
SELECT [Data] FROM [dbo].[Split](#StringOFXIDs,',');
SELECT #XCOUNT = COUNT(1) FROM #SOMETABLE;
WHILE (#XCOUNTER <= #XCOUNT)
BEGIN
SELECT #XCOUNTER = [XID]
FROM #SOMETABLE
WHERE [ID] = #XCOUNTER
INSERT INTO [dbo].[TEST] ([X])
VALUES (#XCOUNTER)
SELECT #XCOUNTER +=1;
END
END
--EXEC [dbo].[uspTest] '1,2,3,4'
and then execute this stored procedure and every thing work but i can't figure out how to split the string on two characters or delimiters and then inserted to temp table thanks for any help in advance.
You can use XML functionality to split into rows, then split into columns:
DECLARE #string VARCHAR(100) = '1,1_5,2_3,4'
;WITH cte AS (SELECT RTRIM(LTRIM(Split.a.value('.', 'VARCHAR(100)'))) AS Txt
,ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS RN
FROM (SELECT CAST ('<M>' + REPLACE(#string, '_', '</M><M>') + '</M>' AS XML) AS DATA
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
,cte2 AS (SELECT CONVERT(XML,'<String><Section>'+ REPLACE(REPLACE(Txt ,'|',','),',', '</Section><Section>') + '</Section></String>') AS Txt
,RN
FROM cte
)
SELECT Txt.value('/String[1]/Section[1]','varchar(100)') AS Col1
,Txt.value('/String[1]/Section[2]','varchar(100)') AS Col2
FROM cte2
ORDER BY RN
Outputs:
Col1 Col2
---------------
1 1
5 2
3 4
This is the scenario:
My app will have the following:
A listbox (The checkbox property enabled) that will display a list of Something.
The user will select from the listbox (multiselect) by using the checkbox.
I will loop into All the checked items and store the ID's into an array. I will store the ID's into something like this separating the ID with a comma (1,2,3,4) and then I will use length -1 to delete the last comma.
How can I convert the string 1,2,3,4 into an integer type of data if my stored procedure is like this?
Select * from tblSomething Where ID in (1,2,3,4)
You can use the following SQL function.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[CommaSeparatedToString]
(
#psCSString VARCHAR(8000)
)
RETURNS #otTemp TABLE(sID VARCHAR(20))
AS
BEGIN
DECLARE #sTemp VARCHAR(50)
WHILE LEN(#psCSString) > 0
BEGIN
SET #sTemp = LEFT(#psCSString, ISNULL(NULLIF(CHARINDEX(',', #psCSString) - 1, -1),
LEN(#psCSString)))
SET #psCSString = SUBSTRING(#psCSString,ISNULL(NULLIF(CHARINDEX(',', #psCSString), 0),
LEN(#psCSString)) + 1, LEN(#psCSString))
INSERT INTO #otTemp VALUES (#sTemp)
END
RETURN
END
And call in your stored procedure like
Select * from tblSomething
Where ID in (SELECT * FROM CommaSeparatedToString('1,2,3,4'))
You can use the
SELECT CAST(MyVarcharCol AS INT) FROM Table
SELECT CONVERT(INT, MyVarcharCol) FROM Table
refer this link
http://msdn.microsoft.com/en-us/library/ms187928.aspx
You need to create dynamic query for this
e.g you are getting list of values in #values paramter so prepare and run the dynamic query like this
DECLARE #query NVARCHAR(500)
DECLARE #values VARCHAR(200)
SET #values='1,2'
SET #query =N'Select * from tblSomething Where ID in ( ' + #values + ')'
SELECT #query
EXEC #Query
Use this function to split the value:
CREATE FUNCTION [dbo].[udfSplitCSV]
(
#String varchar (max),
#Delimiter varchar (10) = ','
)
RETURNS #ValueTable TABLE ([Row] int IDENTITY(1,1), [Value] varchar(max), [Length] int, [Duplicate] int NULL)
BEGIN
DECLARE #NextString varchar(max)
DECLARE #Pos int
DECLARE #NextPos int
IF #String IS NULL RETURN
--Initialize
SET #NextString = ''
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
WHILE (#Pos <> 0)
BEGIN
SET #NextString = RTrim(LTrim(SubString(#String,1,#Pos - 1)))
INSERT INTO #ValueTable ([Value], [Length]) VALUES (#NextString, Len(#NextString))
SET #String = SubString(#String,#Pos+1,Len(#String))
SET #NextPos = #Pos
SET #Pos = CharIndex(#Delimiter,#String)
END
UPDATE #ValueTable
SET [Duplicate] = X.Duplicate
FROM #ValueTable VT
INNER JOIN (Select [Row], [Value], Row_Number() OVER (Partition By [Value] ORDER BY [Value], [Row]) as Duplicate FROM #ValueTable) X
ON X.[Row] = VT.[Row]
RETURN
END
-- Select * from dbo.udfSplitCSV('a , c b,c, a', ',')
When you are storing a bunch of IDs into the array, store with single quote.
so it will be ('1','2','3').
Then you no need to covert IDs into integer.
I have two variables like:
#FieldName
#values
Those two variables hold values like:
#FieldName - contains [a],[b],[c],[d]
#values - contains 5,6,7,8
Now I need to retrieve the data of column 'b' & 'd' only.
How can we get b=6 & d=8?
Thanks in advance.
well I hate to do such a things on SQL Server, but
declare #FieldName nvarchar(max) = '[a],[b],[c],[d]'
declare #values nvarchar(max) = '5,6,7,8'
declare #i int, #j int, #break int
declare #a nvarchar(max), #b nvarchar(max), #result nvarchar(max)
select #break = 0
while #break = 0
begin
select #i = charindex(',', #FieldName), #j = charindex(',', #values)
if #i > 0 and #j > 0
begin
select #a = left(#FieldName, #i - 1), #b = left(#values, #j - 1)
select #FieldName = right(#FieldName, len(#FieldName) - #i), #values = right(#values, len(#values) - #j)
end
else
begin
select #a = #FieldName, #b = #values, #break = 1
end
if #a in ('[b]', '[d]')
select #result = isnull(#result + ' & ', '') + #a + '=' + #b
end
select #result
You can also put all this list into temporary/variable table and do join.
select *
from
(
select T.<yourcolumn>, row_number() over (order by T.<yourcolumn>) as rownum
from <temptable1> as T
) as F
inner join
(
select T.<yourcolumn>, row_number() over (order by T.<yourcolumn>) as rownum
from <temptable2> as T
) as V on V.rownum = F.rownum
Or, even better, you can pass parameters into sp in xml form and not in distinct lists
Try this :
Using XML i'm are trying to spilt the values and storing the result in a table variable
DECLARE #FieldName VARCHAR(MAX),
#values varchar(max)
SET #FieldName = 'a,b,c,d';
SET #values = '5,6,7,8'
SET #FieldName = #FieldName + ',';
SET #values = #values + ',';
DECLARE #X XML
SET #X = CAST('<Item>' + REPLACE(#FieldName, ',', '</Item><Item>') + '</Item>' AS XML)
Declare #X1 XML
Set #X1=CAST('<Position>' + REPLACE(#values, ',', '</Position><Position>') + '</Position>' AS XML)
Declare #FieldSample table
(
FieldName char(1),
rowNum int
)
Declare #valueSample table
(position int,
rowNum int)
Insert into #FieldSample(rowNum,FieldName)
Select * from (
SELECT row_number() over (order by (select 0)) as rowNum, t.value('.', 'char(1)') as field
FROM #x.nodes('/Item') as x(t)
) as a
where a.field !=''
Insert into #valueSample(rowNum,position)
Select * from (
Select row_number() over (order by (select 0)) as rowNum, k.value('.', 'int') as position
from #X1.nodes('/Position') as x1(k)
) as b
where b.position !=0
Basically the last logic you can change it based on how you intend to get the data
Select a.FieldName,b.position from #FieldSample as a
inner join #valueSample as b
on a.rowNum=b.rowNum
where b.position = 6 or b.position =8
Need help on how to improve my SQL script for better performance. dbo.Products table has a million rows. I'm hesitant to rewrite it using dynamic SQL. Thanks!
DECLARE
#Brand varchar(MAX) = 'Brand 1, Brand 2, Brand 3',
#ItemCategory varchar(MAX) = 'IC1, IC2, IC3, IC4, IC5'
--will return all records if params where set to #Brand = NULL, #ItemCategory = NULL
SELECT
[Brand],
SUM([Amount]) AS [Amount]
FROM dbo.Products (NOLOCK)
LEFT JOIN [dbo].[Split](#Brand, ',') FilterBrand ON Brand = [FilterBrand].[Items]
LEFT JOIN [dbo].[Split](#ItemCategory, ',') FilterItemCategory ON ItemCategory = [FilterItemCategory].[Items]
WHERE
(#Brand IS NULL OR (#Brand IS NOT NULL AND [FilterBrand].[Items] IS NOT NULL)) AND
(#ItemCategory IS NULL OR (#ItemCategory IS NOT NULL AND [FilterItemCategory].[Items] IS NOT NULL))
GROUP BY
[Brand]
Below is the split table-valued function that I found on the web:
CREATE function [dbo].[Split]
(
#String varchar(8000),
#Delimiter char(1)
)
RETURNS #Results TABLE (Items varchar(4000))
AS
BEGIN
IF (#String IS NULL OR #String = '') RETURN
DECLARE #i int, #j int
SELECT #i = 1
WHILE #i <= LEN(#String)
BEGIN
SELECT #j = CHARINDEX(#Delimiter, #String, #i)
IF #j = 0
BEGIN
SELECT #j = len(#String) + 1
END
INSERT #Results SELECT RTRIM(SUBSTRING(#String, #i, #j - #i))
SELECT #i = #j + LEN(#Delimiter)
END
RETURN
END
Following solution are with out using functions
Declare #IDs Varchar(100)
SET #IDs = '2,4,6'
Select IsNull(STUFF((Select ', '+ CAST([Name] As Varchar(100)) From [TableName]
Where CharIndex(','+Convert(Varchar,[ID])+',', ','+#IDs+',')> 0
For XML Path('')),1,1,''),'') As [ColumnName]
Here is the function I use. I also have another that wraps this to return numeric values which I find helpful as well.
Edit: Sorry, as for how to improve the performance of the query, I usually split the values into table variables and perform my joins to that but that probably won't change your performance, just your readability. The only thing I can see in terms of performance is your double checking whether your joins produce anything. You really can't get much better performance with two conditional left joins on two tables. It basically boils down to indexes at that point.
(#Brand IS NULL OR [FilterBrand].[Items] IS NOT NULL)
Function:
ALTER FUNCTION [dbo].[fn_SplitDelimittedList]
(
#DelimittedList varchar(8000),
#Delimitter varchar(20)
)
RETURNS
#List TABLE
(
Item varchar(100)
)
AS
BEGIN
DECLARE #DelimitterLength INT
SET #DelimitterLength = LEN(#Delimitter)
-- Tack on another delimitter so we get the last item properly
set #DelimittedList = #DelimittedList + #Delimitter
declare #Position int
declare #Item varchar(500)
set #Position = patindex('%' + #Delimitter + '%' , #DelimittedList)
while (#Position <> 0)
begin
set #Position = #Position - 1
set #Item = LTRIM(RTRIM(left(#DelimittedList, #Position)))
INSERT INTO #List (Item) VALUES (#Item)
set #DelimittedList = stuff(#DelimittedList, 1, #Position + #DelimitterLength, '')
set #Position = patindex('%' + #Delimitter + '%' , #DelimittedList)
end
RETURN
END
Hey just try the split function I have created without using any while loops here.And just use this in place of your split function and use col to match in LEFT join.
ALTER function dbo.SplitString(#inputStr varchar(1000),#del varchar(5))
RETURNS #table TABLE(col varchar(100))
As
BEGIN
DECLARE #t table(col1 varchar(100))
INSERT INTO #t
select #inputStr
if CHARINDEX(#del,#inputStr,1) > 0
BEGIN
;WITH CTE as(select ROW_NUMBER() over (order by (select 0)) as id,* from #t)
,CTE1 as (
select id,ltrim(rtrim(LEFT(col1,CHARINDEX(#del,col1,1)-1))) as col,RIGHT(col1,LEN(col1)-CHARINDEX(#del,col1,1)) as rem from CTE
union all
select c.id,ltrim(rtrim(LEFT(rem,CHARINDEX(#del,rem,1)-1))) as col,RIGHT(rem,LEN(rem)-CHARINDEX(#del,rem,1))
from CTE1 c
where CHARINDEX(#del,rem,1)>0
)
INSERT INTO #table
select col from CTE1
union all
select rem from CTE1 where CHARINDEX(#del,rem,1)=0
END
ELSE
BEGIN
INSERT INTO #table
select col1 from #t
END
RETURN
END
DECLARE #Brand varchar(MAX) = 'Brand 1,Brand 2,Brand 3',
#ItemCategory varchar(MAX) = ' IC1 A ,IC2 B , IC3 C, IC4 D' --'IC1, IC2, IC3, IC4, IC5'
select * from dbo.SplitString(#ItemCategory,',')
Consider a situation we have two variables in SQL Server 2005's SP as below,
#string1 = 'a,b,c,d'
#string2 = 'c,d,e,f,g'
Is there a solution to get a new string out of that like (#string1 U #string2) without using any loops. i.e the final string should be like,
#string3 = 'a,b,c,d,e,f,g'
In case you need to do this as a set and not one row at a time. Given the following split function:
USE tempdb;
GO
CREATE FUNCTION dbo.SplitStrings(#List nvarchar(max))
RETURNS TABLE
AS
RETURN ( SELECT Item FROM
( SELECT Item = x.i.value(N'./text()[1]', N'nvarchar(max)')
FROM ( SELECT [XML] = CONVERT(xml, '<i>'
+ REPLACE(#List,',', '</i><i>') + '</i>').query('.')
) AS a CROSS APPLY [XML].nodes('i') AS x(i) ) AS y
WHERE Item IS NOT NULL
);
GO
Then with the following table and sample data, and string variable, you can get all of the results this way:
DECLARE #foo TABLE(ID INT IDENTITY(1,1), col NVARCHAR(MAX));
INSERT #foo(col) SELECT N'c,d,e,f,g';
INSERT #foo(col) SELECT N'c,e,b';
INSERT #foo(col) SELECT N'd,e,f,x,a,e';
DECLARE #string NVARCHAR(MAX) = N'a,b,c,d';
;WITH x AS
(
SELECT f.ID, c.Item FROM #foo AS f
CROSS APPLY dbo.SplitStrings(f.col) AS c
), y AS
(
SELECT ID, Item FROM x
UNION
SELECT x.ID, s.Item
FROM dbo.SplitStrings(#string) AS s
CROSS JOIN x
)
SELECT ID, Items = STUFF((SELECT ',' + Item
FROM y AS y2 WHERE y2.ID = y.ID
FOR XML PATH(''), TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'')
FROM y
GROUP BY ID;
Results:
ID Items
-- ----------
1 a,b,c,d,e,f,g
2 a,b,c,d,e
3 a,b,c,d,e,f,x
On newer versions (SQL Server 2017+), the query is much simpler, and you don't need to create your own custom string-splitting function:
;WITH x AS
(
SELECT f.ID, c.value FROM #foo AS f
CROSS APPLY STRING_SPLIT
(
CONCAT(f.col, N',', #string), N','
) AS c GROUP BY f.ID, c.value
)
SELECT ID, STRING_AGG(value, N',')
WITHIN GROUP (ORDER BY value)
FROM x GROUP BY ID;
Example db<>fiddle
Now that all said, what you really should do is follow the previous advice and store these things in a related table in the first place. You can use the same type of splitting methodology to store the strings separately whenever an insert or update happens, instead of just dumping the CSV into a single column, and your applications shouldn't really have to change the way they're passing data into your procedures. But it sure will be easier to get the data out!
EDIT
Adding a potential solution for SQL Server 2008 that is a bit more convoluted but gets things done with one less loop (using a massive table scan and replace instead). I don't think this is any better than the solution above, and it is certainly less maintainable, but it is an option to test out should you find you are able to upgrade to 2008 or better (and also for any 2008+ users who come across this question).
SET NOCOUNT ON;
-- let's pretend this is our static table:
CREATE TABLE #x
(
ID int IDENTITY(1,1),
col nvarchar(max)
);
INSERT #x(col) VALUES(N'c,d,e,f,g'), (N'c,e,b'), (N'd,e,f,x,a,e');
-- and here is our parameter:
DECLARE #string nvarchar(max) = N'a,b,c,d';
The code:
DECLARE #sql nvarchar(max) = N'DECLARE #src TABLE(ID INT, col NVARCHAR(32));
DECLARE #dest TABLE(ID int, col nvarchar(32));';
SELECT #sql += '
INSERT #src VALUES(' + RTRIM(ID) + ','''
+ REPLACE(col, ',', '''),(' + RTRIM(ID) + ',''') + ''');'
FROM #x;
SELECT #sql += '
INSERT #dest VALUES(' + RTRIM(ID) + ','''
+ REPLACE(#string, ',', '''),(' + RTRIM(ID) + ',''') + ''');'
FROM #x;
SELECT #sql += '
WITH x AS (SELECT ID, col FROM #src UNION SELECT ID, col FROM #dest)
SELECT DISTINCT ID, Items = STUFF((SELECT '','' + col
FROM x AS x2 WHERE x2.ID = x.ID FOR XML PATH('''')), 1, 1, N'''')
FROM x;'
EXEC sys.sp_executesql #sql;
GO
DROP TABLE #x;
This is much trickier to do in 2005 (though not impossible) because you need to change the VALUES() clauses to UNION ALL...
Two ways you can do that:
Build a CLR function to do the job for you. Move the logic back to .NET code which is much easier platform for string manipulation.
If you have to use SQL Server, then you will need to:
"explode" the two strings into two tables, this function might help: http://blog.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx
Get a unique list of strings from the two tables. (simple query)
"implode" the two string tables into a variable (http://stackoverflow.com/questions/194852/concatenate-many-rows-into-a-single-text-string)
Found this function dbo.Split in a related answer, which you can use like this:
declare #string1 nvarchar(50) = 'a,b,c,d'
declare #string2 nvarchar(50) = 'c,d,e,f,g'
select * from dbo.split(#string1, ',')
select * from dbo.split(#string2, ',')
declare #data nvarchar(100) = ''
select #data = #data + ',' + Data from (
select Data from dbo.split(#string1, ',')
union
select Data from dbo.split(#string2, ',')
) as d
select substring(#data, 2, LEN(#data))
The last SELECT returns
a,b,c,d,e,f,g
How about
set #string3 = #string1+','+#string2
Sorry, wasn't clear you wanted only unique occurrences. What version of SQL server are you using? String manipulation functions vary per version.
If you don't mind a UDF to split the string, try this:
CREATE FUNCTION dbo.Split
(
#RowData nvarchar(2000),
#SplitOn nvarchar(5)
)
RETURNS #RtnValue table
(
Id int identity(1,1),
Data nvarchar(100)
)
AS
BEGIN
Declare #Cnt int
declare #data varchar(100)
Set #Cnt = 1
While (Charindex(#SplitOn,#RowData)>0)
Begin
Insert Into #RtnValue (data)
Select ltrim(rtrim(Substring(#RowData,1,Charindex(#SplitOn,#RowData)-1)))
Set #RowData = Substring(#RowData,Charindex(#SplitOn,#RowData)+1,len(#RowData))
Set #Cnt = #Cnt + 1
End
Insert Into #RtnValue (data)
Select Data = ltrim(rtrim(#RowData))
Return
END
and the code to use the UDF
go
#string1 = 'a,b,c,d'
#string2 = 'c,d,e,f,g'
declare #string3 varchar(200)
set #string3 = ''
select #string3 = #string3+data+','
from ( select data,min(id) as Id from dbo.split(#string1+','+#string2,',')
group by data ) xx
order by xx.id
print left(#string3,len(#string3)-1)
The following SQL function will convert a comma separated list to a table variable...
CREATE FUNCTION [dbo].[udfCsvToTable]( #CsvString VARCHAR( 8000))
-- Converts a comman separated value into a table variable
RETURNS #tbl TABLE( [Value] VARCHAR( 100) COLLATE DATABASE_DEFAULT NOT NULL)
AS BEGIN
DECLARE #Text VARCHAR( 100)
SET #CsvString = RTRIM( LTRIM( #CsvString))
SET #CsvString = REPLACE( #CsvString, CHAR( 9), '')
SET #CsvString = REPLACE( #CsvString, CHAR( 10), '')
SET #CsvString = REPLACE( #CsvString, CHAR( 13), '')
IF LEN( #CsvString) < 1 RETURN
WHILE LEN( #CsvString) > 0 BEGIN
IF CHARINDEX( ',', #CsvString) > 0 BEGIN
SET #Text = LEFT( #CsvString, CHARINDEX( ',', #CsvString) - 1)
SET #CsvString = LTRIM( RTRIM( RIGHT( #CsvString, LEN( #CsvString) - CHARINDEX( ',', #CsvString))))
END
ELSE BEGIN
SET #Text = #CsvString
SET #CsvString = ''
END
INSERT #tbl VALUES( LTRIM( RTRIM( #Text)))
END
RETURN
END
You can then union the two tables together, like so...
SELECT * FROM udfCsvToTable('a,b,c,d')
UNION
SELECT * FROM udfCsvToTable('c,d,e,f,g')
Which will give you a result set of:
a
b
c
d
e
f
g