Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Przekaż strukturę listy jako argument do procedury składowanej

Potrzebujesz sposobu na dzielenie i przetwarzanie ciągu w TSQL, jest na to wiele sposobów. W tym artykule omówiono wady i zalety niemal każdej metody:

"Tablice i listy w SQL Server 2005 i nowszych wersjach, gdy parametry wartości tabeli nie Wytnij” autorstwa Erlanda Sommarskoga

Musisz utworzyć funkcję podziału. Oto jak można użyć funkcji podziału:

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

Wolę podejście oparte na tabeli liczb do dzielenia ciągu w TSQL ale istnieje wiele sposobów dzielenia ciągów w SQL Server, zobacz poprzedni link, który wyjaśnia zalety i wady każdego z nich.

Aby metoda tabeli liczb działała, musisz wykonać tę jednorazową konfigurację tabeli, która utworzy tabelę Numbers który zawiera wiersze od 1 do 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)

Po skonfigurowaniu tabeli liczb utwórz tę funkcję podziału:

CREATE FUNCTION [dbo].[FN_ListToTableRows]
(
     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
    ,@List     varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN 
(
    ----------------
    --SINGLE QUERY-- --this will return empty rows, and row numbers
    ----------------
    SELECT
        ROW_NUMBER() OVER(ORDER BY number) AS RowNumber
            ,LTRIM(RTRIM(SUBSTRING(ListValue, number+1, CHARINDEX(@SplitOn, ListValue, number+1)-number - 1))) AS ListValue
        FROM (
                 SELECT @SplitOn + @List + @SplitOn AS ListValue
             ) AS InnerQuery
            INNER JOIN Numbers n ON n.Number < LEN(InnerQuery.ListValue)
        WHERE SUBSTRING(ListValue, number, 1) = @SplitOn
);
GO 

Możesz teraz łatwo podzielić ciąg CSV na tabelę i dołączyć do niego. Aby wykonać swoje zadanie, jeśli możesz przekazać dwa parametry, jeden z kluczy jako jeden z wartości, a następnie utwórz procedurę w następujący sposób:

CREATE PROCEDURE StoredProcedureName
(
     @Params1  int
    ,@Array1   varchar(8000)
    ,@Params2  int
    ,@Array2   varchar(8000)
)
AS 

DECLARE @YourTable table (col1 int, col2 int)

INSERT INTO @YourTable
        (col1, col2)
    SELECT
        a1.ListValue, a2.ListValue
        FROM dbo.FN_ListToTableRows(',',@Array1)            a1
            INNER JOIN dbo.FN_ListToTableRows(',',@Array2)  a2 ON a1.RowNumber=a2.RowNumber

select * from @YourTable

GO

przetestuj to:

exec StoredProcedureName 17,'127,204,110,198',7,'162,170,163,170'

WYJŚCIE:

(4 row(s) affected)
col1        col2
----------- -----------
127         162
204         170
110         163
198         170

(4 row(s) affected)

lub jeśli chcesz przekazać jedną parę klucz-wartość z jednym parametrem, użyj czegoś takiego:

CREATE PROCEDURE StoredProcedureName
(
     @KeyValueList  varchar(8000)
)
AS 

DECLARE @YourTable table (RowKey varchar(500), RowValue varchar(500))

INSERT INTO @YourTable
        (RowKey, RowValue)
    SELECT
        LEFT(y.ListValue,CHARINDEX(',',y.ListValue)-1),RIGHT(y.ListValue,LEN(y.ListValue)-CHARINDEX(',',y.ListValue))
        FROM dbo.FN_ListToTableRows(';',@KeyValueList) y

SELECT * FROM @YourTable

GO

uruchom go:

exec StoredProcedureName 'a,5;b,BBB;abc,xyz'

WYJŚCIE:

RowKey  RowValue
------- -----------
a       5
b       BBB
abc     xyz

(3 row(s) affected)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Konwertuj „datetime2” na „datetimeoffset” w SQL Server (przykłady T-SQL)

  2. Obsługa dialektu SQL 2008 dla NHibernate

  3. Błąd konwersji danych zbiorczego ładowania (obcięcie)

  4. Typowe błędy DBA w MS SQL Server

  5. Pierwszeństwo typów danych w SQL Server