Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Übergeben mehrerer Datenzeilen an eine gespeicherte Prozedur

Sie können ganz einfach mehrere Werte aus einer einzelnen Zeichenfolge aufteilen. Angenommen, Sie können die Zeichenfolge wie folgt bündeln, indem Sie ein Komma zum Trennen von "Spalten" und ein Semikolon zum Trennen von "Zeilen" verwenden:

foo, 20120101, 26; bar, 20120612, 32

(Dies setzt voraus, dass Doppelpunkte und Semikolons nicht natürlich in den Daten erscheinen können; wenn dies möglich ist, müssen Sie andere Trennzeichen wählen.)

Sie können eine Split-Routine wie diese erstellen, die eine Ausgabespalte enthält, mit der Sie die Reihenfolge bestimmen können, in der der Wert in der ursprünglichen Zeichenfolge erscheint:

CREATE FUNCTION dbo.SplitStrings
(
    @List       NVARCHAR(MAX),
    @Delimiter  NVARCHAR(255)
)
RETURNS TABLE
AS
    RETURN (SELECT Number = ROW_NUMBER() OVER (ORDER BY Number),
        Item FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@List, Number, 
        CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)))
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
        FROM sys.all_objects) AS n(Number)
    WHERE Number <= CONVERT(INT, LEN(@List))
        AND SUBSTRING(@Delimiter + @List, Number, 1) = @Delimiter
    ) AS y);
GO

Dann können Sie es wie folgt abfragen (zur Vereinfachung und Veranschaulichung behandle ich nur 3 Eigenschaften, aber Sie können dies für 11 oder n extrapolieren):

DECLARE @x NVARCHAR(MAX); -- a parameter to your stored procedure

SET @x = N'foo, 20120101, 26; bar, 20120612, 32';

;WITH x AS 
(
    SELECT ID = s.Number, InnerID = y.Number, y.Item 
    -- parameter and "row" delimiter here:
    FROM dbo.SplitStrings(@x, ';') AS s
    -- output and "column" delimiter here:
    CROSS APPLY dbo.SplitStrings(s.Item, ',') AS y
)
SELECT 
    prop1 = x.Item, 
    prop2 = x2.Item, 
    prop3 = x3.Item
FROM x 
INNER JOIN x AS x2 
ON x.InnerID = x2.InnerID - 1
AND x.ID = x2.ID
INNER JOIN x AS x3
ON x2.InnerID = x3.InnerID - 1
AND x2.ID = x3.ID
WHERE x.InnerID = 1
ORDER BY x.ID;

Ergebnisse:

prop1   prop2     prop3
------  --------  -------
foo     20120101  26
bar     20120612  32