Se você precisar usar o
OBJECT_NAME()
função para obter o nome de um objeto de um banco de dados diferente no SQL Server, você pode ter problemas se não souber como ele funciona. Você provavelmente sabe que
OBJECT_NAME()
aceita um object_id
argumento que informa ao SQL Server de qual objeto obter o nome. O que você pode ou não saber é que esta função também aceita um
database_id
opcional argumento que informa ao SQL Server qual banco de dados o object_id
pertence a. Por padrão, o SQL Server assume que
object_id
está no contexto do banco de dados atual. Nesse caso, uma consulta que faz referência a um object_id
em outro banco de dados retornará NULL ou (pior ainda) resultados incorretos. Exemplo 1 – Consulta local (do banco de dados atual)
Primeiro, aqui está uma consulta local que retorna o nome do objeto do banco de dados atual:
USE Music; SELECT name AS [Foreign Key], OBJECT_NAME(parent_object_id) AS [Parent Object Name], OBJECT_NAME(referenced_object_id) AS [Referenced Object Name] FROM Music.sys.foreign_keys WHERE name = 'FK_Artists_Country';
Resultado:
Changed database context to 'Music'. +--------------------+----------------------+--------------------------+ | Foreign Key | Parent Object Name | Referenced Object Name | |--------------------+----------------------+--------------------------| | FK_Artists_Country | Artists | Country | +--------------------+----------------------+--------------------------+ (1 row affected)
Esses resultados estão corretos.
Esta não é uma consulta entre bancos de dados. Este é apenas um exemplo para mostrar como esta função é usada ao obter o nome de um objeto do banco de dados atual.
Exemplo 2 – Consulta entre bancos de dados com RESULTADOS ERRADOS!
Agora, aqui está uma consulta entre bancos de dados que produz resultados incorretos.
USE WideWorldImportersDW; SELECT name AS [Foreign Key], OBJECT_NAME(parent_object_id) AS [Parent Object Name], OBJECT_NAME(referenced_object_id) AS [Referenced Object Name] FROM Music.sys.foreign_keys WHERE name = 'FK_Artists_Country';
Resultado:
Changed database context to 'WideWorldImportersDW'. +--------------------+----------------------+-----------------------------+ | Foreign Key | Parent Object Name | Referenced Object Name | |--------------------+----------------------+-----------------------------| | FK_Artists_Country | CityKey | PK_Dimension_Payment_Method | +--------------------+----------------------+-----------------------------+ (1 row affected)
Tudo o que fiz foi mudar para um banco de dados diferente e executar a mesma consulta novamente.
Você notará que meu
FROM
cláusula usa um nome de três partes para especificar o nome do banco de dados (Music
). Isso permite que a chave estrangeira correta seja encontrada. No entanto, isso não é suficiente para evitar que problemas ocorram. Acontece que o
WideWorldImportersDW
banco de dados tem objetos com o mesmo object_id
que são usados no Music
base de dados. O único problema é que são objetos completamente diferentes, com nomes diferentes. Portanto, os resultados nas duas últimas colunas são falsos. Esses são os nomes dos objetos errados, no banco de dados errado. Minha consulta entre bancos de dados cruzou os fios e retornou os objetos errados! Isso é particularmente perigoso, porque se eu não estivesse prestando atenção, esses resultados poderiam parecer bons. Afinal, não recebi nenhum erro.
Se esses IDs de objeto não existissem neste banco de dados, eu provavelmente teria obtido um valor NULL (o que pode facilitar a detecção de que algo está errado com os resultados).
De qualquer forma, o resultado é simplesmente errado .
Exemplo 3 – Consulta entre bancos de dados com resultados CORRETOS
Para corrigir o exemplo anterior (sem alterar o banco de dados atual), precisamos fornecer o ID do banco de dados do qual queremos o nome do objeto.
Assim:
USE WideWorldImportersDW; SELECT name AS [Foreign Key], OBJECT_NAME(parent_object_id, 5) AS [Parent Object Name], OBJECT_NAME(referenced_object_id, 5) AS [Referenced Object Name] FROM Music.sys.foreign_keys WHERE name = 'FK_Artists_Country';
Resultado:
Changed database context to 'WideWorldImportersDW'. +--------------------+----------------------+--------------------------+ | Foreign Key | Parent Object Name | Referenced Object Name | |--------------------+----------------------+--------------------------| | FK_Artists_Country | Artists | Country | +--------------------+----------------------+--------------------------+ (1 row affected)
Novamente, apenas para esclarecer, o banco de dados atual é
WideWorldImportersDW
, mas os objetos estão em um banco de dados diferente chamado Music
, que tem um ID de banco de dados de 5. Exemplo 4 – Como obter o ID do banco de dados
É bem provável que você não saiba qual é o ID do banco de dados de cabeça. Você provavelmente saberá o nome do banco de dados, mas não seu ID.
Felizmente você pode usar o
DB_ID()
função para retornar o ID do banco de dados, com base em seu nome. Portanto, podemos modificar o exemplo anterior da seguinte forma:
USE WideWorldImportersDW; SELECT name AS [Foreign Key], OBJECT_NAME(parent_object_id, DB_ID('Music')) AS [Parent Object Name], OBJECT_NAME(referenced_object_id, DB_ID('Music')) AS [Referenced Object Name] FROM Music.sys.foreign_keys WHERE name = 'FK_Artists_Country';
Resultado:
Changed database context to 'WideWorldImportersDW'. +--------------------+----------------------+--------------------------+ | Foreign Key | Parent Object Name | Referenced Object Name | |--------------------+----------------------+--------------------------| | FK_Artists_Country | Artists | Country | +--------------------+----------------------+--------------------------+ (1 row affected)