0

他の誰かからプロジェクトを継承したばかりで、DB 内のすべての関係の依存関係を特定する簡単な方法があるかどうか疑問に思っていました。これにより、開発者のコ​​ピーを作成するために本番環境からデータの大部分を簡単に削除できますが、残りのアカウントの関係はそのままです。

4

1 に答える 1

1

これにより、「テンプレート SQL」が正しい順序で提供されます。

ただし、欠落している where 句を埋める必要があります (簡単ではありません)。

;
with    cteTableHierarchy 
          as ( /* Select all table without (selfreferencing) FK */
               select distinct
                        1 as LevelID
                      , OBJECT_SCHEMA_NAME(Parent.object_id) as TableOwner
                      , Parent.name as TableName
                      , Parent.object_id as TbObjID

               from     sys.objects Parent
               left join sys.foreign_key_columns RefKey
                        On RefKey.parent_object_id = Parent.object_id
                           and RefKey.parent_object_id <> RefKey.referenced_object_id
                           and RefKey.constraint_column_id = 1
               where    RefKey.parent_object_id is null
                        and Parent.type = 'U'
                        and Parent.name <> 'dtproperties'
               UNION ALL
               /* add tables that reference the anchor rows */
               SELECT   H.LevelID + 1
                      , OBJECT_SCHEMA_NAME(Parent.object_id) as TableOwner
                      , OBJECT_NAME(Parent.object_id) as TableName
                      , Parent.object_id as TbObjID
               from     sys.objects Parent
               inner join sys.foreign_key_columns RefKey
                        On RefKey.parent_object_id = Parent.object_id
                           and RefKey.parent_object_id <> RefKey.referenced_object_id
                           and RefKey.constraint_column_id = 1
               inner join cteTableHierarchy H
                        on H.TbObjID = RefKey.referenced_object_id 
               where    Parent.type = 'U'
                        and Parent.name <> 'dtproperties'
             )
    select distinct *    , TemplateSQL = 'Delete from [' + TableOwner + '].[' + TableName + '] Where .... '
    from    cteTableHierarchy
    order by LevelID desc -- descending order = order of row deletes
          , TableOwner
          , TableName ;

編集 ........................

「Select *」をコメントアウトし、「Delete deleteAlias」のコメントを外して、実際に削除を実行します。この小さなシンタックス シュガー (Select * vs "Delete deleteAlias") の良い点は、実際に "Delete deleteAlias" を削除しようとしている正確なデータを (select * 経由で) すぐに確認できることです。

以下は、小さな @Holder 変数テーブルを設定します。次に、3 つのテーブルを逆にたどります.......データを削除します。

最後のテーブル (dbo.[Customers] deleteAlias から) には冗長/不要なコードが含まれていますが、「簡潔さ」よりも概念を示そうとしています。

Use Northwind
Go




/* Example to Delete all Order-Details, Orders, Customers based on a known list of CustomerID's */

declare @CustomerIDHolder table ( CustomerID char(5) )
INSERT INTO @CustomerIDHolder ( CustomerID )
Select 'ALFKI' union all select '33333'


--Delete deleteAlias 
  Select * 
from dbo.[Order Details] deleteAlias
where exists 
    ( select null from dbo.[Orders] innerOrds join dbo.Customers innerCusts on innerOrds.CustomerID = innerCusts.CustomerID 
        where
        /* exists inner to outer relationshiop */
        innerOrds.OrderId = deleteAlias.OrderId
        and
        /* filter */
        exists ( Select null from @CustomerIDHolder innerInnerHolder where innerInnerHolder.CustomerID = innerCusts.CustomerID )
  )


--Delete deleteAlias 
  Select * 
from dbo.[Orders] deleteAlias
where exists 
    ( select null from dbo.Customers innerCusts
        where
        /* exists inner to outer relationshiop */
        innerCusts.CustomerID = deleteAlias.CustomerID
        and
        /* filter */
        exists ( Select null from @CustomerIDHolder innerInnerHolder where innerInnerHolder.CustomerID = innerCusts.CustomerID )
  )


--Delete deleteAlias 
  Select * 
from dbo.[Customers] deleteAlias
where exists 
    ( select null from dbo.Customers innerCusts
        where
        /* exists inner to outer relationshiop */
        innerCusts.CustomerID = deleteAlias.CustomerID
        and
        /* filter */
        exists ( Select null from @CustomerIDHolder innerInnerHolder where innerInnerHolder.CustomerID = innerCusts.CustomerID )
  )

そして、これが「残したいものをマークし、残りを削除する」例です........

/* Example to Delete all Order-Details, Orders, Customers based on a known list of CustomerID's */

declare @CustomerIDHolder table ( CustomerID char(5) )
INSERT INTO @CustomerIDHolder ( CustomerID )
Select CustomerID from dbo.Customers

/* Keep all the data except for 2 Customers.  Aka, The Customers who do NOT exist in the holder table will be deleted.... */
Delete deleteAliasHolder From @CustomerIDHolder deleteAliasHolder where exists ( Select CustID from (Select 'ALFKI' as CustID union all select '33333' as CustID ) as derived1 where derived1.CustID = deleteAliasHolder.CustomerID )

Select CustomerID as DataToKeepCustomerID from @CustomerIDHolder 

--Delete deleteAlias 
  Select * 
from dbo.[Order Details] deleteAlias
where exists 
    ( select null from dbo.[Orders] innerOrds join dbo.Customers innerCusts on innerOrds.CustomerID = innerCusts.CustomerID 
        where
        /* exists inner to outer relationshiop */
        innerOrds.OrderId = deleteAlias.OrderId
        and
        /* filter */
        not exists ( Select null from @CustomerIDHolder innerInnerHolder where innerInnerHolder.CustomerID = innerCusts.CustomerID )
  )


--Delete deleteAlias 
  Select * 
from dbo.[Orders] deleteAlias
where exists 
    ( select null from dbo.Customers innerCusts
        where
        /* exists inner to outer relationshiop */
        innerCusts.CustomerID = deleteAlias.CustomerID
        and
        /* filter */
        not exists ( Select null from @CustomerIDHolder innerInnerHolder where innerInnerHolder.CustomerID = innerCusts.CustomerID )
  )


--Delete deleteAlias 
  Select * 
from dbo.[Customers] deleteAlias
where exists 
    ( select null from dbo.Customers innerCusts
        where
        /* exists inner to outer relationshiop */
        innerCusts.CustomerID = deleteAlias.CustomerID
        and
        /* filter */
        not exists ( Select null from @CustomerIDHolder innerInnerHolder where innerInnerHolder.CustomerID = innerCusts.CustomerID )
  )
于 2013-05-23T17:46:55.110 に答える