Передача списка в хранимую процедуру не работает - PullRequest
2 голосов
/ 30 ноября 2011

Когда я пытаюсь выполнить этот запрос, он работает:

SELECT *
FROM tbl_Users
WHERE UserId IN (555, 3695, 8787))

Но когда я помещаю это в хранимую процедуру, оно получает значение, только если я передаю один идентификатор. Если я передам больше идентификаторов

Я ничего не получил из базы данных:

CREATE PROCEDURE myStoredProcedure
    @m_UserIdList varchar(500)
AS    
    SELECT u.*, p.*
    FROM tbl_Users u 
    INNER JOIN tbl_Bunker b 
    ON u.BunkerId = b.Bunker
    WHERE u.UserId IN (@m_UserIdList)

Ответы [ 6 ]

4 голосов
/ 30 ноября 2011

Это потому, что ваше select утверждение эквивалентно:

SELECT u.*, p.* 
FROM tbl_Users u  
INNER JOIN tbl_Bunker b ON u.BunkerId = b.Bunker 
WHERE u.UserId IN ('555, 3695, 8787') 

Вы в основном ищете, чтобы узнать, является ли UserId строкой, которая буквально соответствует '555, 3695, 8787', а это не то, что вам нужно.

2 голосов
/ 30 ноября 2011

Акула объяснила это лучше, чем я собиралась.Если я правильно помню, вы можете это сделать, но прошло много времени с тех пор, как мне приходилось делать то, что вы ищете, поэтому я могу ошибаться.

1 голос
/ 30 ноября 2011

Поскольку это не упоминалось, вы можете использовать тип данных XML.

BEGIN
DECLARE @xml XML
SELECT @xml = '<n>1</n><n>2</n><n>3</n>'

SELECT t.n.value('.','int')  FROM @xml.nodes('*') as t(n)
IF 1 IN (SELECT t.n.value('.','int')  FROM @xml.nodes('*') as t(n))
    PRINT('Yep')
IF 4 NOT IN (SELECT t.n.value('.','int')  FROM @xml.nodes('*') as t(n))
    PRINT('It Works')
END

Он не так эффективен, как столбцы с табличными значениями, но его легче настроить / использовать для "вызывающего".

Если у вызывающей стороны уже есть массив или список элементов для преобразования их в XML, он просто должен сделать String.Join с "" в качестве разделителя, тогда, если результирующая строка не пустая, prepend " "и добавить""

1 голос
/ 30 ноября 2011

Да, он обрабатывает @m_UserIdList как одно единственное значение и сравнивает его с u.UserId. Вам нужно разделить значения и проверить их отдельно. Одед опередил меня, но он прав - вы должны использовать табличный параметр. Вот ссылка из Одеда:

http://www.sommarskog.se/arrays-in-sql-2008.html

Этот сайт предлагает множество разных подходов к этой проблеме:

http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm

Один из подходов заключается в использовании динамического SQL, однако вы должны знать об опасностях этого. Прочитайте это сначала:

http://www.sommarskog.se/dynamic_sql.html

Если вы решите пойти по этому пути, что-то вроде этого может сработать:

DECLARE @SQL varchar(600)

SET @SQL = 
'SELECT u.*, p.*
FROM tbl_Users u
    INNER JOIN tbl_Bunker b ON u.BunkerId = b.Bunker
WHERE u.UserId IN (' + @m_UserIdList+ ')'

EXEC(@SQL)  
1 голос
/ 30 ноября 2011

@m_UserIdList - это VARCHAR(500), а не список значений, поэтому это не будет работать. Вы можете попробовать передать переданную строку в таблицу (и для этого существует множество способов - просто выполните поиск по этому сайту).

Однако, поскольку вы используете SQL Server 2008, вам следует взглянуть на табличных параметров - они позволяют передавать таблицу значений в хранимую процедуру.

0 голосов
/ 30 ноября 2011

Вы не можете передать строку значений хранимой процедуре. Самый очевидный ответ - сделать всю строку SQL-запроса динамической, две ссылки должны провести вас через различные другие доступные альтернативы -

http://www.sommarskog.se/arrays-in-sql.html

Параметризация предложения SQL IN

...