C# 在SQL server中拆分行和列并插入到临时表中?

C# 在SQL server中拆分行和列并插入到临时表中?,c#,sql,sql-server,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)以及字符本身。也没有空间 我需要做的是拆分原始表的列: 使用char(0) 然后使用char(1) 结果应该是一个包含2列和x行的表: column1 column2 colum3 ---------------------- item1

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

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

char(0)
char(1)
以及字符本身。也没有空间

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

  • 使用
    char(0)
  • 然后使用
    char(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;
        }
    }
    
    第二步是拆分每一行(这很容易)


    但是函数如何返回上面的表,以便在SQL server中进一步处理它呢?

    我认为实现这一点最简单的方法是将分割函数创建为clr。在.NET中,您可以访问性能更好的StringFunction工具集。可能比您在t-sql中使用时获得的性能更好。

    测试表和数据:

    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
    

    请添加测试数据和预期结果您熟悉pivto/unpivot吗?我在MSSQL上找到了它,我现在无法测试它:-(,这里的链接是诱惑修复的吗?或者它可以不同吗?@Jaques它是存储过程的本地内存表。
    ;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