ms sql 由 & 拆分基于数据作为列名 [英] ms sql split by & based on data as a column name

查看:25
本文介绍了ms sql 由 & 拆分基于数据作为列名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在结果"字段的数据集"表中有 4 行,它由与号 (&) 分隔.我想根据字段名称将结果"字段划分为多个字段.如何在 SSIS 或 SQL 中执行此操作?字段名是高亮的.如果没有 .net 脚本也能实现,那就太好了.如果您注意到,字段名称是混乱的.

I have 4 rows in 'dataset' table in 'result' field and it is seperated by ampersand (&). I want to divide 'result' field into multiple fields based on field name. How do I do this in SSIS or SQL? Fieldname are higligtened. It would be nice it can be doable without .net script. If you notice, field names are jumbled.

结果(字段名)

deptid=1 &名字=din &姓氏=kal &中间名=kum

deptid=1 & firstname=din & lastname=kal & middlename=kum

名字=raj &=puli &中间名=kumar &deptid=2

firstname=raj & lastname=puli & middlename=kumar & deptid=2

名字=pavan &=gud &中间名=kumarrao

firstname=pavan & lastname=gud & middlename=kumarrao

deptid=7 &名字=sha &=hank

deptid=7 & firstname=sha & lastname=hank

输出

**deptid**  **firstname**   **lastname**    **middlename**

1               din             kal              kum

2               raj             puli             kumar

                pavan           gud              kumarrao

7               sha             hank     

推荐答案

CROSS APPLY 表格与某种形式的 拆分字符串 函数.使用这些结果创建动态 SQL 命令并执行.将这些结果保留到一个新表中,并DROP 保留旧表.存储这样的数据是不行.

CROSS APPLY the table with some form of split string function. Use these results to create a Dynamic SQL command and execute. Persist these results to a new table and DROP the old one. Storing data like that is not okay.

随机分割字符串:

IF NOT EXISTS ( SELECT  1
                FROM    sys.objects
                WHERE   name = 'SplitString'
                    AND type = 'TF' )
BEGIN
    --DROP FUNCTION dbo.SplitString;
    EXEC( 'CREATE FUNCTION dbo.SplitString() RETURNS @t TABLE ( x BIT ) AS BEGIN RETURN; END' );
END;
GO

ALTER FUNCTION dbo.SplitString 
(
    @String             VARCHAR( MAX ),
    @Delimiter          VARCHAR( 16 )
) RETURNS @Values TABLE
(
    SplitString         VARCHAR( MAX )          
) AS BEGIN
    /*
        dbo.SplitString

        @Param:
        String, the string to be split,
        Delimiter, the delimiter to use.

        @Returns:
        Table, each tuple consisting of a tokenized value of the original string, 
            split by the provided delimiter.  Empty expressions result in NULL values.

        @Example:
        SELECT  *
        FROM    dbo.SplitString( 'This is a test', ' ' );

        SELECT  *
        FROM    dbo.SplitString( NULL, ' ' );       
     */
    DECLARE @i          INTEGER,
            @Split      VARCHAR( MAX ),
            @RowCount   INTEGER;
        SET @RowCount = 0;

        SET @i = -1;        
    WHILE ( LEN( ISNULL( @String, '' ) ) > 0 )
    BEGIN
        SET @String = LTRIM( RTRIM( @String ) );

        SET @i = CHARINDEX( @Delimiter, @String );
        IF ( @i = 0 )
        BEGIN
            INSERT INTO @Values ( SplitString )
            VALUES ( LTRIM( RTRIM( @String ) ) );

            SET @String = '';
        END ELSE BEGIN
            INSERT INTO @Values ( SplitString )
            VALUES ( LTRIM( RTRIM( LEFT( @String, @i - LEN( @Delimiter ) ) ) ) );

            SET @String = RIGHT( @String, LEN( @String ) - @i );
        END;

        SET @RowCount = @RowCount + 1;
    END;  

    IF ( @RowCount = 0 )
    BEGIN
        INSERT INTO @Values ( SplitString )
        VALUES ( NULL );
    END;  

    RETURN;
END;
GO

测试用例:

IF NOT EXISTS ( SELECT  1
                FROM    sys.objects
                WHERE   name = 'DropThisNotAtomicNonsense'
                    AND type = 'U' )
BEGIN
    --DROP TABLE dbo.DropThisNotAtomicNonsense;
    CREATE TABLE dbo.DropThisNotAtomicNonsense
    (
        DropThisNotAtomicNonsense_PK    TINYINT IDENTITY( 1, 1 ) NOT NULL,
                                            PRIMARY KEY ( DropThisNotAtomicNonsense_PK ),
        Result          VARCHAR( MAX )
    );

    INSERT INTO dbo.DropThisNotAtomicNonsense ( Result )
    VALUES  ( 'deptid=1 & firstname=din & lastname=kal & middlename=kum' ),
            ( 'firstname=raj & lastname=puli & middlename=kumar & deptid=2' ),
            ( 'firstname=pavan & lastname=gud & middlename=kumarrao' ),
            ( 'deptid=7 & firstname=sha & lastname=hank' );
END;
GO

解决的问题:

SET NOCOUNT ON;

DECLARE @Cols       VARCHAR( MAX ),
        @SQL        NVARCHAR( MAX );

CREATE TABLE #t_KeyValue
(
    OriginalEntity  TINYINT,
    FieldName       VARCHAR( MAX ),
    FieldValue      VARCHAR( MAX )
);

INSERT INTO #t_KeyValue ( OriginalEntity, FieldName, FieldValue )
SELECT  OriginalEntity = ugh.DropThisNotAtomicNonsense_PK,
        FieldName = LEFT( x.SplitString, CHARINDEX( '=', x.SplitString ) - 1 ),
        FieldValue = RIGHT( x.SplitString, CHARINDEX( '=', REVERSE( x.SplitString ) ) - 1 )
FROM    dbo.DropThisNotAtomicNonsense ugh
CROSS APPLY dbo.SplitString( ugh.Result, '&' ) x;

CREATE TABLE #t_ColumnList
(
    FieldName               VARCHAR( MAX ),
    Processed               TINYINT NOT NULL DEFAULT 0
);

INSERT INTO #t_ColumnList ( FieldName )
SELECT  DISTINCT FieldName
FROM    #t_KeyValue;

IF NOT EXISTS ( SELECT  1
                FROM    sys.objects
                WHERE   name = 'NormalTable'
                    AND type = 'U' )
BEGIN
    --DROP TABLE dbo.NormalTable;
    CREATE TABLE dbo.NormalTable
    (
        NormalTable_PK      TINYINT IDENTITY( 1, 1 ) NOT NULL,
                                PRIMARY KEY ( NormalTable_PK ),
        OriginalEntity      TINYINT
    )

    WHILE EXISTS (  SELECT  1
                FROM    #t_ColumnList
                WHERE   Processed = 0 )
    BEGIN
        SELECT  @SQL = FieldName
        FROM    #t_ColumnList
        WHERE   Processed = 0;

        UPDATE  #t_ColumnList
            SET Processed = 1
        WHERE   FieldName = @SQL;

        SET @SQL = N'
            ALTER TABLE dbo.NormalTable
            ADD [' + REPLACE( @SQL, '''', '' ) + ']     VARCHAR( 128 );'
        EXECUTE dbo.sp_executesql @command = @SQL;
    END;

    SELECT  @Cols = ISNULL( @Cols, '' ) + '[' + FieldName + '], '
    FROM (  SELECT  DISTINCT FieldName
            FROM    #t_KeyValue ) l
        SET @Cols = LEFT( @Cols, LEN( @Cols ) - 1 );

    SET @SQL = N'
        INSERT INTO dbo.NormalTable ( OriginalEntity, ' + @Cols + ' )
        SELECT  OriginalEntity, ' + @Cols + '
        FROM (  SELECT  OriginalEntity, FieldName, FieldValue
                FROM    #t_KeyValue ) s
        PIVOT ( MAX( FieldValue ) FOR
                FieldName IN ( ' + @Cols + ' ) ) p;';
    RAISERROR ( @SQL, 0, 1 ) WITH NOWAIT;
    EXECUTE sp_executesql @command = @SQL;
END;
GO

DROP TABLE #t_ColumnList;
DROP TABLE #t_KeyValue;
GO

SELECT  *
FROM    dbo.NormalTable;
GO

DROP TABLE dbo.DropThisNotAtomicNonsense;
GO

SET NOCOUNT OFF;

现在,有了漂亮的新表,您可以执行 ALTER ... COLUMN 语句以切换到某些 这些列上的正确数据类型.

Now, with your nice, new table, you can perfom ALTER ... COLUMN statements to switch to some proper data types on those columns.

这篇关于ms sql 由 & 拆分基于数据作为列名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆