【问题标题】:Creating a trigger dynamic创建触发器动态
【发布时间】:2010-10-28 17:50:51
【问题描述】:

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

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

如果我尝试使用一个

EXEC('USE dbase
GO
CREATE TRIGGER [blah]
GO')

我明白了:

“GO”附近的语法错误

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

有什么技巧可以避免我的问题吗?

谢谢

【问题讨论】:

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


    【解决方案1】:

    “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]
    ')
    

    【讨论】:

    • 非常感谢!那个帮了我!
    • 或者干脆这样:EXECUTE dbase.sys.sp_sqlexec 'CREATE TRIGGER...'.
    【解决方案2】:

    你可以在调用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
    

    【讨论】:

      【解决方案3】:

      对于动态数据库和动态触发器,无需“更改登录..”使用这种方式

      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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-05
        • 1970-01-01
        • 2012-07-31
        • 2011-09-02
        • 2012-01-12
        • 1970-01-01
        • 1970-01-01
        • 2014-02-02
        相关资源
        最近更新 更多