T-SQL Проблема при передаче строки CSV в хранимую процедуру - PullRequest
0 голосов
/ 21 июля 2010

У меня есть та процедура, которая возвращает строки, связанные по ID с переданным аргументом, т.е. 1,5,7,9

ALTER PROCEDURE [dbo].[get_data]
 @MyCodes as varchar(max) = ''
AS
BEGIN
 DECLARE @query as nvarchar(max)

 set @query = 'SELECT name FROM user WHERE id IN (@p_MyCodes)'

 exec SP_EXECUTESQL @query,
                        N'@p_MyCodes varchar(max)', 
                        @p_MyCodes = @MyCodes
END

Эта процедура выдает ошибку: Ошибка преобразования типа данных varchar в числовой. при передаче в качестве аргумента, например, 3,7,5

Что не так?

Ответы [ 3 ]

3 голосов
/ 21 июля 2010

Я не думаю, что это достигнет того, чего вы ожидаете.Ошибка, которую вы получаете, заключается в том, что она не может преобразовать строку «3,7,5» в число (обратите внимание, что она НЕ пытается анализировать ваши индивидуальные значения).

Два способа получить то, чтоВы хотите:

1) Создать функцию табличного значения, которая принимает строку CSV и возвращает результаты (я уверен, что их много в Интернете; вот связанный вопрос: Эквивалентная функция разделения на T-SQL ).Это хорошо, потому что вы можете полностью избавиться от вызова sproc SP_EXECUTESQL;Ваш запрос:

SELECT name FROM user where id IN (SELECT value FROM dbo.f_Split(@p_MyCodes))

2) Измените ваш набор на что-то вроде:

set @query = 'SELECT name FROM user WHERE id in (' + @p_MyCodes + ')'

Я не рекомендую # 2, он предлагает дыру для SQL-инъекций.

1 голос
/ 21 июля 2010

Вы не можете передать список ID в качестве параметра.Вы можете создать оператор SQL, конкатенируя:

set @query = 'SELECT name FROM user WHERE id IN (' + @MyCodes + ')'
exec SP_EXECUTESQL @query

Хотя это отключает любое повторное использование плана выполнения и включает внедрение SQL

Лучшим решением было бы разделить список на:временная таблица (или табличная переменная) и использование JOIN.В прошлом году я написал сообщение в блоге о различных способах разделения строк в T-SQL: http://florianreischl.blogspot.com/2009/09/high-performance-string-split-functions.html

0 голосов
/ 21 июля 2010

Вы не можете использовать запятую с оператором in, вы должны использовать фактические значения. Итак, вам нужно либо разбить строку и поместить значения во временную таблицу, либо объединить строку в запросе:

set @query = 'SELECT name FROM user WHERE id IN (' + @p_MyCodes + ')'

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

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