创建触发器动态

时间:2009-05-25 12:56:38

标签: sql sql-server stored-procedures triggers dynamic-sql

我使用的是MS SQL 2008,我想在动态创建的数据库中创建一个触发器。

在另一个数据库的存储过程中调用创建数据库并完美运行,但是当我想添加触发器或存储过程时,执行失败。

如果我尝试使用

运行dynamiy SQL
EXEC('USE dbase
GO
CREATE TRIGGER [blah]
GO')

我明白了:

  

'GO'附近的语法错误

如果我删除'USE ...',将在错误的数据库中创建触发器。

有没有办法避免我的问题?

THX

4 个答案:

答案 0 :(得分:3)

“GO”不是T-SQL语言。它是由SSMS等客户端工具解释为关键字分隔符(意思是“将文本发送到服务器”)。

现在,CREATE TRIGGER必须是批处理中的第一个语句,因此不能使用“USE dbname”。

如果在EXEC之前提到“USE dbnname”,那么它可能会在默认数据库中用于连接。你必须测试(我现在不能,对不起)

--Might work
USE dbase
EXEC ('CREATE TRIGGER [blah]
')

或者您必须使用sqlcmd或osql来连接和运行代码:这允许您在连接上设置db上下文。但不在T-SQL中。

或者您可以在EXEC之前尝试ALTER LOGIN xxx WITh DEFAULT_DATABASE = dbname

ALTER LOGIN xxx WITH DEFAULT_DATABASE = dbname 
--Now the EXEC will connect to default db if above approach fails
EXEC('CREATE TRIGGER [blah]
')

答案 1 :(得分:0)

您可以在调用exec之前切换数据库,然后在之后切换回来:

use newdb
exec ('CREATE TRIGGER [blah] ...')
use originaldb

或者使用RPC enalbed创建一个链接服务器到正确的数据库,并且:

EXEC ('CREATE TRIGGER [blah] ...') AT LinkedServerName

或者在数据库中创建一个具有默认目录的其他用户,您可以在其中创建触发器:

EXECUTE AS LOGIN = 'UserName'
EXEC ('CREATE TRIGGER [blah] ...')
REVERT

答案 2 :(得分:0)

创建仅验证存在的引用,然后使用alter。

进行修改
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[MiTrigger]') AND type in (N'TR'))
    EXEC ('CREATE TRIGGER [MiTrigger] ON [dbo].[MiTabla] FOR DELETE AS SET NOCOUNT ON')
GO

答案 3 :(得分:0)

动态数据库和动态触发器无需“Alter Login ..”使用这种方式

set @db = 'XXX'
set @sql = 'use [' + @db + ']; 

exec (''CREATE TRIGGER [dbo].[Trigger1] ON dbo.Table1
    FOR UPDATE, INSERT, DELETE
    AS
    BEGIN
        SET NOCOUNT ON;
        /*your code*/
    END;'')'

exec (@sql)