我有一个包含分隔字符串数据的表,
A|B|C|D|E|
F|G|H|I|K|
1|2|3|4|5|
6|7|8|9|10|
寻找像
这样的输出col1 col2 col2 col4 col5
A B C D E
F G H I K
1 2 3 4 5
6 7 8 9 10
在某些情况下,分隔的字符串有106个管道(|)分隔值。需要帮助才能有一个select语句,可以将分隔的字符串展平为要插入临时表的行。请指教......
目前,我们正在为每一行生成select语句并批量插入表中,这需要花费2个小时的时间来完成500000条记录。
答案 0 :(得分:1)
测试数据
DECLARE @t TABLE (Data NVARCHAR(1000))
INSERT INTO @t
VALUES
('A|B|C|D|E|F|G|H|I|K'),
('F|G|H|I|K|L|3|4|5|11'),
('1|2|3|4|5|11|7|8|9|10|13'),
('6|7|8|9|10|13|E|F|G|H|I|K')
<强>查询强>
;WITH Split_Fields (Field, xmlfields)
AS
(
SELECT Data AS Field,
CONVERT(XML,'<Fields><field>'
+ REPLACE(Data,'|', '</field><field>') + '</field></Fields>') AS xmlfields
FROM @t
)
SELECT
xmlfields.value('/Fields[1]/field[1]','varchar(100)') AS Column1,
xmlfields.value('/Fields[1]/field[2]','varchar(100)') AS Column2,
xmlfields.value('/Fields[1]/field[3]','varchar(100)') AS Column3,
xmlfields.value('/Fields[1]/field[4]','varchar(100)') AS Column4,
xmlfields.value('/Fields[1]/field[5]','varchar(100)') AS Column5,
xmlfields.value('/Fields[1]/field[6]','varchar(100)') AS Column6,
xmlfields.value('/Fields[1]/field[7]','varchar(100)') AS Column7,
xmlfields.value('/Fields[1]/field[8]','varchar(100)') AS Column8,
xmlfields.value('/Fields[1]/field[9]','varchar(100)') AS Column9,
xmlfields.value('/Fields[1]/field[10]','varchar(100)') AS Column10
FROM Split_Fields
结果集
╔═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦══════════╗
║ Column1 ║ Column2 ║ Column3 ║ Column4 ║ Column5 ║ Column6 ║ Column7 ║ Column8 ║ Column9 ║ Column10 ║
╠═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬══════════╣
║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I ║ K ║
║ F ║ G ║ H ║ I ║ K ║ L ║ 3 ║ 4 ║ 5 ║ 11 ║
║ 1 ║ 2 ║ 3 ║ 4 ║ 5 ║ 11 ║ 7 ║ 8 ║ 9 ║ 10 ║
║ 6 ║ 7 ║ 8 ║ 9 ║ 10 ║ 13 ║ E ║ F ║ G ║ H ║
╚═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩══════════╝
答案 1 :(得分:0)
目前,这是我采取的方法,在大约30分钟内执行500个事务的插入,包含106列:代码基本上生成100个插入语句,每个批处理TABLOCK选项,从表中读取500000个分隔字符串,并插入到目的地。
set @sql_temp=N'
declare @BatchSize int
declare @BatchCounter int
declare @TotalRecordCount int
declare @strBatchSQL nvarchar(max)
SET @BatchSize = 100
SET @BatchCounter = 0
set @TotalRecordCount = '+cast(@recordcount as varchar(50))+'
SET @strBatchSQL=null
while @BatchCounter < (@TotalRecordCount/@BatchSize) + 1
begin
SET @strBatchSQL =STUFF(
(
SELECT CAST('''' AS NVARCHAR(MAX)) + RTRIM(LTRIM(DelimitedFields))
FROM (
SELECT Row_Line,DelimitedFields,_Record_Id FROM (
SELECT
row_number() OVER(ORDER BY _Record_ID) AS Row_Line,Record_Id,Import_Sequence_Number,
''INSERT INTO '+ SUBSTRING(@YourTable,1,LEN(@YourTable)-1) +'_FLAT_TMP] WITH (TABLOCK) VALUES (''''''+ convert(varchar(20),rank() OVER (ORDER BY Record_Id))+'''''',''''N'''','''''+@LoadSpecificId+''''',''''N'''',''''''+Cast(Import_Sequence_Number as VarChar(100))+'''''',''+'''''''' + CAST(Record_ID AS VARCHAR (100)) + '''''','''''' + replace(record_string,''|'', '''''','''''') + '''''');'' AS DelimitedFields
FROM ' + @YourTable + ' WHERE Record_Id BETWEEN '+cast(@minrecordID as varchar(50))+' and '+cast(@maxrecordID as varchar(50))+' ) TabAlias
WHERE TabAlias.Row_Line > (@BatchSize * @BatchCounter )
AND TabAlias.Row_Line <= ((@BatchSize * @BatchCounter)+ @BatchSize)
) AS a
FOR XML PATH('''')
), 1,0, '''')
EXEC SP_EXECUTESQL @strBatchSQL
set @BatchCounter = @BatchCounter + 1
end'
EXEC SP_EXECUTESQL @sql_temp