我有一个带有列的SQL表,其中包含'type | type1 | type2 | type3 | type4'等字符串。 我需要选择字符串,id。拆分字符串并插入另一个表。第一项应该是默认值,我需要获取它的标识并插入另一个类型为值的表。
请帮我创建T-SQL查询以实现理想的结果。
实施例
步骤1 从表1中选择项目
第2步拆分为数组
第3步插入表2 (第一项将是默认值)
第4步使用基于TypeID和默认True的默认类型值更新表1
表1
ID Items Default
--------------------------------------------------
1 type|type1|type2|type3|type4
2 type|type1|type2|type3|type4
表2
ID TypeID Type Default(bool)
--------------------------------------------------
1 1 type1 1
2 1 type2 0
答案 0 :(得分:2)
虽然我完全不同意使用游标,但我想不出另一种方式。此解决方案未经过测试,但看起来应该没问题。
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;
希望这有帮助。
答案 1 :(得分:2)
使用Arnold Fribble对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
你可以写下面的内容(我对table2中的ID字段做了一些猜测,而table1中的defaultTypeID应该是什么,但你应该可以调整它)
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
此输出
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