两个如何使用两个分隔符拆分数据并插入到表中

时间:2016-02-15 08:06:13

标签: sql-server sql-server-2008 tsql

有这样的字符串:

declare @parse nvarchar(max) = 'p1=201,p22=129,p3=5555555555,p21=1234567*22.08.2013*12.00,p5=some_text1,p12=12.0|p1=202,p22=145,p3=4515125,p21=12756624*16.08.2013*15.00,p5=some_tex2t,p12=16.0|p1=105,p22=103,p3=54658294572,p21=54112124*16.09.2013*11.00,p5=some_text3,p12=20.0|p1=10,p22=20,p3=30,p21=42421212*16.09.2014*11.15,p5=some_text4,p12=45.0'

想要分割和存储这样的数据:

p1     p22     p3            p21                         p5           p12
201   129     5555555555    1234567*22.08.2013*12.00    some_text1    12.0
202   145     4515125       12756624*16.08.2013*15.00   some_text2    16.0
105   103     54658294572   54112124*16.09.2013*11.00   some_text3    20.0
10    20      30            42421212*16.09.2014*11.15   some_text4    45.0

我尝试这样的事情:

declare @xml xml
declare @parse nvarchar(max) = 'p1=201,p22=129,p3=5555555555,p21=1234567*22.08.2013*12.00,p5=some_text1,p12=12.0|p1=202,p22=145,p3=4515125,p21=12756624*16.08.2013*15.00,p5=some_tex2t,p12=16.0|p1=105,p22=103,p3=54658294572,p21=54112124*16.09.2013*11.00,p5=some_text3,p12=20.0|p1=10,p22=20,p3=30,p21=42421212*16.09.2014*11.15,p5=some_text4,p12=45.0'
declare @parse_details TABLE(name varchar(50), [par] varchar(50))
set @parse = REPLACE(@parse,'|',',')

select @xml = '<item><value>'+replace(replace(@parse, '=','</value><value>'), ',','</value></item><item><value>')+'</value></item>'

INSERT INTO @parse_details(name,par)
select N.value('value[1]', 'varchar(50)') as name,
       N.value('value[2]', 'varchar(50)') as [par]
from @xml.nodes('item') as T(N)

    ;WITH cte AS
    (
        SELECT name,par, rn = ROW_NUMBER() OVER(PARTITION BY name ORDER BY par)
        FROM @parse_details
    )

    SELECT 
    p1 = MAX(CASE WHEN name = 'p1' THEN par END)
    ,p22 = MAX(CASE WHEN name = 'p22' THEN par END)
    ,p3 = MAX(CASE WHEN name = 'p3' THEN par END)
    ,p21 = MAX(CASE WHEN name = 'p21' THEN par END)
    ,p5 = MAX(CASE WHEN name = 'p5' THEN par END)
    ,p12 = MAX(CASE WHEN name = 'p12' THEN par END)
    FROM cte
    GROUP BY rn;

但它选择了错误的数据。结果是:

p1  p22 p3             p21                           p5         p12
10  103 30             1234567*22.08.2013*12.00     some_tex2t  12.0
105 129 4515125        12756624*16.08.2013*15.00    some_text1  16.0
201 145 54658294572    42421212*16.09.2014*11.15    some_text3  20.0
202 20  5555555555     54112124*16.09.2013*11.00    some_text4  45.0

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

此脚本以以下格式生成insert into语句:

Insert into mytable values (.....),(....),(.....)



Set @parse = replace(@parse, '|', '),(')
Set @parse = replace(@parse, 'p1=', '')
Do the same for p22 and 03 and so on

Set @parse = 'insert into mytable values (' + @parse + ')'

Exec(@parse)

答案 1 :(得分:0)

我认为这个脚本有效:

;with split_rows as(
select substring(@parse + '|', 1, charindex('|', @parse + '|', 1) - 1) + ',' as f
     , substring(@parse + '|', charindex('|', @parse + '|', 1) + 1, 2147483647) as l
     , 1 as rn
union all
select substring(l, 1, charindex('|', l, 1) - 1) + ',' as f
     , substring(l, charindex('|', l, 1) + 1, 2147483647) as l
     , rn + 1 as rn
  from split_rows
  where charindex('|', l, 1) > 0)
, split_columns as(
select substring(f, 1, charindex(',', f, 1) - 1) as f
     , substring(f, charindex(',', f, 1) + 1, 2147483647) as l
     , rn
  from split_rows
union all
select substring(l, 1, charindex(',', l, 1) - 1) as f
     , substring(l, charindex(',', l, 1) + 1, 2147483647) as l
     , rn
  from split_columns
  where charindex(',', l, 1) > 0)

select [p1], [p22], [p3], [p21], [p5], [p12]
  from (select substring(f, 1, charindex('=', f, 1) - 1) as i
             , substring(f, charindex('=', f, 1) + 1, 2147483647) as v
             , rn
          from split_columns) p
  pivot(max(v) for i in([p1], [p22], [p3], [p21], [p5], [p12])) as pvt
  option (maxrecursion 0)