在SQL Server中拆分行和列并插入临时表?

时间:2015-01-23 12:24:52

标签: c# sql sql-server

我在特定表的一列中有数据,其格式如下:

item1 char(1) value1 char(1) value2 char(0) item2 char(1) value3 char(1) value4 char(0)

注意:

char(0)char(1)以及角色本身。也没有空格。

我需要做的是拆分原始表的列:

  1. 首先使用char(0)
  2. 拆分成行
  3. 然后使用char(1)
  4. 再次拆分(1)中的每一行

    结果应该是一个包含2个列和x行的表:

    column1 column2 colum3
    ----------------------
    item1   value1  value2
    item2   value3  value4
    

    我正在写一个CLR函数来分割数据:

    public partial class Functions
    {
        public static IEnumerable SplitData(SqlString value)
        {
            string[] rows = value.Value.Split('\n');
    
            for (int i = 0, n = rows.Length; i < n; i++)
            {
    
            }
    
            return rows;
        }
    }
    

    每行都包含文本,例如:

    item char(1) value1 char(1) value2
    

    第二步是拆分每一行(这很容易)。

    但是该函数如何返回上面的表,以便可以在SQL服务器中进一步处理?

2 个答案:

答案 0 :(得分:0)

我认为实现这一目标的最简单方法是将分割功能创建为clr。在.NET中,您将可以访问具有良好性能的更好的字符串函数工具集。如果你在t-sql中执行它可能会获得更好的性能。

答案 1 :(得分:0)

测试表和数据:

DECLARE @t table(id int identity(1,1), col1 varchar(max))
insert @t values
('item'+char(1)+ 'value1'+char(1)+'value4'+char(1)+char(0)+ 'item'+char(1)+'value1'+char(1)+ 'value2'+char(1)+char(0)),
('item'+char(1)+ 'value1'+char(1)+'value2'+char(1)+char(0)+ 'item2'+char(1)+'value1'+char(1)+ 'value2'+char(1)+char(0))

查询:

;WITH SplitByRow as
(
        SELECT id, t.c.value('.', 'VARCHAR(2000)') colx
        FROM (
            SELECT id, x = CAST('<t>' + 
                REPLACE(REPLACE(col1, char(1), '!new row!'), char(0), '</t><t>') + '</t>' AS XML)
        FROM @t
        ) a
        CROSS APPLY x.nodes('/t') t(c)
), SplitByColumn as
(
  SELECT 
    id,
    (row_number() over (order by (select 1))+2)/3 rowx, 
    (row_number() over (order by (select 1))+2)%3 colx,
    t.c.value('.', 'VARCHAR(2000)') value
    FROM 
    (
        SELECT id, x = CAST('<t>' + 
            REPLACE(colx, '!new row!', '</t><t>') + '</t>' AS XML)
        FROM SplitByRow
    ) a
    CROSS APPLY x.nodes('/t') t(c)
    WHERE t.c.value('.', 'VARCHAR(2000)') <> ''
)
SELECT 
  id, [0] col1,[1] col2,[2] col3
FROM 
  SplitByColumn 
INTO 
  #temp
PIVOT
    (min([value]) FOR colx
    in([0],[1],[2])  
)AS p

结果:

SELECT * FROM #temp

id  col1    col2    col3
1   item    value1  value4
1   item    value1  value2
2   item    value1  value2
2   item2   value1  value2