如何在不同的数据库中创建触发器?

And*_*ykh 0 sql-server-2008 sql-server

是否可以创建一个存储过程,在与存储过程本身所在的数据库不同的数据库中创建表触发器 (DDL) 。数据库位于同一服务器实例上。如果是,那么如何?

例如,这不起作用:

create PROCEDURE [dbo].[CreateTriggrer]
  @db varchar(60)
AS
BEGIN
  SET NOCOUNT ON;   
  declare @statement nvarchar(max) = N'CREATE TRIGGER [dbo].[TestTrigger]
   ON  [$database$].[dbo].[TestTable] 
   AFTER INSERT, UPDATE, DELETE
AS 
BEGIN
  PRINT ''test''
END'

    set @statement = REPLACE(@statement,'$database$',@db)
    EXEC dbo.sp_executesql @statement = @statement

END
Run Code Online (Sandbox Code Playgroud)

当这样调用时:

EXEC [dbo].[CreateTriggrer] @db = N'TestDatabase'
Run Code Online (Sandbox Code Playgroud)

它返回此错误:

消息 2108,级别 15,状态 1,过程 TestTrigger,第 6 行
无法在“TestDatabase.dbo.TestTable”上创建触发器,因为目标不在当前数据库中。

这是公平的。有没有办法实现我想要的?

Aar*_*and 7

DECLARE @statement NVARCHAR(MAX) = N'CREATE TRIGGER [dbo].[TestTrigger]
  ON [dbo].[TestTable] 
  AFTER INSERT, UPDATE, DELETE
  AS 
  BEGIN
    PRINT ''test'';
  END';

DECLARE @sql NVARCHAR(MAX) = QUOTENAME(@db) + '.sys.sp_executesql';

EXEC @sql @statement;
Run Code Online (Sandbox Code Playgroud)

这并不完全直观,但它应该可以工作。这是一个更简单的示例,您可以独立测试:

USE [master];
GO
DECLARE @db SYSNAME = N'tempdb';

DECLARE @statement NVARCHAR(MAX) = N'SELECT DB_NAME(), * FROM sys.database_files';

DECLARE @sql NVARCHAR(MAX) = QUOTENAME(@db) + 'sys.sp_executesql';

EXEC @sql @statement;
Run Code Online (Sandbox Code Playgroud)

归功于 Erland Sommarskog - 如果您想更深入地了解它的工作原理,您应该阅读这篇文章