2017-12-02 93 views
0

我有一個非常簡單的觸發器,複製當前行的「FOR UPDATE ... SELECT * FROM刪除」 觸發複製到表有兩個額外的列

  • AuthorsAuthorID(PK)AuthorNameBio

  • AuthorsHistoryHistoryID(PK)AuthorIDAuthorNameBiohWhen(dateTime)

hWhen使用getDate()填寫其值。

CREATE TRIGGER [dbo].[AuthorHistory] 
ON [dbo].[B_Authors] 
FOR UPDATE 
AS 
    INSERT INTO B_AuthorsHistory 
     SELECT * 
     FROM deleted 

有更多的列,但他們無關緊要。所有列都是相同的類型,相同的空設置,相同的默認值,而不是PK更改。

它完美的工作,但今天我想添加一列。

  • 我試圖將它添加到Authors,它立即拋出一個錯誤,關於觸發器中的列表列表。 (我正在使用Select *
  • 我加了第一列到AuthorsHistory,再次嘗試Authors,並且它直接提到觸發器拋出了一個不同的錯誤。

我找到解決方法,刪除了扳機,調整列,添加了扳機,但我也不得不刪除從AuthorsHistory暫時hWhen(這是不是現在的問題,還是構建它)。

另一種選擇很可能是針對列名和值。 我在代碼中這樣做,但我喜歡這樣的想法,即使我可以避免更新,也無需更新。

問題:有沒有一種方法,我可以用SELECT * **我有一個相同的觸發(即「Products ==> ProductsHistory」)上的其他表也這麼做?

+1

不要使用SSMS設計器來添加你的列,如果你只是使用TSQL,你應該可以將它們添加到兩個表中。例如http://rextester.com/NNIWQN4856 –

+0

好的,謝謝。 @MartinSmith –

回答

1

依我之見,一個新的列添加到兩個表,從而使觸發不會失敗的唯一辦法,是做一個查詢這樣的:

;disable trigger dbo.AuthorHistory on dbo.B_Authors; 

alter table dbo.B_Authors add NewColumn int null; 

alter table dbo.B_AuthorsHistory add NewColumn int null; 

;enable trigger dbo.AuthorHistory on dbo.B_Authors; 

但是,如果你有高如果任何其他事務會在查詢過程中更改dbo.Authors中的數據,則可能會丟失dbo.AuthorsHistory中的一些數據。

+1

我的解釋是他們在添加列時不是通過併發執行來看到這一點。這將通過SSMS重新創建表格(使用新的柱狀圖),然後在更改後觸發(現在不同步)來解釋。希望他們不會使用SSMS表格設計師來改變生產。 –

+0

我同意。無論如何,最好不要使用'select *'。 – GriGrim

+0

審計觸發器是個人對「SELECT *」感到滿意的案例。這意味着如果你添加一個新的列到基表中,幾乎不可能忘記把它添加到歷史表中(因爲你會因爲不匹配而導致運行時錯誤) –