【问题标题】:MSSQL 2012 Splitting Records Into Multiple RowMSSQL 2012 将记录拆分为多行
【发布时间】:2015-12-07 09:43:19
【问题描述】:

目前我的记录如下。一条完整的记录用管道|分隔,数据用逗号分隔。

 123,870503-23-5370,021|456,830503-23-5371,031|789,870103-11-5372,041|654,870501-23-5373,051|321,880503-12-5374,061|987,870803-23-5375,071|109,870508-06-5376,081|174,810503-03-5377,091|509,870103-01-5378,101|687,870501-12-5379,131

如何将记录拆分成:

C1  C2             C3         
123 870503-23-5370 021
456 830503-23-5371 031
789 870103-11-5372 041
......

【问题讨论】:

    标签: sql sql-server tsql stored-procedures sql-server-2012


    【解决方案1】:

    这种操作应该在应用层进行。

    使用基于| 拆分的快速解决方法:

    declare @S varchar(1000) = '123,870503-23-5370,021|456,830503-23-5371,031|789,870103-11-5372,041|654,870501-23-5373,051|321,880503-12-5374,061|987,870803-23-5375,071|109,870508-06-5376,081|174,810503-03-5377,091|509,870103-01-5378,101|687,870501-12-5379,131'
    

    使用PARSENAME分割到每一列:

    ;WITH cte AS
    (
    select 
    REPLACE(n.r.value('.', 'varchar(500)'), ',','.') As c
    from (select cast('<r>'+replace(@S, '|', '</r><r>')+'</r>' as xml)) as s(XMLCol)
      cross apply s.XMLCol.nodes('r') as n(r)
    )
    SELECT PARSENAME(c,3) AS col1,
           PARSENAME(c,2) AS col2,
           PARSENAME(c,1) AS col3
    FROM cte;
    

    LiveDemo

    输出:

    ╔══════╦════════════════╦══════╗
    ║ col1 ║      col2      ║ col3 ║
    ╠══════╬════════════════╬══════╣
    ║  123 ║ 870503-23-5370 ║  021 ║
    ║  456 ║ 830503-23-5371 ║  031 ║
    ║  789 ║ 870103-11-5372 ║  041 ║
    ║  654 ║ 870501-23-5373 ║  051 ║
    ║  321 ║ 880503-12-5374 ║  061 ║
    ║  987 ║ 870803-23-5375 ║  071 ║
    ║  109 ║ 870508-06-5376 ║  081 ║
    ║  174 ║ 810503-03-5377 ║  091 ║
    ║  509 ║ 870103-01-5378 ║  101 ║
    ║  687 ║ 870501-12-5379 ║  131 ║
    ╚══════╩════════════════╩══════╝
    

    警告:

    当您的字符串包含一些字符(如&lt;&amp;'"&gt;)时,使用 XML 可能会导致问题。

    PARSENAME 用于快速拆分最多 4 个切片。仅适用于不包含 . 字符的数据。

    编辑:

    插入非常简单:

    ;WITH cte AS
    (
    select 
    REPLACE(n.r.value('.', 'varchar(500)'), ',','.') As c
    from (select cast('<r>'+replace(@S, '|', '</r><r>')+'</r>' as xml)) as s(XMLCol)
      cross apply s.XMLCol.nodes('r') as n(r)
    )
    INSERT INTO your_table(col1, col2, col3)
    SELECT PARSENAME(c,3) AS col1,
           PARSENAME(c,2) AS col2,
           PARSENAME(c,1) AS col3
    FROM cte;
    

    【讨论】:

    • 使用Value方法可以克服第一个限制
    • 感谢lad2025的快速回复。您的脚本正在运行。能否展开,以便我可以将结果插入数据库。
    • @SiChiPan 为此使用INSERT
    • 批量插入是当您达到高记录数时最快的加载方式。 XML 解析适用于小容量记录,但当您持续解析大容量数据时,搜索功能就会成为问题。
    【解决方案2】:

    另一种方法是简单地将数据导出到 csv 文件(您可以通过管理工作室轻松完成),然后通过指定字段和记录分隔符使用 BULK INSERT 加载该 csv 文件。如何做到这一点的详细说明可以在这里找到:bulk insert csv

    【讨论】:

      猜你喜欢
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-09
      相关资源
      最近更新 更多