有人可以提供關於如何爲數據庫中的所有表格插入通用而不是觸發器的源代碼。我想要運行存儲過程,而不是爲db中的所有表創建插入觸發器。而不是在所有表格上插入觸發器
回答
不明白爲什麼你想要在每張表上不用觸發器,除了將提供的值插入基表中之外,你還打算在結果代碼中做什麼(就像發生了什麼,如果有的話)沒有,而不是觸發器),這是我想出的。你會注意到,如果觸發器已經存在,它會丟棄這個觸發器,所以你可以在同一個數據庫中多次運行,而不會出現「already exists」錯誤。它忽略IDENTITY,ROWGUIDCOL,計算列和TIMESTAMP/ROWVERSION列。最後,我將展示如何快速檢查,而不是執行(已註釋掉)輸出腳本(最多8K),並將其轉換爲XML,以便查看更多(最多64K)。不保證你可以在SSMS中返回整個事情,具體取決於有多少表/列。如果你想檢查它並/或者手動運行它,你可能需要創建一個表來存儲這個值 - 然後你可以通過一個應用程序或者你有什麼。現在如果你想讓它自動執行,你可以遵循Yuck的觀點 - 將它保存爲一個存儲過程並創建一個響應某些DDL事件(CREATE TABLE等)的DDL觸發器。
SET NOCOUNT ON;
DECLARE
@cr VARCHAR(2) = CHAR(13) + CHAR(10),
@t VARCHAR(1) = CHAR(9),
@s NVARCHAR(MAX) = N'';
;WITH t AS
(
SELECT [object_id],
s = OBJECT_SCHEMA_NAME([object_id]),
n = OBJECT_NAME([object_id])
FROM sys.tables WHERE is_ms_shipped = 0
)
SELECT @s += 'IF OBJECT_ID(''dbo.ioTrigger_' + t.s + '_' + t.n + ''') IS NOT NULL
DROP TRIGGER [dbo].[ioTrigger_' + t.s + '_' + t.n + '];
G' + 'O
CREATE TRIGGER ioTrigger_' + t.s + '_' + t.n + '
ON ' + QUOTENAME(t.s) + '.' + QUOTENAME(t.n) + '
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
-- surely you must want to put some other code here?
INSERT ' + QUOTENAME(t.s) + '.' + QUOTENAME(t.n) + '
(
' +
(
SELECT @t + @t + name + ',' + @cr
FROM sys.columns AS c
WHERE c.[object_id] = t.[object_id]
AND is_identity = 0
AND is_rowguidcol = 0
AND is_computed = 0
AND system_type_id <> 189
FOR XML PATH(''), TYPE
).value('.[1]', 'NVARCHAR(MAX)') + '--'
+ @cr + @t + ')'
+ @cr + @t + 'SELECT
' +
(
SELECT @t + @t + name + ',' + @cr
FROM sys.columns AS c
WHERE c.[object_id] = t.[object_id]
AND is_identity = 0
AND is_rowguidcol = 0
AND is_computed = 0
AND system_type_id <> 189
FOR XML PATH(''), TYPE
).value('.[1]', 'NVARCHAR(MAX)') + '--'
+ @cr + @t + 'FROM
inserted;
END' + @cr + 'G' + 'O' + @cr
FROM t
ORDER BY t.s, t.n;
SELECT @s = REPLACE(@s, ',' + @cr + '--' + @cr, @cr);
-- you can inspect at least part of the script by running the
-- following in text mode:
SELECT @s;
-- if you want to see more of the whole thing (but not necessarily
-- the whole thing), run this in grid mode and click on result:
SELECT CONVERT(XML, @s);
需要注意幾個問題:
1)我不稀疏列,XML集合,文件流等處理,所以如果你有特殊的表格,你可能會遇到的一些這些功能的併發症。
2)觸發器的名稱沒有真正的「保護」 - 您可以有一個名爲foo的模式,另一個名爲foo_bar的模式,然後foo中的表名爲bar_none,而foo_bar中的表名稱爲none。這會導致重複的觸發器名稱,因爲我使用下劃線作爲分隔符。我對CDC抱怨,但they closed the bug as won't fix。如果您碰巧使用具有下劃線的模式,請注意一點。
這讓我開始了我想要的方向。謝謝。 – Lrn
您只能在SQL Server 2008+中爲DDL語句創建數據庫觸發器。
如果您需要DML觸發器上數據庫中的每個表(INSTEAD OF INSERT
),你將不得不必須要麼自己管理他們或嘗試創建一個數據庫級別的DDL觸發器,負責然後創建或更新任何CREATE
或ALTER
表語句中的INSTEAD OF INSERT
觸發器。會變得毛茸茸的,幾乎肯定會需要使用動態SQL。
出於好奇,你是否想要建立某種審計機制?
如果審計是目標,那麼我懷疑SQL Server Audit,或者至少是CDC或Change Tracking,會是一個不那麼幹擾和有問題的方法。然而,其中一些是版本特定的。 –
@Aaron:在獲得批准之前,不要過於偏離主題,但我個人更喜歡將解決方案放入SQL數據庫。我修改了一個腳本,類似於http://weblogs.asp.net/jgalloway/archive/2008/01/27/adding-simple-trigger-based-auditing-to-your-sql-server-database.aspx很多我自己的項目。當然,你所說的沒什麼錯。 – Yuck
- 1. TSQL觸發器,而不是插入
- 2. 創建而不是插入觸發器
- 3. 插入多行時,觸發器不會觸發所有行SQL
- 4. 插入表作用,而不是INSERT觸發器
- 5. 觸發器更新所有行,不只是插入
- 6. 使用OUTPUT/INTO而不是插入觸發器無效'插入'表
- 7. Sql而不是插入觸發器 - 插入數據如果不存在
- 8. 插入觸發器從表1插入到表格2
- 9. MySQL觸發器 - 在表格1中插入更新表格
- 10. 我有一個在插入表格後觸發的數據庫觸發器。
- 11. EF4 RowCount問題,而不是插入觸發器,而更新其他表
- 12. 插入表的觸發器
- 13. 創建觸發器在所有表上觸發
- 14. 計算列 - 觸發器而不是插入
- 15. SCOPE_IDENTITY而不是插入觸發器解決方案
- 16. 插入多行而不是一個的觸發器
- 17. 表格在插入後觸發器中發生變異
- 18. 如何找到觸發器不存在的所有表格
- 19. Databaselink&而不是觸發器
- 20. sql server而不是觸發器插入語句與變量和值插入
- 21. initialLayoutAttributesForAppearingItemAtIndexPath爲所有可見單元格觸發,而不僅僅是插入的單元格
- 22. SQL而不是觸發器有時不會觸發?
- 23. SQL Server插入後觸發器不復制所有行
- 24. 在表插入創建Oracle觸發器
- 25. 觸發器返回所有行而不是一行的結果
- 26. 插入觸發器時不考慮條件是否觸發
- 27. 總和觸發所有插入的值
- 28. SQL Server觸發器插入整個表的行,而不是新的
- 29. 緩慢加入所插入/刪除觸發器表
- 30. Oracle在插入所有觸發器之前
仍然不明白觸發點。除了將值插入基表中之外,他們還會做什麼? –