sql >> Database teknologi >  >> RDS >> Sqlserver

hvordan opdele og indsætte CSV-data i en ny tabel i en enkelt sætning?

Du har brug for en måde at opdele og behandle strengen i TSQL, der er mange måder at gøre dette på. Denne artikel dækker fordele og ulemper ved næsten alle metoder:

Arrays og lister i SQL Server 2005 and Beyond

Du skal oprette en delt funktion. Sådan kan en split-funktion bruges:

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

Jeg foretrækker taltabeltilgangen til at opdele en streng i TSQL - Brug af en Tabel med tal men der er adskillige måder at opdele strenge på i SQL Server, se det forrige link, som forklarer fordelene og ulemperne ved hver.

For at Numbers Table-metoden skal fungere, skal du udføre denne ene tidtabellsopsætning, som vil oprette en tabel Numbers der indeholder rækker fra 1 til 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)
 

Når taltabellen er sat op, skal du oprette denne opdelingsfunktion:

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 
 

Du kan nu nemt opdele en CSV-streng i en tabel og slutte dig til den:

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

OUTPUT:

Value
----------------------
1
22
333
4444

(4 row(s) affected)
 

for at lave en ny tabel, brug denne:

--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

OUTPUT:

DocumentID  SomeValue
----------- ---------
1           AAA
2           AAA
3           AAA
4           AAA
5           BBBB
6           BBBB

(6 row(s) affected)
 

hvis du ikke ønsker at oprette en Numbers-tabel og kører SQL Server 2005 og nyere, kan du bare bruge denne opdelingsfunktion (ingen Numbers-tabel påkrævet):

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. Forsøger at vise 2 tabeller data

  2. Find posten med maksimal værdi i SQL

  3. Grundlæggende om parallel programmering med Fork/Join Framework i Java

  4. Objektreference, c#