No SQL Server, é possível obter DB_ID
o contexto mais distante da pilha de chamadas?
Meu objetivo é criar algumas funções úteis (e reconhecidamente hacky) em um banco de dados de sandbox de desenvolvimento que facilite e concise obter os nomes totalmente qualificados dos objetos, com nomes abreviados ou fragmentados, além de excluir objetos usando o mesmo nome abreviado . Essas funções de utilitário estariam em um único banco de dados de utilitário, mas chamado de outros bancos de dados no mesmo servidor.
Pelo que posso ver nos testes:
ORIGINAL_DB_NAME()
como pretendido retorna o que estava na cadeia de conexão, não o contexto atual (definido porUSE [dbname]
).- Quando chamada em uma função,
DB_NAME()
retorna o nome do banco de dados em que a função está definida . Outra maneira de dizer isso é que o contexto dentro de uma função ou procedimento armazenado é o do banco de dados no qual está definido
Sei que o mecanismo controla cada um dos contextos do banco de dados para cima e para baixo na pilha de chamadas (veja a prova abaixo). Então, existe alguma maneira de acessar essas informações?
Quero poder encontrar e operar objetos no contexto do banco de dados do chamador, mesmo que o código em execução não esteja no mesmo banco de dados. Por exemplo:
use SomeDB
EXEC util.dbo.frobulate_table 'my_table'
Eu sei que posso fazer
EXEC util.dbo.frobulate_table 'SomeDB.dbo.my_table'
Mas estou realmente curioso para saber se é possível consultar a pilha de chamadas dessa maneira.
Atualização / observação
Eu li e baixei o código do blog de Gabriel McAdams . Isso fornece um registro do ID do procedimento de chamada para cima e para baixo na pilha, mas ainda assume que tudo está no mesmo banco de dados.
A prova de que o SQL Server lembra a pilha de chamadas para cima e para baixo do contexto do banco de dados
Exemplo: Em um servidor dev com bancos de dados 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
O processo ECHO_STACK imprime:
Before, DB_NAME inside dbo.ECHO_STACK : TestDB2
TestDB1.dbo.ECHO_DB_NAME returned : TestDB1
After, DB_NAME inside dbo.ECHO_STACK : TestDB2
fonte
USE xyz;
precedente?DROP
declaração.Respostas:
Você não pode fazer isso com funções em um banco de dados utilitário. No entanto, você pode criar procedimentos utilitários no banco de dados mestre, marcá-los como objetos do sistema e chamá-los a partir do contexto de qualquer banco de dados no seu sistema. Um artigo com um bom exemplo pode ser encontrado neste local .
fonte