Konteks DB_ID dari tumpukan panggilan lebih jauh

11

Dalam SQL Server, apakah mungkin untuk mendapatkan DB_IDdari konteks dari tumpukan panggilan yang lebih jauh?

Tujuan saya adalah untuk membuat beberapa fungsi utilitas yang berguna (dan memang hacky) dalam database kotak pasir dev yang membuatnya mudah dan ringkas untuk mendapatkan nama objek yang sepenuhnya memenuhi syarat diberi nama pendek atau terfragmentasi, dan juga untuk menghapus objek menggunakan nama pendek yang sama . Fungsi utilitas ini akan berada dalam database utilitas tunggal tetapi dipanggil dari database lain di server yang sama.

Dari apa yang saya lihat dari pengujian:

  • ORIGINAL_DB_NAME()seperti yang dimaksud mengembalikan apa pun yang ada di string koneksi, bukan konteks saat ini (ditetapkan oleh USE [dbname]).
  • Ketika dipanggil dalam suatu fungsi DB_NAME()mengembalikan nama database di mana fungsi itu didefinisikan . Cara lain untuk mengatakan ini adalah bahwa konteks di dalam suatu fungsi atau prosedur tersimpan adalah dari database di mana ia didefinisikan

Saya tahu mesin melacak setiap konteks database naik dan turun dari tumpukan panggilan (lihat di bawah untuk bukti). Jadi adakah cara untuk mengakses informasi ini?

Saya ingin dapat menemukan dan mengoperasikan objek dalam konteks basis data pemanggil, meskipun kode yang dieksekusi tidak ada dalam database yang sama. Sebagai contoh:

use SomeDB
EXEC util.dbo.frobulate_table 'my_table'

Saya tahu saya bisa melakukannya

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

Tapi saya benar-benar ingin tahu apakah mungkin untuk meminta panggilan stack dengan cara ini.

Perbarui / catat

Saya memang membaca dan mengunduh kode dari blog Gabriel McAdams . Ini memberikan catatan ID prosedur panggilan ke atas dan ke bawah tumpukan tetapi masih menganggap semuanya dalam database yang sama.

Bukti SQL Server mengingat konteks DB atas dan ke bawah tumpukan panggilan

Contoh: Pada server dev dengan database TestDB1 dan 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 proc mencetak:

Before, DB_NAME inside dbo.ECHO_STACK : TestDB2
TestDB1.dbo.ECHO_DB_NAME returned     : TestDB1
After, DB_NAME inside dbo.ECHO_STACK  : TestDB2
Joshua Honig
sumber
Itu akan mungkin melalui acara yang diperpanjang tetapi hanya sebagai hal yang benar-benar baru. Bukan sesuatu untuk penggunaan produksi serius. Bahkan jika Anda tahu nama database, bagaimana Anda akan menggunakannya? Memiliki semuanya dalam sql dinamis dengan yang USE xyz;sebelumnya?
Martin Smith
Jujur saya tidak bisa mengatakan saya punya kasus yang kuat mengapa ini perlu . Aku merasa sangat menarik dan jika saya melakukan sosok itu saya akan memasukkannya ke dalam dua procs sedikit berguna saya gunakan dalam saya basis data sandbox dev: Salah satu yang mendapat nama lengkap dari suatu obyek diberikan fragmen dikenali terpendek dari nama (seperti di contoh pertama saya dalam pertanyaan), dan yang lain membunuh objek dengan menggunakan fungsi lain untuk mendapatkan nama lengkap dan juga menggunakan jenis objek yang diidentifikasi untuk menghasilkan DROPpernyataan.
Joshua Honig
@SQLKiwi Pertanyaan diperbarui sesuai. Terima kasih atas jawaban yang lain juga. Saya sudah memiliki berbagai fungsi CLR untuk manipulasi string, jadi ini seharusnya menjadi langkah alami berikutnya bagi saya.
Joshua Honig

Jawaban:

4

Anda tidak dapat melakukan ini dengan fungsi di basis data utilitas. Namun Anda dapat membuat prosedur utilitas di database master, menandainya sebagai objek sistem, dan memanggil mereka dari konteks basis data apa pun di sistem Anda. Artikel dengan contoh yang baik dapat ditemukan di lokasi ini .

nabrond
sumber
Ini novel tapi agak berbahaya. Sangat mudah untuk kehilangan jejak konfigurasi server khusus seperti ini saat Anda bermigrasi ke lingkungan yang berbeda (mis. Server baru atau versi baru dari SQL Server).
Riley Major