Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Предайте списък-структура като аргумент на съхранена процедура

Имате нужда от начин да разделите и обработите низа в TSQL, има много начини да направите това. Тази статия обхваща плюсовете и минусите на почти всеки метод:

"Масиви и списъци в SQL Server 2005 и след това, когато параметрите на стойността на таблицата не Cut it“ от Ерланд Сомарског

Трябва да създадете функция за разделяне. Ето как може да се използва функция за разделяне:

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

Предпочитам подхода на числовата таблица за разделяне на низ в TSQL но има много начини за разделяне на низове в SQL Server, вижте предишната връзка, която обяснява плюсовете и минусите на всеки.

За да работи методът Numbers Table, трябва да направите тази еднократна настройка на таблицата, която ще създаде таблица 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 [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 

Вече можете лесно да разделите CSV низ в таблица и да се присъедините към нея. За да изпълните задачата си, ако можете да подадете два параметъра, един от ключове, един от стойности, след което създайте своята процедура по следния начин:

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

тествайте го:

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

ИЗХОД:

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

(4 row(s) affected)

или ако искате да предадете двойка ключ стойност на един параметър, използвайте нещо подобно:

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

стартирайте го:

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

ИЗХОД:

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. Извличане на SQL релации като низ, разделен със запетая

  2. BUK INSERT в определени колони?

  3. Оптимизиране на Delete на SQL Server

  4. Какъв е еквивалентът на LOCK_ESCALATION =TABLE в SQL Server 2005?

  5. Свържете се към SQL Server чрез IP адрес