2

テーブルの削除を防止したくはありませんが、特定のテーブルがデータベースに削除された場合は、テーブル全体をバックアップするか、削除する前に行をクエリして特定の行を別のテーブルに選択したいと考えています。

テーブルで通常のトリガーを使用すると、行が削除された場合、「削除済み」テーブルにアクセスして、削除された行にアクセスできます。

DROP_TABLE トリガーは、テーブルが削除された後に起動します。

DROP_TABLE トリガーの Deleted テーブルに相当するものはありますか? 私が使用できる別のアプローチはありますか?または、これらのテーブルを作成および削除する Windows サービスのビジネス ロジックを再コーディングする必要がありますか?

(ドロップをロールバックし、データにアクセスしてコピーアウトし、トリガーを再帰的に起動せずにテーブルを再ドロップするトリガーを書きたくありません。私は独創性が好きですが、これはあまりにも厄介なソリューションです自分)

これを Microsoft SQL Server Enterprise Edition (64 ビット) および Microsoft SQL Server Developer Edition (64 ビット) で実行しています。

4

2 に答える 2

1

助けてくれてありがとう、しかし私自身の質問に直接答えてください:

  1. DDL トリガー (DROP TABLE で起動) の場合、DELETE/UPDATE トリガー内の削除されたテーブルに相当するものはありません。

  2. ドロップをロールバックし、データをコピーして、ドロップを再発行しない限り、同等のソリューションはありません。

  3. 唯一の適切で正しいアプローチは、必要に応じてソフト削除/移動/名前変更を許可するために、これらのテーブルを作成および削除する Windows サービスのビジネス ロジックを再コーディングすることです。

于 2013-01-09T16:24:09.850 に答える
0

気になるのがトリガーの再帰的な発火である場合は、それを確認できます。これは、最初の DROP TABLE に対してのみ実行されます。

alter Trigger ddlt_ProcessDropTable
on all server for drop_table
AS
begin
    if( trigger_nestlevel() = 1 ) -- only run if top level drop table
    begin
        declare @data XML
        set @data = EVENTDATA()
        -- rollback the drop
        rollback;

        -- get table name
        declare @TableName sysname, @SchemaName sysname, @DataBaseName sysname, @Sql nvarchar(1000);
        select 
            @TableName = @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(2000)'),
            @SchemaName = @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'nvarchar(2000)'),
            @DataBaseName = @data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'nvarchar(2000)')

        /****
        Do stuff with the dropped table...
        ****/

        -- re-drop the table
        set @sql = 'Drop Table ' + 
            QuoteName(@DataBaseName) + '.' + QuoteName(@SchemaName) + '.' + QuoteName(@TableName)
        exec(@sql)
    end

end
GO
于 2013-01-09T13:57:21.133 に答える