Contesto DB_ID dallo stack di chiamate più avanti


11

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 da USE [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

Sarebbe possibile tramite eventi estesi, ma solo come novità davvero. Non qualcosa per un uso produttivo serio. Anche se conosci il nome del database come lo useresti comunque? Hai tutto in sql dinamico con un USE xyz;precedente?
Martin Smith,

Onestamente non posso dire di avere una solida causa del perché questo sarebbe necessario . Ho trovato molto interessante e se io faccio la figura fuori Io porrò in due piccoli proc a portata di mano che uso nel mio database sandbox dev: Uno che prende il nome completo di un oggetto dato il breve frammento riconoscibile del nome (ad esempio in il mio primo esempio nella domanda) e un altro che uccide gli oggetti usando l'altra funzione per ottenere il nome completo e usa anche il tipo di oggetto identificato per generare DROPun'istruzione.
Joshua Honig,

@SQLKiwi Domanda aggiornata di conseguenza. Grazie anche per l'altra risposta. Ho già una varietà di funzioni CLR per la manipolazione delle stringhe, quindi questo dovrebbe essere un passaggio naturale per me.
Joshua Honig,

Risposte:


4

Non è possibile farlo con le funzioni in un database di utilità. È tuttavia possibile creare procedure di utilità nel database master, contrassegnarle come oggetti di sistema e chiamarle dal contesto di qualsiasi database sul sistema. Un articolo con un buon esempio può essere trovato in questa posizione .


Questo è nuovo ma un po 'pericoloso. È facile perdere traccia delle configurazioni personalizzate del server come questa mentre si esegue la migrazione verso ambienti diversi (ad es. Nuovo server o nuova versione di SQL Server).
Riley Major,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.