Переменная имеет область видимости только в том пакете, в котором она находится.Когда вы запускаете динамический SQL, динамический SQL имеет другую область действия, поэтому к переменным нельзя получить доступ, если они находятся в другом.Например, оба следующих оператора сгенерируют ошибку:
DECLARE @SQL nvarchar(MAX) = N'SELECT @i;';
DECLARE @i int = 1;
EXEC (@SQL);
GO
DECLARE @SQL nvarchar(MAX) = N'DECLARE @i int = 1;';
EXEC (@SQL);
SELECT @i;
GO
Если вы используете динамический SQL, вам необходимо передать детали любых переменных в качестве параметров, используя sp_executesql
.Например:
DECLARE @SQL nvarchar(MAX) = N'SELECT @n;';
DECLARE @i int = 1;
EXEC sp_executesql @SQL, N'@n int', @n = @i;
Если вы хотите, чтобы возвращаемые скалярные значения были переменными, используйте параметр OUTPUT
(лично я рекомендую использовать синтаксис {Variable} = EXEC {Expression/Stored Procedure}
, поэтому одна из причин заключается в том, что вы ограничены однимскалярное значение).
Итак, еще раз, как пример:
DECLARE @SQL nvarchar(MAX) = N'SET @a = @n + 1;';
DECLARE @i int = 1, @b int;
EXEC sp_executesql @SQL, N'@n int, @a int OUTPUT', @n = @i, @a = @b OUTPUT;
PRINT @b;