SQL Server does not allow to create triggers on Temporary tables that included local and global temporary tables.
If you try to create trigger , this is the error you will get.
USE [Database]
GO
--Create SalePerson Table
CREATE TABLE #TempSalePerson(
SalePersonID INT PRIMARY KEY,
FirstName VARCHAR(25),
LastName VARCHAR(25),
)
GO
--Create DML( Insert) Trigger
CREATE TRIGGER dbo.Trg_InsertSalePerson
ON #TempSalePerson
AFTER INSERT AS
BEGIN
SELECT * FROM INSERTED
END
GO
Msg 167, LEVEL 15, State 1, PROCEDURE Trg_InsertSalePerson, Line 2
Cannot CREATE TRIGGER ON a TEMPORARY object.
This is true for local or global temp tables.
The second part of the post is , if You can create Trigger on System tables in SQL Server. That is kind of true. You can create the trigger on system tables in SQL Server. I was able to create trigger on 147 system tables in MSDB and also I created the triggers in Master databases on System Tables. For 5 tables as they have columns data type text, ntext etc. in MSDB , The query threw me error. I might be able to create trigger on those tables as well if I exclude those columns from Trigger Update clause. There could be system tables which do not provide permission to create trigger as well. Further testing is required.
Error I got for 5 Tables in MSDB as my create trigger is more generic as I did not exclude columns of data type such as text, ntext.
Msg 311, LEVEL 16, State 1, PROCEDURE Trg_sysreplicationalerts, Line 7
Cannot USE TEXT, NTEXT, OR IMAGE columns IN the 'inserted' AND 'deleted' tables.
As we learn that we can create the trigger on system table but I am not sure if the trigger fire. There could be some internal code that will not allow the trigger to fire. So If you decided to create a trigger on system table , test that out. My advise will be , don't create the trigger on system tables as they are used by system and we don't have much information about internals.
Script to Create Trigger on All system tables for test purpose
USE [Database]
GO
DECLARE @TableName AS VARCHAR(500)
DECLARE @SchemaName AS VARCHAR(100)
--Create Trigger on System Tables, Trigger will print the statement
--and show the record which got updated.
DECLARE CreateTrigger CURSOR FOR
SELECT name AS TableName,
Schema_name(schema_id) AS SchemaName
FROM sys.tables
WHERE is_ms_shipped = 1
OPEN CreateTrigger
FETCH Next FROM CreateTrigger INTO @TableName, @SchemaName
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL VARCHAR(MAX)=NULL
SET @SQL='CREATE TRIGGER [' + @SchemaName + '].[TrgTest_'
+ @TableName + ']
ON [' + @SchemaName + '].['
+ @TableName + ']
AFTER Update AS
BEGIN
Print ''Trigger Ran Successfully''
SELECT * FROM INSERTED
END'
EXEC (@SQL)
PRINT @SQL
FETCH Next FROM CreateTrigger INTO @TableName, @SchemaName
END
CLOSE CreateTrigger
DEALLOCATE CreateTrigger
Drop triggers on all tables in Database those we created by using above script.
USE [Database]
GO
DECLARE @TriggerName AS VARCHAR(500)
-->Drop or Delete All Triggers in a Database in SQL Server
DECLARE DropTrigger CURSOR FOR
SELECT TRG.name AS TriggerName
FROM sys.triggers TRG
INNER JOIN sys.tables TBL
ON TBL.OBJECT_ID = TRG.parent_id
AND TRG.name LIKE 'TRGTest_%'
OPEN DropTrigger
FETCH Next FROM DropTrigger INTO @TriggerName
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL VARCHAR(MAX)=NULL
SET @SQL='Drop Trigger ' + @TriggerName
PRINT 'Trigger ::' + @TriggerName
+ ' Droped Successfully'
EXEC (@SQL)
PRINT @SQL
FETCH Next FROM DropTrigger INTO @TriggerName
END
CLOSE DropTrigger
DEALLOCATE DropTrigger
If you try to create trigger , this is the error you will get.
USE [Database]
GO
--Create SalePerson Table
CREATE TABLE #TempSalePerson(
SalePersonID INT PRIMARY KEY,
FirstName VARCHAR(25),
LastName VARCHAR(25),
)
GO
--Create DML( Insert) Trigger
CREATE TRIGGER dbo.Trg_InsertSalePerson
ON #TempSalePerson
AFTER INSERT AS
BEGIN
SELECT * FROM INSERTED
END
GO
Msg 167, LEVEL 15, State 1, PROCEDURE Trg_InsertSalePerson, Line 2
Cannot CREATE TRIGGER ON a TEMPORARY object.
This is true for local or global temp tables.
The second part of the post is , if You can create Trigger on System tables in SQL Server. That is kind of true. You can create the trigger on system tables in SQL Server. I was able to create trigger on 147 system tables in MSDB and also I created the triggers in Master databases on System Tables. For 5 tables as they have columns data type text, ntext etc. in MSDB , The query threw me error. I might be able to create trigger on those tables as well if I exclude those columns from Trigger Update clause. There could be system tables which do not provide permission to create trigger as well. Further testing is required.
Error I got for 5 Tables in MSDB as my create trigger is more generic as I did not exclude columns of data type such as text, ntext.
Msg 311, LEVEL 16, State 1, PROCEDURE Trg_sysreplicationalerts, Line 7
Cannot USE TEXT, NTEXT, OR IMAGE columns IN the 'inserted' AND 'deleted' tables.
As we learn that we can create the trigger on system table but I am not sure if the trigger fire. There could be some internal code that will not allow the trigger to fire. So If you decided to create a trigger on system table , test that out. My advise will be , don't create the trigger on system tables as they are used by system and we don't have much information about internals.
Script to Create Trigger on All system tables for test purpose
USE [Database]
GO
DECLARE @TableName AS VARCHAR(500)
DECLARE @SchemaName AS VARCHAR(100)
--Create Trigger on System Tables, Trigger will print the statement
--and show the record which got updated.
DECLARE CreateTrigger CURSOR FOR
SELECT name AS TableName,
Schema_name(schema_id) AS SchemaName
FROM sys.tables
WHERE is_ms_shipped = 1
OPEN CreateTrigger
FETCH Next FROM CreateTrigger INTO @TableName, @SchemaName
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL VARCHAR(MAX)=NULL
SET @SQL='CREATE TRIGGER [' + @SchemaName + '].[TrgTest_'
+ @TableName + ']
ON [' + @SchemaName + '].['
+ @TableName + ']
AFTER Update AS
BEGIN
Print ''Trigger Ran Successfully''
SELECT * FROM INSERTED
END'
EXEC (@SQL)
PRINT @SQL
FETCH Next FROM CreateTrigger INTO @TableName, @SchemaName
END
CLOSE CreateTrigger
DEALLOCATE CreateTrigger
Drop triggers on all tables in Database those we created by using above script.
USE [Database]
GO
DECLARE @TriggerName AS VARCHAR(500)
-->Drop or Delete All Triggers in a Database in SQL Server
DECLARE DropTrigger CURSOR FOR
SELECT TRG.name AS TriggerName
FROM sys.triggers TRG
INNER JOIN sys.tables TBL
ON TBL.OBJECT_ID = TRG.parent_id
AND TRG.name LIKE 'TRGTest_%'
OPEN DropTrigger
FETCH Next FROM DropTrigger INTO @TriggerName
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL VARCHAR(MAX)=NULL
SET @SQL='Drop Trigger ' + @TriggerName
PRINT 'Trigger ::' + @TriggerName
+ ' Droped Successfully'
EXEC (@SQL)
PRINT @SQL
FETCH Next FROM DropTrigger INTO @TriggerName
END
CLOSE DropTrigger
DEALLOCATE DropTrigger
No comments:
Post a Comment