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()

вы должны поместить все это в параметр, как вы делаете в нижнем запросе Это может быть потому, что оно не детерминировано (по крайней мере для функций)