Note: My intention with this question was to learn about approaches other than mine, to execute multiple CREATE TRIGGER statements in a single string. Not "solving" this, by executing one by one, is not the requirement. No need to use temporary tables, while loops, cursors, etc. I hope someone else can benefit from this post, although it has had a strangely negative and unfortunate reception.
I want to dynamically create many triggers in the same script, but it fails, do you know any way to achieve this?
Try the following script:
declare @commands varchar(max) = '
drop table if exists dbo.Countries
drop table if exists dbo.Cities
create table dbo.Countries(
id int identity not null primary key,
Country varchar(50) not null
)
create table dbo.Cities(
id int identity not null primary key,
City varchar(50) not null
)
'
print @commands
/* This execution works well */
execute (@commands)
go
declare @commands varchar(max) = '
create trigger tr_Countries on
dbo.Countries for insert as
begin
print ''A new country was created.''
end
create trigger tr_Cities on
dbo.Cities for insert as
begin
print ''A new city was created.''
end
'
print @commands
/* This execution fails:
Msg 156, Level 15, State 1, Procedure tr_Countries, Line 8 [Batch Start Line 20]
Incorrect syntax near the keyword 'trigger'.
*/
execute (@commands)
As you can see, the two batches are very similar, but the first one runs successfully and the second one fails.
The idea is to apply this pattern to metadata maintenance:
- Select the objects to be processed
- Create commands over those objects with a query
- Compile the commands list into a string
- Execute dynamically the commands string
declare @Commands varchar(max)
/* You get a list of objects that meet your requirements,
normally it will be a query with multiple tables and conditions */
;with QueryObjectsYouNeed as (
select 'Table_01' TableName union all
select 'Table_02' TableName union all
select 'Table_03'
),
/* With those objects create the commands */
CommandsList as (
select 'drop table if exists ' + TableName Command
from QueryObjectsYouNeed
)
/* Compile the commands into a string */
select @Commands = string_agg(cast(Command as varchar(max)), char(13))
from CommandsList
print @Commands
/* Execute dynamically the commands string */
Execute(@Commands)
Another way is to use a table variable or a temporary table, store the commands in it, and then iterate the list to execute each command one at a time.