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”上创建触发器,因为目标不在当前数据库中。
这是公平的。有没有办法实现我想要的?
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 - 如果您想更深入地了解它的工作原理,您应该阅读这篇文章。
| 归档时间: |
|
| 查看次数: |
9007 次 |
| 最近记录: |