sql >> Databáze >  >> RDS >> Sqlserver

Jak získat OBJECT_NAME() z jiné databáze na SQL Server

Pokud budete někdy potřebovat použít OBJECT_NAME() Funkce pro získání názvu objektu z jiné databáze na SQL Serveru, můžete narazit na problémy, pokud nevíte, jak to funguje.

Pravděpodobně víte, že OBJECT_NAME() přijímá object_id argument, který říká serveru SQL Server, ze kterého objektu má získat název.

Co možná víte, ale možná ne, je, že tato funkce přijímá také nepovinné database_id argument, který říká SQL Serveru, která databáze má object_id patří.

Ve výchozím nastavení SQL Server předpokládá object_id je v kontextu aktuální databáze. V tomto případě dotaz, který odkazuje na object_id v jiné databázi vrátí NULL nebo (ještě hůř) nesprávné výsledky.

Příklad 1 – Místní dotaz (z aktuální databáze)

Nejprve je zde místní dotaz, který vrátí název objektu z aktuální databáze:

POUŽÍVEJTE hudbu; VYBERTE název JAKO [Zahraniční klíč], OBJECT_NAME(id nadřazeného_objektu) AS [Název nadřazeného objektu], OBJECT_NAME(id_referencovaného_objektu) AS [Název odkazovaného objektu]FROM Music.sys.foreign_keysWHERE name ='FK_Artists_Country';

Výsledek:

Kontext databáze byl změněn na „Hudba“.+--------------------+----------------- -----+--------------------------+| Cizí klíč | Název nadřazeného objektu | Název odkazovaného objektu ||--------------------+----------------------+- -------------------------|| FK_Artists_Country | Umělci | Země |+--------------------+----------------------+--- -----------------------+ (dotčen 1 řádek)

Tyto výsledky jsou správné.

Toto není dotaz napříč databázemi. Toto je pouze příklad, který ukazuje, jak se tato funkce používá při získávání názvu objektu z aktuální databáze.

Příklad 2 – Dotaz napříč databázemi s NESPRÁVNÝMI VÝSLEDKY!

Nyní je zde dotaz napříč databázemi, který produkuje nesprávné výsledky.

USE WideWorldImportersDW;SELECT name AS [cizí klíč], OBJECT_NAME(parent_object_id) AS [Parent Object Name], OBJECT_NAME(referenced_object_id) AS [Referenced Object Name]FROM Music.sys.foreign_keysWHERE name ='FK_Artists; 

Výsledek:

Kontext databáze byl změněn na 'WideWorldImportersDW'.+--------------------+----------------- -----+-----------------------------+| Cizí klíč | Název nadřazeného objektu | Název odkazovaného objektu ||--------------------+----------------------+- ----------------------------|| FK_Artists_Country | CityKey | PK_Dimension_Payment_Metod |+--------------------+----------------------+--- --------------------------+ (dotčen 1 řádek)

Vše, co jsem udělal, bylo přepnout na jinou databázi a poté znovu spustit stejný dotaz.

Všimnete si, že můj FROM klauzule používá k určení názvu databáze třídílný název (Music ). To umožňuje nalezení správného cizího klíče. To však nestačí k tomu, aby se předešlo problémům.

Jak se ukázalo, WideWorldImportersDW databáze má objekty se stejným object_id které se používají v Music databáze. Jediným problémem je, že jsou to úplně jiné objekty s různými jmény. Takže výsledky v posledních dvou sloupcích jsou falešné. Toto jsou jména nesprávných objektů ve špatné databázi. Můj dotaz napříč databázemi překřížil dráty a vrátil nesprávné objekty!

To je obzvláště nebezpečné, protože kdybych nedával pozor, tyto výsledky by se mohly zdát v pořádku. Koneckonců, chyba se mi nezobrazila.

Pokud by tato ID objektů v této databázi neexistovala, pravděpodobně bych dostal hodnotu NULL (což by mohlo usnadnit zjištění, že s výsledky není něco v pořádku).

Ať tak či onak, výsledek je jednoduše špatný .

Příklad 3 – Dotaz mezi databázemi se SPRÁVNÝMI výsledky

Abychom opravili předchozí příklad (beze změny aktuální databáze), musíme zadat ID databáze, ze které chceme název objektu.

Takhle:

USE WideWorldImportersDW;SELECT name AS [cizí klíč], OBJECT_NAME(parent_object_id, 5) AS [Parent Object Name], OBJECT_NAME(referenced_object_id, 5) AS [Referenced Object Name]FROM Music.sys.foreign_keysWHERE name ='FKArtists;

Výsledek:

Kontext databáze byl změněn na 'WideWorldImportersDW'.+--------------------+----------------- -----+--------------------------+| Cizí klíč | Název nadřazeného objektu | Název odkazovaného objektu ||--------------------+----------------------+- -------------------------|| FK_Artists_Country | Umělci | Země |+--------------------+----------------------+--- -----------------------+ (dotčen 1 řádek)

Opět pro upřesnění, aktuální databáze je WideWorldImportersDW , ale objekty jsou v jiné databázi s názvem Music , který má databázi ID 5.

Příklad 4 – Jak získat ID databáze

Je docela pravděpodobné, že nebudete vědět, jaké ID databáze máte z hlavy. Pravděpodobně budete znát název databáze, ale ne její ID.

Naštěstí můžete použít DB_ID() funkce, která vrátí ID databáze na základě jejího názvu.

Proto můžeme předchozí příklad upravit následovně:

USE WideWorldImportersDW;VYBERTE název JAKO [cizí klíč], OBJECT_NAME(id rodičovského_objektu, DB_ID('Hudba')) AS [Název nadřazeného objektu], OBJECT_NAME(id_objektu odkazu, DB_ID('Hudba')) JAKO [Název odkazovaného objektu]FROM Music.sys.foreign_keysWHERE name ='FK_Artists_Country';

Výsledek:

Kontext databáze byl změněn na 'WideWorldImportersDW'.+--------------------+----------------- -----+--------------------------+| Cizí klíč | Název nadřazeného objektu | Název odkazovaného objektu ||--------------------+----------------------+- -------------------------|| FK_Artists_Country | Umělci | Země |+--------------------+----------------------+--- -----------------------+ (dotčen 1 řádek)

  1. Android – SQLite – ZVOLTE MEZI datem1 A datem2

  2. Jak vytvořit tabulku, pouze pokud v SQLite neexistuje

  3. Postup pro export tabulky do více souborů csv

  4. SQL - Jak vybrat řádek se sloupcem s maximální hodnotou