Reputation: 799
I have a SQL table with column which contain string like 'type|type1|type2|type3|type4'. I need to select the string, id. Split string and insert to another table. First item should be default and I need to get identity of it and insert to another table with the type value.
Please help me to create T-SQL query to accomplish desirable result.
Example
Step 1 To select Items from Table 1.
Step 2 Split to array
Step 3 Insert to Table 2 (first item will be default)
Step 4 Update Table 1 with default Type Value based on TypeID and Default True
Table 1
ID Items Default
--------------------------------------------------
1 type|type1|type2|type3|type4
2 type|type1|type2|type3|type4
Table 2
ID TypeID Type Default(bool)
--------------------------------------------------
1 1 type1 1
2 1 type2 0
Upvotes: 1
Views: 171
Reputation: 52645
Using the split function from Arnold Fribble's answer on this thread
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
You can write the following (I made some guesses about the ID field in table2 and what the defaultTypeID should be in table1 but you should be able to adjust that)
CREATE TABLE #table1 (
id INT,
items VARCHAR(MAX),
defaulttypeid INT
)
CREATE TABLE #table2 (
id INT IDENTITY,
typeid INT,
TYPE VARCHAR(5),
isdefault BIT
)
INSERT INTO #table1
VALUES (1,
'type|type1|type2|type3|type4',
NULL),
(2,
'type|type1|type2|type3|type4',
NULL)
INSERT INTO #table2
(typeid,
TYPE,
isdefault)
SELECT id typeid,
Rtrim(split.s) AS item,
CASE
WHEN ( split.pn = 1 ) THEN 1
ELSE 0
END AS isdefault
FROM #table1
CROSS APPLY test.dbo.Split('|', items) AS split
UPDATE #table1
SET defaulttypeid = t2.ID
FROM #table1 t1
INNER JOIN #table2 t2
ON t1.id = t2.typeid
AND t2.isdefault = 1
DROP TABLE #table1
DROP TABLE #table2
This outputs
ID Items DefaultTypeID
----------- ------------------------------ -------------
1 type|type1|type2|type3|type4 1
2 type|type1|type2|type3|type4 6
ID TypeID Type IsDefault
----------- ----------- ----- ---------
1 1 type 1
2 1 type1 0
3 1 type2 0
4 1 type3 0
5 1 type4 0
6 2 type 1
7 2 type1 0
8 2 type2 0
9 2 type3 0
10 2 type4 0
Upvotes: 2
Reputation: 25435
Though I totally disagree with the use of cursors I can't think of another way. This solution isn't tested but It looks like it should be ok.
DECLARE @pos INT
DECLARE @id INT
DECLARE @string VARCHAR(MAX)
DECLARE @default INT
DECLARE @substring VARCHAR(MAX)
DECLARE tempCursor CURSOR FOR
SELECT id, string
FROM table_name
OPEN tempCursor;
FETCH NEXT FROM tempCursor
INTO @id, @string
WHILE @@FETCH_STATUS = 0
BEGIN
SET @default = 1
SET @pos = CHARINDEX('|', @string)
WHILE (@pos <> 0)
BEGIN
SET @substring = SUBSTRING(@string, 1, @pos - 1)
INSERT INTO table_name2(typeid, type, default) VALUES (@id, @substring, @default)
SET @string = substring(@string, @pos+1, LEN(@string))
SET @pos = charindex('|', @string)
SET @default = 0
END
FETCH NEXT FROM tempCursor
INTO @id, @string
END
CLOSE EWSCursor;
DEALLOCATE EWSCursor;
Hope this helps.
Upvotes: 2