Я бы настоятельно рекомендовал не использовать динамический SQL с именами таблиц.Вы настраиваете себя на серьезные проблемы с SQL-инъекцией.Вы должны проверить все, что входит в переменную @tableName
.
Тем не менее, в вашем примере ...
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', @tableName=@tableName
... вы пытаетесь ввести объявленный @tableName
в текст, который вы создаете для @sql
, итогда вы пытаетесь передать параметр через spexecutesql
.Это делает ваш @sql
недействительным при попытке вызвать его.
Вы можете попробовать:
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', @tableName=@tableName
..., что даст вам строку ...
'
CREATE TRIGGER TR_' + @tableName + N' ON ' + @tableName + N' FOR INSERT
AS
BEGIN
PRINT @tableName
END'
..., которая затем может принять параметр, который выпройти через ...
EXEC sp_executesql @sql, N'@tableName sysname', @tableName=@tableName ;
Опять же, я бы использовал некоторую тщательную проверку (и белый список) перед передачей чего-либо в динамический SQL, который будет использовать имя динамической таблицы.
ПРИМЕЧАНИЕ. Как отмечено ниже, я полагаю, что вы ограничены в операторах DML, которые могут выполняться с sp_executesql()
, и я думаю, что параметризация также ограничена.И, основываясь на других ваших комментариях, звучит не так, как будто вам действительно нужен динамический процесс, а способ повторить определенную задачу для нескольких элементов.Если это так, я рекомендую сделать это вручную с помощью копирования / вставки, а затем выполнить операторы.