Я пытаюсь динамически создавать триггеры, но столкнулся с запутанной проблемой, sp_executesql
с использованием sp_executesql
и передачей параметров в динамический SQL. Следующий простой тестовый пример работает:
DECLARE @tableName sysname = 'MyTable';
DECLARE @sql nvarchar(max) = N'
CREATE TRIGGER TR_' + @tableName + N' ON ' + @tableName + N' FOR INSERT
AS
BEGIN
PRINT 1
END';
EXEC sp_executesql @sql
Однако я хочу иметь возможность использовать @tableName
(и другие значения) в качестве переменных в скрипте, поэтому я передал его вызову sp_executesql
:
DECLARE @tableName sysname = 'ContentItems';
DECLARE @sql nvarchar(max) = N'
CREATE TRIGGER TR_' + @tableName + N' ON ' + @tableName + N' FOR INSERT
AS
BEGIN
PRINT @tableName
END';
EXEC sp_executesql @sql, N'@tableName sysname', @[email protected]
При запуске выше, я получаю ошибку:
Сообщение 156, уровень 15, состояние 1, строка 2
Неверный синтаксис рядом с ключевым словом "TRIGGER".
После нескольких попыток я обнаружил, что даже если я вообще не использую @tableName
в динамическом SQL, я все равно получаю эту ошибку. И я также получаю эту ошибку, пытаясь создать PROCEDURE
(за исключением, очевидно, сообщение неправильный синтаксис рядом с ключевым словом "ПРОЦЕДУРА".)
Так как SQL работает нормально либо напрямую, либо когда не передаются параметры для sp_executesql
, похоже, что я столкнулся с настоящим ограничением в механизме SQL, но я нигде не вижу его документированного. Кто-нибудь знает, есть ли способ принять динамический скрипт CREATE
, или, по крайней мере, иметь представление о лежащем в основе ограничении?
Обновление Я могу добавить оператор PRINT
и получить приведенный ниже SQL, который является действительным и успешно выполняется (при непосредственном запуске). Я все еще получаю сообщение об ошибке, если в SQL нет ничего динамического (это просто одна строка без конкатенации).
CREATE TRIGGER TR_ContentItems ON ContentItems FOR INSERT
AS
BEGIN
PRINT @tableName
END
Я также получаю ту же ошибку, используя sysname
или nvarchar(max)
для параметра.