I think that way you can get what you want:
CREATE TABLE [log]
(
Id UNIQUEIDENTIFIER CONSTRAINT log_Id_DF DEFAULT(NEWID()) NOT NULL
, [Timestamp] DATETIME CONSTRAINT log_Timestamp_DF DEFAULT(GETDATE()) NOT NULL
, Tabela NVARCHAR(255) NOT NULL
, Colunas NVARCHAR(MAX) NOT NULL
, PRIMARY KEY (Id)
)
DECLARE @SQL AS NVARCHAR(MAX) = ''
DECLARE cur_trigger CURSOR FOR
SELECT '
CREATE TRIGGER [' + TABLE_SCHEMA + '].[tr' + TABLE_NAME + '_auto]
ON [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] FOR INSERT, UPDATE, DELETE AS
BEGIN
DECLARE @IdTabela INT
DECLARE @Tabela NVARCHAR(255)
DECLARE @Colunas NVARCHAR(MAX)
SELECT @Tabela = object_name(parent_id)
FROM sys.triggers
WHERE object_id = @@PROCID
SELECT @IdTabela = T.id
FROM sysobjects P JOIN sysobjects T ON P.parent_obj = T.id
WHERE P.id = @@PROCID
SELECT @Colunas = ISNULL(@Colunas + '', '', '''') + name
FROM syscolumns
WHERE id = @IdTabela
AND CONVERT(VARBINARY, REVERSE(COLUMNS_UPDATED())) & POWER(CONVERT(BIGINT, 2), colorder - 1) > 0
INSERT INTO [log](Tabela, Colunas) VALUES(@Tabela, @Colunas)
END
'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME <> 'log'
ORDER BY TABLE_NAME
OPEN cur_trigger
FETCH NEXT FROM cur_trigger INTO @SQL
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC(@SQL)
FETCH NEXT FROM cur_trigger INTO @SQL
END
CLOSE cur_trigger
DEALLOCATE cur_trigger
Basically uses dynamic SQL to build trigger
and then just run.
In terms of syntax is correct, but has not been tested in your scenario.
Some ideas taken from SOen : SQL Server Update Trigger, Get Only Modified Fields
To query all triggers
of a database, you can do the following:
SELECT *
FROM sys.triggers
WHERE [type] = 'TR'
ORDER BY [name]