2011-07-12 62 views
-1

我想動態地創建一個觸發器,並需要替換部分的創建語句,特別是連接完成的數據庫名稱。使用變量在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 [(SELECT DB_NAME())].[dbo].[UseType] i ON inserted.[UseTypeID] = i.[UseTypeID] 
END 

我試過這個,但顯然它只是使用它實際上並沒有評估SELECT DB_NAME(文字),有沒有辦法得到它來評估此值。

我正在使用sql 2005/8。我們有一個使用sqlcmd的部署工具,所以後退將是改變工具以接收可以傳遞給sqlcmd的變量,但是如果我可以減少工作量並在腳本本身執行它(會生成)方便。

+0

您不需要DB_NAME(),因爲這將解析爲包含具有此觸發器的表UseType的同一數據庫。然後你寫入觸發器所在的同一張表。你實際想要解決的問題是什麼? – gbn

+0

爲什麼包含數據庫名稱?不應該'dbo.UseType'給你正確的表? –

+0

觸發器與加入數據庫的數據庫不同 –

回答

3

唯一的方法是使用動態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

但DB_NAME()將是包含觸發器和表的相同數據庫。 – gbn

+1

@gbn - 是的,這就是爲什麼它毫無意義。我假設他想爲多個數據庫執行此操作,並且需要類似'sp_msforeachdb' – JNK

+0

@gbn - 根據他的意見 – JNK

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 
+0

但它已經是相同的數據庫了!閱讀關於 – gbn

+0

的問題的意見同意,我只是回答你如何做到這一點。不是應該做還是有任何價值。觸發器中的動態sql可能有類似的有效用法。 – JNappi