在sql触发器创建中使用变量

时间:2011-07-12 01:50:29

标签: sql sql-server tsql triggers

我正在尝试动态创建触发器,需要替换部分create语句,特别是连接完成的数据库名称。

CREATE TRIGGER [dbo].[tr_UseType_update] ON [dbo].[UseType] FOR UPDATE AS
BEGIN
  SET NOCOUNT ON 
  INSERT [dbo].[UseType]
  SELECT 'Updated', i.*
    FROM inserted
   INNER JOIN [(SELECT DB_NAME())].[dbo].[UseType] i ON inserted.[UseTypeID] = i.[UseTypeID]
END

我已经尝试过了,但很明显它只是使用了它实际上没有评估SELECT DB_NAME()的文本,有没有办法让它来评估这个值。

我正在使用sql 2005/8。我们有一个使用sqlcmd的部署工具,因此后备将更改工具以接收可传递给sqlcmd的变量,但是如果我可以减少工作量并在脚本本身(生成)中执行此操作很方便。

2 个答案:

答案 0 :(得分:4)

唯一的方法是使用动态sql。

没有其他方法可以参数化数据库名称或表名。

话虽如此,动态创建这样的触发器似乎是一个危险的想法。

做你想做的最简单的方法就是:

USE MyDataBase

DECLARE @DB varchar(100) = 'MyOtherDatabaseThatIAmJoiningToInTheInsert'
DECLARE @SQL Varchar (MAX)

SET @SQL = '
CREATE TRIGGER [dbo].[tr_UseType_update] ON [dbo].[UseType] FOR UPDATE AS
BEGIN
  SET NOCOUNT ON 
  INSERT [dbo].[UseType]
  SELECT ''Updated'', i.*
    FROM inserted
   INNER JOIN ' + @DB + '.[dbo].[UseType] i ON inserted.[UseTypeID] = i.[UseTypeID]
END'

It's mandatory to read this before doing any dynamic sql code, though!

答案 1 :(得分:0)

您可能会执行动态sql并将其加载到临时表中,而临时表又可用于触发器。

CREATE TRIGGER [dbo].[tr_UseType_update] ON [dbo].[UseType]
    FOR UPDATE
AS
    BEGIN
        SET NOCOUNT ON
        CREATE TABLE #t (userTypeId INT)
        DECLARE @sql NVARCHAR(500) SET @sql = 'insert into #t select userTypeID from ' + DB_NAME() + '.dbo.UseType'
        EXEC sp_executeSQL @sql

        INSERT  [dbo].[UseType]
                SELECT  'Updated',
                        i.*
                FROM    inserted
                        INNER JOIN #t i ON inserted.[UseTypeID] = i.[UseTypeID]
    END