アプローチは、本質的にガベージコレクションのアプローチであり、およびトリガーの使用よりも優先される可能性があります。システムの全体的な特性を知らずに、応答性が重要である場合、このアプローチは、所与のレコードの削除に時間を追加しない。言い換えれば、参照されていないリソースを持つリスクは、削除ステップを遅くするリスクよりも低くなります。
このサンプルコードでは、IDを持つテーブルをループし、そのテーブルの孤児を中央の「リソース」テーブルで削除します。
仮定:
- 親テーブルの各がどうにかID列
- リソーステーブル「ファイル」を識別し、その親を見つけることができるためのテーブルを持っています(このサンプルでは、列「テーブル名」があり一例として、ハードコードされた)
(Microsftスクリプトセンターに投稿されました) http://gallery.technet.microsoft.com/scriptcenter/Garbage-Collection-of-a-99594c13
DECLARE @ResourceTableName sysname
SET @ResourceTableName = 'Resource'
--cursor variables
DECLARE @sql nvarchar(max)
DECLARE @primarySchema sysname
DECLARE @primaryTableName sysname
DECLARE @identityColumnName sysname
DECLARE curTableName CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT table_schema, table_name, column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1
AND table_name <> @ResourceTableName
-- loop through tables
OPEN curTableName
FETCH NEXT FROM curTableName
INTO @primarySchema, @primaryTableName, @identityColumnName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = '
DELETE --SELECT *
FROM ' + @ResourceTableName + '
WHERE TableName = ''' + @primaryTableName + '''
AND ParentID NOT IN (
SELECT ' + @identityColumnName + ' FROM ' + @primarySchema + '.' + @primaryTableName + '
)'
--PRINT @sql
EXEC sp_ExecuteSQL @sql
FETCH NEXT FROM curTableName
INTO @primarySchema, @primaryTableName, @identityColumnName
END
-- close a cursor
CLOSE curTableName
DEALLOCATE curTableName
いいえ関係= =(私が知っている)他の唯一のデータベースレベルのオプションは..トリガーです。トリガーコードの大部分が同じである場合(たとえば、テーブルだけが変更されている場合)、自動的に生成されます。別のオプションは、定期的に実行され、特定の保守タスク(孤立したレコードの削除など)を実行する「クリーンアップジョブ」を実行することです。 –
フィードバックに感謝 – daljit