我使用的是MS SQL 2008,我想在动态创建的数据库中创建一个触发器。
在另一个数据库的存储过程中调用创建数据库并完美运行,但是当我想添加触发器或存储过程时,执行失败。
如果我尝试使用
运行dynamiy SQLEXEC('USE dbase
GO
CREATE TRIGGER [blah]
GO')
我明白了:
'GO'附近的语法错误
如果我删除'USE ...',将在错误的数据库中创建触发器。
有没有办法避免我的问题?
THX
答案 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)