我使用 MS SQL 2008,我想在动态创建的数据库中创建触发器。
创建数据库是在另一个数据库的存储过程中调用的,并且运行良好,但是当我想添加触发器或存储过程时,执行失败。
如果我尝试使用
EXEC('USE dbase
GO
CREATE TRIGGER [blah]
GO')
我得到:
'GO' 附近的语法错误
如果我删除“USE ...”,触发器将在错误的数据库中创建。
有什么技巧可以避免我的问题吗?
谢谢
我使用 MS SQL 2008,我想在动态创建的数据库中创建触发器。
创建数据库是在另一个数据库的存储过程中调用的,并且运行良好,但是当我想添加触发器或存储过程时,执行失败。
如果我尝试使用
EXEC('USE dbase
GO
CREATE TRIGGER [blah]
GO')
我得到:
'GO' 附近的语法错误
如果我删除“USE ...”,触发器将在错误的数据库中创建。
有什么技巧可以避免我的问题吗?
谢谢
“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]
')
您可以在调用 exec 之前切换数据库,并在之后立即切换回来:
use newdb
exec ('CREATE TRIGGER [blah] ...')
use originaldb
或者创建一个链接服务器到正确的数据库,启用 RPC,并且:
EXEC ('CREATE TRIGGER [blah] ...') AT LinkedServerName
或者创建一个不同的用户,该用户在您要创建触发器的数据库中具有默认目录,并且:
EXECUTE AS LOGIN = 'UserName'
EXEC ('CREATE TRIGGER [blah] ...')
REVERT
无需“更改登录 ..” 使用这种方式进行动态数据库和动态触发器
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)