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

CSVデータを分割して1つのステートメントで新しいテーブルに挿入する方法は?

    TSQLで文字列を分割して処理する方法が必要です。これを行うには、さまざまな方法があります。この記事では、ほぼすべての方法の長所と短所について説明します。

    SQLServer2005以降の配列とリスト

    分割関数を作成する必要があります。分割関数の使用方法は次のとおりです。

    SELECT
        *
        FROM YourTable                               y
        INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value
    

    TSQLで文字列を分割するために数値テーブルアプローチを使用する数字の表 ただし、SQLServerで文字列を分割する方法は多数あります。それぞれの長所と短所を説明している前のリンクを参照してください。

    Numbers Tableメソッドを機能させるには、この1回限りのテーブル設定を行う必要があります。これにより、テーブルNumbersが作成されます。 1から10,000までの行が含まれています:

    SELECT TOP 10000 IDENTITY(int,1,1) AS Number
        INTO Numbers
        FROM sys.objects s1
        CROSS JOIN sys.objects s2
    ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
    

    Numbersテーブルを設定したら、次の分割関数を作成します。

    CREATE FUNCTION inline_split_me (@SplitOn char(1),@param varchar(7998)) RETURNS TABLE AS
       RETURN(SELECT substring(@SplitOn + @param + ',', Number + 1,
                        charindex(@SplitOn, @SplitOn + @param + @SplitOn, Number + 1) - Number - 1)
                     AS Value
              FROM   Numbers
              WHERE  Number <= len(@SplitOn + @param + @SplitOn) - 1
                AND  substring(@SplitOn + @param + @SplitOn, Number, 1) = @SplitOn)
    
    GO 
    

    CSV文字列をテーブルに簡単に分割して結合できるようになりました:

    select * from dbo.inline_split_me(';','1;22;333;4444;;') where LEN(Value)>0
    

    出力:

    Value
    ----------------------
    1
    22
    333
    4444
    
    (4 row(s) affected)
    

    新しいテーブルを作成するには、これを使用します:

    --set up tables:
    DECLARE @Documents table (DocumentID varchar(500), SomeValue varchar(5))
    INSERT @Documents VALUES ('1,2,3,4','AAA')
    INSERT @Documents VALUES ('5,6'    ,'BBBB')
    
    DECLARE @NewDocuments table (DocumentID int, SomeValue varchar(5))
    
    --populate NewDocuments
    INSERT @NewDocuments
        (DocumentID, SomeValue)
    SELECT
        c.value,a.SomeValue
        FROM @Documents    a
            CROSS APPLY dbo.inline_split_me(',',a.DocumentID) c
    
     --show NewDocuments contents:
    select * from @NewDocuments
    

    出力:

    DocumentID  SomeValue
    ----------- ---------
    1           AAA
    2           AAA
    3           AAA
    4           AAA
    5           BBBB
    6           BBBB
    
    (6 row(s) affected)
    

    Numbersテーブルを作成せず、SQL Server 2005以降を実行している場合は、この分割関数を使用できます(Numbersテーブルは必要ありません):

    CREATE FUNCTION inline_split_me (@SplitOn char(1),@String varchar(7998))
    RETURNS TABLE AS
    RETURN (WITH SplitSting AS
               (SELECT
                    LEFT(@String,CHARINDEX(@SplitOn,@String)-1) AS Part
                        ,RIGHT(@String,LEN(@String)-CHARINDEX(@SplitOn,@String)) AS Remainder
                    WHERE @String IS NOT NULL AND CHARINDEX(@SplitOn,@String)>0
                UNION ALL
                SELECT
                    LEFT(Remainder,CHARINDEX(@SplitOn,Remainder)-1)
                        ,RIGHT(Remainder,LEN(Remainder)-CHARINDEX(@SplitOn,Remainder))
                    FROM SplitSting
                    WHERE Remainder IS NOT NULL AND CHARINDEX(@SplitOn,Remainder)>0
                UNION ALL
                SELECT
                    Remainder,null
                    FROM SplitSting
                    WHERE Remainder IS NOT NULL AND CHARINDEX(@SplitOn,Remainder)=0
               )
               SELECT Part FROM SplitSting
           )
    GO
    


    1. Oracleテーブルの列を行番号で更新します

    2. JavaからSageに接続する

    3. BLOBをOracleデータベース内の他のBLOBと比較します

    4. エイリアスとしてのMysql動的値