T-SQL: невозможно передать конкатенированную строку в качестве аргумента хранимой процедуры
Сценарий:
Необходимо передать n аргументов хранимой процедуре. Один из аргументов имеет тип varchar(x)
. Этот аргумент varchar должен быть построен из нескольких других переменных varchar. Эта проблема использует SQL Server 2005, но это поведение относится ко всем версиям SQL Server.
Настройка
DECLARE @MyString varchar(500), @MyBar varchar(10), @MyFoo varchar(10)
SELECT @MyBar= 'baz '
SELECT @MyFoo= 'bat '
-- try calling this stored procedure!
EXEC DoSomeWork @MsgID, 'Hello ' + @MyBar + '" world! "' + @MyFoo + '".'
Это создает исключение в SQL Server: Incorrect syntax near '+'
. Как правило, вы можете подумать, что тип данных будет неправильным (т.е. Переменные имеют разные типы, но это приведет к появлению другого сообщения об ошибке).
Здесь правильная реализация, которая компилируется без ошибок:
SELECT @MyString= 'Hello ' + @MyBar + '" world! "' + @MyFoo + '".';
EXEC DoSomeWork @ID, @MyString
Вопрос: Почему заключается в том, что T-SQL не может обрабатывать конкатенацию varchar в качестве аргумента? Он знает типы, поскольку они были объявлены правильно как varchar.
Ответы
Ответ 1
Оператор EXECUTE просто имеет другую грамматику, а затем другие выражения, такие как SELECT и SET. Например, обратите внимание на раздел синтаксиса в верхней части следующих двух страниц.
EXECUTE: http://msdn.microsoft.com/en-us/library/ms188332.aspx
Оператор SET: http://msdn.microsoft.com/en-us/library/ms189484.aspx
Синтаксис EXECUTE принимает только значение
[[@parameter =] { значение | @variable [ВЫХОД] | [ИСХОДНЫЕ]]
В то время как синтаксис SET принимает выражение
{@local_variable = выражение}
Значение в основном просто жестко закодированная константа, но выражение будет оцениваться. Это похоже на наличие varchar 'SELECT 1 + 1'. Это просто значение варчара прямо сейчас. Однако вы можете оценить строку следующим образом:
EXEC('SELECT 1 + 1')
Я полагаю, что все, что я указываю, заключается в том, что команда EXEC не позволяет выражений по определению, которые вы, по-видимому, уже выяснили. Я не знаю, каковы намерения разработчиков T-SQL, когда они это сделали. Я предполагаю, что грамматика просто выйдет из-под контроля, если вам разрешено бросать подзапросы в подзапросы в списке параметров хранимой процедуры.
Выражение T-SQL: http://msdn.microsoft.com/en-us/library/ms190286.aspx
Ответ 2
Вы не можете сделать что-то вроде этого
exec SomeProc getdate()
вы должны поместить все это в параметр, как вы делаете в нижнем запросе
Это может быть потому, что оно не детерминировано (по крайней мере для функций)
Ответ 3
Это ограничение для инструкции EXEC. Подробнее см. Проклятие и благословения динамического SQL.