sql >> データベース >  >> RDS >> Sqlserver

TSQL:文字列のテーブルへのネストされた分割/解析(1つの文字列に複数の連結されたタグ:値)

    これは少しブルートフォース機能ですが、機能します... 2つのパラメータを取ります(1つはプライマリデリミタ用、もう1つはセカンダリデリミタ用):

    IF EXISTS ( SELECT * from dbo.sysobjects WHERE id = object_id(N'[dbo].[doubleSplit]') 
                AND OBJECTPROPERTY(id, N'IsTableFunction') = 1 )
        DROP FUNCTION [dbo].[doubleSplit]
    GO
    
    CREATE FUNCTION dbo.doubleSplit ( 
            @sourceString varchar(MAX),
            @primaryDelimiter varchar(100),
            @secondaryDelimiter varchar(100) )
    RETURNS @tblArray TABLE 
       (
        ElementID smallint IDENTITY(1,1),
        Element varchar(MAX),
        Value varchar(MAX)
       )
    AS
    BEGIN
    
        DECLARE @primaryIndex smallint
        DECLARE @secondaryIndex smallint
        DECLARE @primaryStart smallint
        DECLARE @secondaryStart smallint
        DECLARE @primaryDelimiterSize smallint
        DECLARE @seondaryDelimiterSize smallint
        DECLARE @primaryElement varchar(MAX);
        DECLARE @seondaryElement varchar(MAX);
    
        SET @primaryDelimiterSize = LEN(@primaryDelimiter)
        SET @seondaryDelimiterSize = LEN(@secondaryDelimiter)
        --loop through source string and add elements to destination table array
        WHILE LEN(@sourceString) > 0
        BEGIN
            SET @primaryIndex = CHARINDEX(@primaryDelimiter, @sourceString)
            IF @primaryIndex = 0
            BEGIN
                SET @secondaryIndex = CHARINDEX(@secondaryDelimiter, @sourceString)
                IF @secondaryIndex = 0
                BEGIN
                    INSERT INTO @tblArray (Element, Value) VALUES(@sourceString, '')
                END
                ELSE
                BEGIN
                    SET @secondaryStart = @secondaryIndex + @seondaryDelimiterSize;
                    INSERT INTO @tblArray (Element, Value) 
                    VALUES(SUBSTRING(@sourceString, 1, @secondaryIndex - 1), 
                           SUBSTRING(@sourceString, @secondaryIndex + @seondaryDelimiterSize, LEN(@sourceString) - @secondaryStart + 1))
                END
                BREAK
            END
            ELSE
            BEGIN
                SELECT @primaryElement = SUBSTRING(@sourceString, 1, @primaryIndex - 1);
                SET @secondaryIndex = CHARINDEX(@secondaryDelimiter, @primaryElement)
                SET @secondaryStart = @secondaryIndex + @seondaryDelimiterSize;
                INSERT INTO @tblArray (Element, Value) 
                VALUES(SUBSTRING(@primaryElement, 1, @secondaryIndex - 1), 
                       SUBSTRING(@primaryElement, @secondaryIndex + @seondaryDelimiterSize, LEN(@primaryElement) - @secondaryStart + 1))
                SET @primaryStart = @primaryIndex + @primaryDelimiterSize
                SET @sourceString = SUBSTRING(@sourceString, @primaryStart , LEN(@sourceString) - @primaryStart + 1)
            END
        END
    
        RETURN
    END
    GO
    

    次に、このように呼び出して、期待される結果を得ることができます:

    SELECT * FROM dbo.doubleSplit('a-->1,b-->16,x-->99', ',', '-->')
    

    これを返します:

    ElementID   Element Value
    1           a       1
    2           b       16
    3           x       99
    

    そしてこれ:

    SELECT * FROM dbo.doubleSplit('a-->1', ',', '-->')
    

    これを返します:

    ElementID  Element  Value
    1          a        1
    

    など




    1. 特定の状況でこのSQLが結果を返すようにするにはどうすればよいですか?

    2. マクロとは何ですか?どのように使用しますか?

    3. PSQLスクリプト(bashスクリプトから供給)の変数として外部XMLファイルにアクセスする

    4. MySQL +コードファースト+遅延読み込みの問題!