上位の呼び出しスタックからのDB_IDコンテキスト


11

SQL ServerではDB_ID、コールスタックの上位からコンテキストからを取得できますか?

私の目標は、開発サンドボックスデータベースに便利な(そして確かにハッキーな)ユーティリティ関数を作成して、短い名前または断片化された名前を与えられたオブジェクトの完全修飾名を簡単かつ簡潔に取得し、さらに同じ短い名前を使用してオブジェクトを削除することです。これらのユーティリティ関数は単一のユーティリティデータベースにありますが、同じサーバー上の他のデータベースから呼び出されます。

私がテストから見ることができるものから:

  • ORIGINAL_DB_NAME()意図したとおり、現在のコンテキスト(によって設定USE [dbname])ではなく、接続文字列にあるものを返します。
  • 関数で呼び出されると、その関数が定義されてDB_NAME()いるデータベースの名前を返します。別の言い方をすると、関数またはストアドプロシージャ内のコンテキストは、それが定義されているデータベースのコンテキストです。

エンジンがコールスタックの上下にある各データベースコンテキストを追跡していることを知っています(証明については以下を参照してください)。この情報にアクセスする方法はありますか?

実行中のコードが同じデータベース内にない場合でも、呼び出し元のデータベースのコンテキストでオブジェクトを検索して操作できるようにしたい。例えば:

use SomeDB
EXEC util.dbo.frobulate_table 'my_table'

私はできることを知っています

EXEC util.dbo.frobulate_table 'SomeDB.dbo.my_table'

しかし、この方法でコールスタックをクエリできるかどうかは、私が本当に興味があるだけです。

更新/メモ

Gabriel McAdamsのブログからコードを読んでダウンロードしました。これにより、スタックの上下の呼び出しプロシージャIDの記録が提供されますが、すべてが同じデータベースにあると見なされます。

SQL ServerがDBコンテキストのアップとダウンのコールスタックを記憶していることの証明

例:データベースTestDB1とTestDB2を持つ開発サーバー

use TestDB1
GO
CREATE FUNCTION dbo.ECHO_DB_NAME() RETURNS nvarchar(128) BEGIN RETURN DB_NAME() END
GO

use TestDB2
GO
CREATE PROCEDURE dbo.ECHO_STACK AS 
BEGIN
    DECLARE @name nvarchar(128)
    SET @name = DB_NAME()
    PRINT 'Before, DB_NAME inside dbo.ECHO_STACK : ' + @name
    SET @name = TestDB1.dbo.ECHO_DB_NAME()        
    PRINT 'TestDB1.dbo.ECHO_DB_NAME returned     : ' + @name
    SET @name = DB_NAME()
    PRINT 'After, DB_NAME inside dbo.ECHO_STACK  : ' + @name
END
GO

use master
SELECT DB_NAME()  -- Returns 'master'
EXEC TestDB2.dbo.ECHO_STACK 

ECHO_STACKプロシージャは次を出力します。

Before, DB_NAME inside dbo.ECHO_STACK : TestDB2
TestDB1.dbo.ECHO_DB_NAME returned     : TestDB1
After, DB_NAME inside dbo.ECHO_STACK  : TestDB2

それは、拡張イベントを介して可能ですが、実際には目新しさとしてのみです。本格的な本番用ではありません。データベース名がわかっていても、どうやってそれを使用しますか?動的SQLのUSE xyz;前にすべてが含まれていますか?
マーティン・スミス

正直なところ、なぜこれが必要になるのかについて、確かな理由があるとは言えません。私はそれが非常に興味深い発見し、私があればやるフィギュアそれを私はサンドボックスのdevのデータベースに使用する2つの便利な小さなprocsの中でそれを置く:(などのように名前の最短認識フラグメントを指定されたオブジェクトの完全な名前を取得しますワン質問の私の最初の例)、および別の関数を使用して完全な名前を取得し、識別されたオブジェクトのタイプを使用してDROPステートメントを生成する別の例
Joshua Honig

@SQLKiwi質問はそれに応じて更新されました。他の回答もありがとうございます。文字列操作用のさまざまなCLR関数を既に持っているので、これは私にとって自然な次のステップになるはずです。
Joshua Honig

回答:


4

ユーティリティデータベースの関数を使用してこれを行うことはできません。ただし、マスターデータベースにユーティリティプロシージャを作成し、システムオブジェクトとしてマークを付け、システム上の任意のデータベースのコンテキストから呼び出すことができます。良い例の記事がこの場所にあります。


これは斬新ですが少し危険です。異なる環境(新しいサーバーやSQL Serverの新しいバージョンなど)に移行すると、このようなカスタムサーバー構成を見失う可能性があります。
ライリー少佐
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.