我想提出一個服務器級觸發器,以防止這不是一個數據庫快照任何數據庫的下落。乍一看,下面看起來好像它應該工作,但它從來沒有。我嘗試了扭轉邏輯,並沒有幫助。有誰知道我做錯了什麼?SQL Server觸發器,以防止數據庫中刪除
DECLARE @DBName NVARCHAR(100),
@eventData XML;
SET @eventData = EVENTDATA();
SELECT @DBName = @eventData.value('data(/EVENT_INSTANCE/DatabaseName)[1]', 'SYSNAME');
RAISERROR('Attempting delete of %s.', 10, 1, @DBName);
IF @DBName IN (SELECT name
FROM sys.databases
WHERE source_database_id IS NOT NULL)
BEGIN
RAISERROR('[%s] was successfully dropped.', 10, 1, @DBname) WITH LOG;
END;
ELSE
BEGIN
RAISERROR('[%s] cannot be deleted without first disabling the server trigger "tgr_prevent_db_drop".', 10, 1, @DBname) WITH LOG;
ROLLBACK;
END;
頂部的RAISERROR總是確認正確的數據庫(例如,一個被刪除),當我從sys.databases中運行SELECT手動它總是返回相應的數據。不幸的是,無論我做什麼,它總是落入「真正的數據庫及其數據庫快照」的「..was successfully dropped」部分。
嗨@TheGameIswar,我沒跟蹤。如果數據庫快照,它會在source_database_id列中的值,並出現在SELECT這樣的條件應該永遠是真的,那麼。如果它不是一個快照,source_database_id必須爲NULL,所以我期望它評估爲false。如果我在DDL觸發器之外運行它,它按預期工作。它只在DDL觸發器內失敗。最終,我想允許快照刪除,但防止父數據庫刪除。 – PseudoToad
@PseudoToad的sys.databases中具有基於用戶的權限返回值的問題。如果觸發器沒有在sys.databases中看到快照數據庫,那麼觸發器將作爲無權訪問的用戶執行。 –