Разумный / быстрый метод для передачи списков переменных в хранимую процедуру SqlServer2008 - PullRequest
5 голосов
/ 21 апреля 2009

Достаточно сложный запрос мозга нашел тысячу и один способ передать списки параметров переменной длины, которые включают такие методы, как:

Наши требования - передать два списка целых чисел переменной длины (~ максимум 20 дюймов) в хранимую процедуру. Все методы, описанные выше, кажутся смешными.

Это просто так, или это лучше?

Edit: Я только что нашел этот , который может квалифицировать этот вопрос как обман

Ответы [ 2 ]

7 голосов
/ 21 апреля 2009

Да, я бы определенно посмотрел на Таблица значений параметров для этого. Дополнительным преимуществом может быть то, что вы можете использовать красивую, чистую реализацию, основанную на множестве, для внутренних нужд вашей процедуры, без необходимости какого-либо масштабирования данных.

Вот еще одна ссылка , а также ...

1 голос
/ 21 апреля 2009

Вот довольно быстрый способ разделения строк с использованием только T-SQL, а входной параметр - это только строка. Вам необходимо иметь таблицу и функцию (как описано ниже), уже настроенную для использования этого метода.

создать эту таблицу:

CREATE TABLE Numbers (Number  int not null primary key identity(1,1))
DECLARE @n int
SET @n=1
SET IDENTITY_INSERT Numbers ON
WHILE @N<=8000
BEGIN
    INSERT INTO Numbers (Number) values (@n)
    SET @n=@n+1
END
SET IDENTITY_INSERT Numbers OFF

создайте эту функцию для разделения массива строк (у меня есть другие версии, где удаляются пустые разделы и те, которые не возвращают номера строк):

CREATE FUNCTION [dbo].[FN_ListAllToNumberTable]
(
     @SplitOn              char(1)              --REQUIRED, the character to split the @List string on
    ,@List                 varchar(8000)        --REQUIRED, the list to split apart
)
RETURNS
@ParsedList table
(
    RowNumber int             --REQUIRED, the list to split apart
   ,ListValue varchar(500)    --OPTIONAL, the character to split the @List string on, defaults to a comma ","

)
AS
BEGIN

--this will return empty rows, and row numbers
INSERT INTO @ParsedList
        (RowNumber,ListValue)
    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

RETURN

END 
go

Вот пример того, как разделить параметр на части:

CREATE PROCEDURE TestPass
(
    @ArrayOfInts    varchar(255)  --pipe "|" separated list of IDs
)
AS

SET NOCOUNT ON

DECLARE @TableIDs  TABLE (RowNumber int, IDValue int null)

INSERT INTO @TableIDs (RowNumber, IDValue)  SELECT RowNumber,CASE WHEN LEN(ListValue)<1 then NULL ELSE  ListValue END FROM dbo.FN_ListAllToNumberTable('|',@ArrayOfInts)

SELECT * FROM @TableIDs
go

это основано на: http://www.sommarskog.se/arrays-in-sql.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...