Dalam SQL Server, apakah mungkin untuk mendapatkan DB_ID
dari 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 olehUSE [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
sumber
USE xyz;
sebelumnya?DROP
pernyataan.Jawaban:
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 .
sumber