sql >> Base de Datos >  >> RDS >> Sqlserver

Pasar varias filas de datos a un procedimiento almacenado

Puede dividir varios valores de una sola cadena con bastante facilidad. Digamos que puede agrupar la cadena de esta manera, usando una coma para separar las "columnas" y un punto y coma para separar las "filas":

foo, 20120101, 26; bar, 20120612, 32

(Esto supone que los dos puntos y los puntos y comas no pueden aparecer de forma natural en los datos; si pueden, deberá elegir otros delimitadores).

Puede crear una rutina dividida como esta, que incluye una columna de salida que le permite determinar el orden en que apareció el valor en la cadena original:

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

Luego puede consultarlo así (por simplicidad e ilustración, solo manejo 3 propiedades, pero puede extrapolar esto para 11 o n):

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;

Resultados:

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