1

マルチテナントソリューションに取り組んでいます。そのため、SQL Server には多数のデータベースがあります。ロックの問題を調べており、どのロックが待機されているかを確認できる必要があります。

sys.dm_tran_locks動的ビューを照会しましたが、resource_associated_entity_id 列によって参照されるデータベース、オブジェクト、およびインデックス名も含めたいと考えています。これはsys.partitionsテーブルにリンクしていますが、そのテーブルは現在のデータベースの行のみを返し、私が見ているロックは複数のデータベースに分散されています。

カーソルを作成せずに動的に生成されたクエリを使用せずにこの情報を取得する方法はありますか?

4

2 に答える 2

2

短い答え: いいえ、これを回避する方法はありません。sys.partitionsおよび他のデータベース固有のビューは、そのように迷惑です。OBJECT_NAME()オブジェクト全体の場合、データベース ID を使用するため、通常は でこれを回避できます。割り当て ID については、運が悪いです。

技術的に言えば、古い pal を使用してカーソルを自分で作成することを避けることができますsp_msforeachdbが、それは文書化されておらず、通常は希望する形式で結果が得られないため、自分で作成することをお勧めします。

非常に動的であるためsys.dm_tran_locks、必要なときにロック情報を取得するのは簡単ではありません。考えられる代替手段は、プロファイラー トレースまたは拡張イベント セッションを使用して、取得されたロックの正確なシーケンスを取得することです (明らかに、これは大量のデータであるため、特定のクエリをトラブルシューティングする場合にのみこれを行います)。ことわざのたわごとがファンを襲ったときに誰が物事を保持しているかを知ることだけが必要な場合でも、sp_msforeachdb 'dbcc opentran(''?'')'それでも驚くほど効果的です.

于 2014-10-20T16:08:03.067 に答える
2

技術的には「いいえ」。現在のデータベース コンテキストの外部でインデックス名を取得するメタデータ関数はありません。この悲しい事実は、同様に有用な方法で使用しようとすると、次の使用にも悪影響を及ぼします。

したがって、次の 2 つのオプションがあります。

  • 動的 SQL (ご想像のとおり)
  • を含むすべての必要な ID を受け入れ、database_id"context connection = true" を介して接続して目的のシステム ビューを照会する SQLCLR 関数 (これが、SQL#のインデックス名と sys.objects に関してこの問題を解決した方法ですが、 SQLCLR 関数 (スカラーまたは TVF) へのパラメーターとして取り込み、動的に構築された SQL を介してローカルでデータベースに接続する手法はdatabase_id、他のメタデータに対しても同じように機能します)。
    編集
    さらに簡単にするために、データベース名を渡し、それを連結してSqlCommand.CommandTextIDをSqlParametersとして使用します。したがって、署名は、インデックス名を取得するという点では次の
    GetIndexName(@DatabaseName sysname, @object_id INT, @index_id INT)
    ようになり、次のように使用されます。
    GetIndexName(DB_NAME(dmv.database_id), dmv.object_id, dmv.index_id)

参考までに、データベースを指定できるかどうか、または現在のデータベースのみであるかどうかによってグループ化されたメタデータ関数のリストを次に示します。

データベースを指定できます

現在のデータベースのみ

于 2014-10-20T16:08:39.237 に答える