2012-12-07 13 views
8

SQL Serverバージョン - 2008 R2の取得SQL Serverのクロスデータベースの依存関係

私はメンテナンスを引き継ぐことを目的に、DMSソリューションの評価に取り組んでいます。元のソリューションには、製造元に関するデータを持つ1つの中央データベースがあります。また、ディーラーごとに1つのデータベースがあります。つまり、多数のデータベース間の依存関係が存在します。

問題:

  • ないDBのドキュメント
  • ないコードがヒープ
  • 多くはありません標準オブジェクトの命名規則
  • コメント中央DBは460+テーブルと900 +ストアドプロシージャを持っています、その他に加えて オブジェクト
  • 各ディーラーDBには370+テーブルと2350+ SProcsがあります最初のステップとして、他の オブジェクト

にnが、私はクロスデータベースの依存関係を含むオブジェクトの依存関係を、理解することが重要であるため、DBの完全なクリーンアップを推奨しています。私はRed Gateのソリューションを使ってみましたが、出力が大きすぎます。私が望むのは、依存関係のないデータベース内のオブジェクトのリストです。他のオブジェクトに依存することも、それに依存するオブジェクトもありません。 - 依存関係を - 私は、各DBから設定されたこの結果を挿入する先の

SELECT 
DB_NAME() referencing_database_name, 
OBJECT_NAME (referencing_id) referencing_entity_name, 
ISNULL(referenced_schema_name,'dbo') referenced_schema_name, 
referenced_entity_name, 
ao.type_desc referenced_entity_type, 
ISNULL(referenced_database_name,DB_NAME()) referenced_database_name 
FROM sys.sql_expression_dependencies sed 
JOIN sys.all_objects ao 
ON sed.referenced_entity_name = ao.name 

私はテーブルを作成します。ここでは

は、私は、依存関係のリストを取得するために使用したスクリプトです。次のステップとして、データベース内のすべてのオブジェクトのリストを含む別のテーブル(AllObjects)を作成します。ここでこれを行うためのスクリプトは次のとおりです。

SELECT 
DB_NAME() DBName, 
name, 
type_desc 
FROM sys.all_objects 
WHERE type_desc IN 
(
'VIEW', 
'SQL_TABLE_VALUED_FUNCTION', 
'SQL_STORED_PROCEDURE', 
'SQL_INLINE_TABLE_VALUED_FUNCTION', 
'USER_TABLE', 
'SQL_SCALAR_FUNCTION' 
) 

さて、依存関係テーブルにreferenced_entity_name列に表示されません。この表から名前のリストは、私が探していますオブジェクトのリストを与える必要があります。

SELECT 
AO.DBName, 
AO.name, 
AO.type_desc 
FROM AllObjects AO 
LEFT OUTER JOIN Dependencies D ON 
D.referenced_database_name = AO.DBName AND 
D.referenced_entity_name = AO.name AND 
D.referenced_entity_type = AO.type_desc 
WHERE 
D.referenced_database_name IS NULL AND 
D.referenced_entity_name IS NULL AND 
D.referenced_entity_type IS NULL 

は今の質問:

  1. いくつかのオブジェクトの依存関係は、出力に欠けているように見えます。私は何ですか がありますか?
  2. 私の発見が正しいことをどのように検証するのですか?
  3. 私はこれを行う別の方法があるので、 の結果と再確認を比較できますか?事前に

おかげで、

ラジ

+0

SYSTEMオブジェクトも気になりますか? –

+0

しかし、type = 'U'はユーザテーブルだけを与えますか?私はまた、他のユーザーが作成したオブジェクトも考慮する必要があります。 – Raj

+0

申し訳ありませんが、 "is_ms_shipped = 0"は2番目のクエリに適しています。これにより、システム固有のオブジェクトが除外されます。 –

答えて

3

ああ、MSはsys.sql_expression_dependenciesでクロスデータベースの依存関係を検出するには良い努力をしたが、私はそれが前に物事を欠場見てきました。あなたのケースでは、依存関係が見つからないという例が見つかり、バックトラッキングを開始します。その場合は、クエリを修正してください。 sys.sql_expression_dependenciesは特定のクラスの依存関係を省略しますか?どのような条件の下で?動的SQLは責任がありますか?等

また、sys.sql_modules内のオブジェクトごとに​​を実行し、コードを再実行する必要があります。これにより、SQL Serverは強制的に依存情報を最新の状態に更新します。

妥当性検査のために、トレースを設定し、イベント114「監査スキーマオブジェクトアクセスイベント」とストアドプロシージャまたはRPCコールの開始および完了イベントを待ち受けます。列を含めるDatabaseNameParentNameObjectNameServerNameSPIDおよびRequestID(MARS対応接続の場合)たぶんいくつかの他の人。オブジェクトのアクセス時に「監査スキーマオブジェクトアクセスイベント」が発生するため、このトレースの実行中にアプリケーションを実行し、SPID + RequestIdを使用してデータを照合し、sys.sql_expression_dependenciesを使用して結果と比較します。依存関係データに表示されないトレースデータに何かがある場合は、何かを見逃してしまいました。

7

結果は、次のスクリプトが検出したものと比較することができます。 ここに完全ですarticle

CREATE PROCEDURE [dbo].[get_crossdatabase_dependencies] AS 

SET NOCOUNT ON; 

CREATE TABLE #databases(
    database_id int, 
    database_name sysname 
); 

INSERT INTO #databases(database_id, database_name) 
SELECT database_id, [name] 
FROM sys.databases 
WHERE 1 = 1 
    AND [state] <> 6 /* ignore offline DBs */ 
    AND database_id > 4; /* ignore system DBs */ 

DECLARE 
    @database_id int, 
    @database_name sysname, 
    @sql varchar(max); 

CREATE TABLE #dependencies(
    referencing_database varchar(max), 
    referencing_schema varchar(max), 
    referencing_object_name varchar(max), 
    referenced_server varchar(max), 
    referenced_database varchar(max), 
    referenced_schema varchar(max), 
    referenced_object_name varchar(max) 
); 

WHILE (SELECT COUNT(*) FROM #databases) > 0 BEGIN 
    SELECT TOP 1 @database_id = database_id, 
       @database_name = database_name 
    FROM #databases; 

    SET @sql = 'INSERT INTO #dependencies select 
     DB_NAME(' + convert(varchar,@database_id) + '), 
     OBJECT_SCHEMA_NAME(referencing_id,' 
      + convert(varchar,@database_id) +'), 
     OBJECT_NAME(referencing_id,' + convert(varchar,@database_id) + '), 
     referenced_server_name, 
     ISNULL(referenced_database_name, db_name(' 
      + convert(varchar,@database_id) + ')), 
     referenced_schema_name, 
     referenced_entity_name 
    FROM ' + quotename(@database_name) + '.sys.sql_expression_dependencies'; 

    EXEC(@sql); 

    DELETE FROM #databases WHERE database_id = @database_id; 
END; 

SET NOCOUNT OFF; 

SELECT * FROM #dependencies; 
+1

データベースがオフラインの場合でも、アクセスしようとするため、エラーが発生する可能性があります。 –

+0

良い点、オフラインデータベースを無視するための行を 'WHERE'フィルタに追加しました^ _ ^ – Oreo