sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo obtener un OBJECT_NAME() de una base de datos diferente en SQL Server

Si alguna vez necesita usar el OBJECT_NAME() para obtener el nombre de un objeto de una base de datos diferente en SQL Server, es posible que tenga problemas si no sabe cómo funciona.

Probablemente sepas que OBJECT_NAME() acepta un object_id argumento que le dice a SQL Server de qué objeto obtener el nombre.

Lo que quizás sepa o no, es que esta función también acepta un database_id opcional. argumento que le dice a SQL Server qué base de datos tiene el object_id pertenece a.

De forma predeterminada, SQL Server asume que object_id está en el contexto de la base de datos actual. En este caso, una consulta que hace referencia a un object_id en otra base de datos devolverá NULL o (aún peor) resultados incorrectos.

Ejemplo 1:consulta local (de la base de datos actual)

Primero, aquí hay una consulta local que devuelve el nombre del objeto de la base de datos actual:

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)

Estos resultados son correctos.

Esta no es una consulta entre bases de datos. Este es solo un ejemplo para mostrar cómo se usa esta función al obtener el nombre de un objeto de la base de datos actual.

Ejemplo 2:¡Consulta entre bases de datos con RESULTADOS INCORRECTOS!

Ahora, aquí hay una consulta de base de datos cruzada que produce resultados incorrectos.

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)

Todo lo que hice fue cambiar a una base de datos diferente y luego ejecutar la misma consulta nuevamente.

Notarás que mi FROM utiliza un nombre de tres partes para especificar el nombre de la base de datos (Music ). Esto permite encontrar la clave externa correcta. Sin embargo, esto no es suficiente para evitar que ocurran problemas.

Resulta que WideWorldImportersDW la base de datos tiene objetos con el mismo object_id que se utilizan en la Music base de datos. El único problema es que son objetos completamente diferentes, con nombres diferentes. Entonces, los resultados en las dos últimas columnas son falsos. Estos son los nombres de los objetos incorrectos, en la base de datos incorrecta. ¡Mi consulta entre bases de datos se cruzó y devolvió los objetos incorrectos!

Esto es particularmente peligroso, porque si no estuviera prestando atención, estos resultados podrían parecer correctos. Después de todo, no recibí ningún error.

Si estos ID de objeto no existieran en esta base de datos, probablemente habría obtenido un valor NULL (lo que podría facilitar la detección de que algo anda mal con los resultados).

De cualquier manera, el resultado es simplemente incorrecto .

Ejemplo 3:consulta entre bases de datos con resultados CORRECTOS

Para corregir el ejemplo anterior (sin cambiar la base de datos actual), debemos proporcionar el ID de la base de datos de la que queremos el nombre del objeto.

Así:

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)

De nuevo, para que quede claro, la base de datos actual es WideWorldImportersDW , pero los objetos están en una base de datos diferente llamada Music , que tiene un ID de base de datos de 5.

Ejemplo 4:cómo obtener el ID de la base de datos

Es muy probable que no sepa cuál es la identificación de la base de datos en la parte superior de su cabeza. Probablemente sabrá el nombre de la base de datos, pero no su ID.

Afortunadamente puedes usar el DB_ID() función para devolver el ID de la base de datos, en función de su nombre.

Por lo tanto, podemos modificar el ejemplo anterior de la siguiente manera:

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)