创建具有特定名称的表时的数据库触发器

Database trigger when a table is created with a particular name

提问人:Seamus 提问时间:4/26/2023 最后编辑:marc_sSeamus 更新时间:4/26/2023 访问量:112

问:

我已经查看(并尝试使用)创建表上的SQL Server 2008触发器,但没有成功。我目前将一个 CSV 文件上传到一个名为 .此文件中的数据使用存储过程 ETL 到另一个表中,然后删除该表。DataTMPDataTMP

我希望实现的是,在创建时,它的创建会触发存储过程的执行,并且在成功执行后,该表将被删除。DataTMPDataTMP

我尝试过的是:

CREATE OR REPLACE TRIGGER trig_DataUpsert 
AFTER CREATE ON SCHEMA
BEGIN
   EXEC usp_data_ETL
   DROP TABLE DataTMP
END

在触发器 CREATE 语句中的“OR”和“ON”处建议错误

我正在使用 SSMS v18I'm using SSMS v18

sql-server 触发器 sql-server-2008-r2 SSMS

评论

2赞 Joel Coehoorn 4/26/2023
您真的在使用 SQL Server 2008 吗?
0赞 marc_s 4/26/2023
在 SSMS 中执行时返回什么?这将是您正在运行的实际服务器版本....SSMS v18.11 只是 GUI 工具 - 而不是数据库引擎 ...SELECT @@VERSION
0赞 Seamus 4/26/2023
Microsoft SQL Server 2008 R2 (SP3) - 10.50.6220
0赞 marc_s 4/26/2023
SQL Server 2008 和 2008 R2 在几年前已结束生命周期,现在完全不受支持。您确实应该考虑升级到受支持的版本。
0赞 Seamus 4/26/2023
哈哈,是的,我知道。唉,我不是钱包的持有者!:-(

答:

1赞 FAB 4/26/2023 #1

我不确定 SQL Server 2008,我没有要测试的实例,但据我所知,DDL 触发器当时也可用。

请尝试这个,或适应你的情况:

--DROP TRIGGER IF EXISTS trig_DataUpsert ON DATABASE
-- alternative for SQL Server 2008, as IF EXISTS wouldn't have been available back then
IF EXISTS (SELECT 1 FROM sys.triggers WHERE [name] = N'trig_DataUpsert' AND [type] = 'TR')
DROP TRIGGER trig_DataUpsert ON DATABASE
GO

CREATE TRIGGER trig_DataUpsert
ON DATABASE
FOR CREATE_TABLE
AS
    DECLARE @tblName NVARCHAR(MAX)
    SELECT @tblName = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(max)')

    IF @tblName = N'DataTMP'
    BEGIN
        PRINT 'EXEC usp_data_ETL'
        DROP TABLE DataTMP
    END
    ELSE
        RETURN

评论

0赞 Seamus 4/26/2023
谢谢你的FAB。我错过了“AS”之后的三行。
0赞 Olesia Dudareva 4/26/2023 #2

如果我从链接的问题中正确理解,则你正在尝试在 SSMS 中使用 PL/SQL (ORACLE)。SQL Server 中没有 CREATE OR REPLACE 语句。 在MSSQL中,只有创建/更改/删除操作。

检查 SQL Server 版本中可用于触发器的更好方法是从模板创建触发器。在对象资源管理器中:数据库/可编程性/数据库触发器/右键单击“新建数据库触发器”。

该模板将如下所示:

USE <database_name, sysname, AdventureWorks>
GO

IF EXISTS(
  SELECT *
    FROM sys.triggers
   WHERE name = N'<trigger_name, sysname, table_alter_drop_safety>'
     AND parent_class_desc = N'DATABASE'
)
    DROP TRIGGER <trigger_name, sysname, table_alter_drop_safety> ON DATABASE
GO

CREATE TRIGGER <trigger_name, sysname, table_alter_drop_safety> ON DATABASE 
    FOR <data_definition_statements, , DROP_TABLE, ALTER_TABLE> 
AS 
IF IS_MEMBER ('db_owner') = 0
BEGIN
   PRINT 'You must ask your DBA to drop or alter tables!' 
   ROLLBACK TRANSACTION
END
GO

只需填写模板,它应该可以工作。

评论

0赞 Seamus 4/26/2023
谢谢 Olesia,我已经用“新数据库触发器”走了这么远,但需要下面提到的三行。我对 ORACLE 报价不好。tbh,这看起来确实很奇怪,因为我之前创建过表触发器,但只是认为在数据库级别它可能会有所不同。没有注意到PL / SQL。谢谢。