In SQL Server, è possibile ottenere DB_IDdal contesto più lontano dallo stack di chiamate?
Il mio obiettivo è quello di creare alcune utili funzioni (e certamente hacky) utilità in un database dev sandbox che rendano facile e conciso ottenere i nomi completi degli oggetti dati i loro nomi brevi o frammentati e inoltre eliminare gli oggetti usando lo stesso nome breve . Queste funzioni di utilità si troverebbero in un unico database di utilità ma venivano chiamate da altri database sullo stesso server.
Da quello che posso vedere dai test:
ORIGINAL_DB_NAME()come previsto restituisce tutto ciò che era nella stringa di connessione, non il contesto corrente (impostato daUSE [dbname]).- Quando viene chiamata in una funzione
DB_NAME()restituisce il nome del database in cui è definita quella funzione . Un altro modo di dire questo è che il contesto all'interno di una funzione o di una procedura memorizzata è quello del database in cui è definito
So che il motore tiene traccia di ciascuno dei contesti del database su e giù per lo stack di chiamate (vedi sotto per la prova). Quindi c'è un modo per accedere a queste informazioni?
Voglio essere in grado di trovare e operare su oggetti nel contesto del database del chiamante, anche se il codice di esecuzione non si trova nello stesso database. Per esempio:
use SomeDB
EXEC util.dbo.frobulate_table 'my_table'
So di poterlo fare
EXEC util.dbo.frobulate_table 'SomeDB.dbo.my_table'
Ma sono davvero curioso di sapere se è possibile interrogare lo stack di chiamate in questo modo.
Aggiornamento / nota
Ho letto e scaricato il codice dal blog di Gabriel McAdams . Ciò fornisce una registrazione dell'ID della procedura di chiamata su e giù per lo stack ma presuppone comunque che tutto sia nello stesso database.
La prova che SQL Server ricorda lo stack di chiamate su e giù per il contesto DB
Esempio: su un server di sviluppo con database TestDB1 e 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
Il proc ECHO_STACK stampa:
Before, DB_NAME inside dbo.ECHO_STACK : TestDB2
TestDB1.dbo.ECHO_DB_NAME returned : TestDB1
After, DB_NAME inside dbo.ECHO_STACK : TestDB2
DROPun'istruzione.
USE xyz;precedente?