sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man hämtar ett OBJECT_NAME() från en annan databas i SQL Server

Om du någonsin behöver använda OBJECT_NAME() funktion för att hämta ett objekts namn från en annan databas i SQL Server, kan du stöta på problem om du inte vet hur det fungerar.

Du vet förmodligen att OBJECT_NAME() accepterar ett object_id argument som talar om för SQL Server vilket objekt namnet ska hämtas från.

Vad du kanske vet eller inte vet är att den här funktionen också accepterar ett valfritt database_id argument som talar om för SQL Server vilken databas object_id tillhör.

Som standard antar SQL Server att object_id är i sammanhanget med den aktuella databasen. I det här fallet, en fråga som refererar till ett object_id i en annan databas kommer att returnera NULL eller (ännu värre) felaktiga resultat.

Exempel 1 – Lokal fråga (från aktuell databas)

Först, här är en lokal fråga som returnerar objektnamnet från den aktuella databasen:

ANVÄND musik;VÄLJ namn SOM [Främmande nyckel], OBJECT_NAME(parent_object_id) AS [Parent Object Name], OBJECT_NAME(referenced_object_id) AS [Referenced Object Name]FRÅN Music.sys.foreign_keysWHERE name ='FK_Artists_Country';
>

Resultat:

Ändrade databaskontext till "Musik".+-------------------------+---------------- -----+---------------------------------+| Utländsk nyckel | Namn på överordnat objekt | Refererat objektnamn ||------------------------+----------------------------+- --------------------------|| FK_Artister_Land | Konstnärer | Land |+--------------------+---------------------+--- -----------------------+(1 rad påverkad)

Dessa resultat är korrekta.

Detta är inte en korsdatabasfråga. Detta är bara ett exempel för att visa hur den här funktionen används när man hämtar ett objekts namn från den aktuella databasen.

Exempel 2 – Korsdatabasfråga med FEL RESULTAT!

Nu, här är en korsdatabasfråga som ger felaktiga resultat.

ANVÄND WideWorldImportersDW;VÄLJ namn SOM [Främmande nyckel], OBJECT_NAME(parent_object_id) AS [Parent Object Name], OBJECT_NAME(referenced_object_id) SOM [Referenced Object Name]FRÅN Music.sys.foreign_keysWHERE name ='FK'Artists; 

Resultat:

Ändrade databaskontext till 'WideWorldImportersDW'.+-------------------------+----------------- -----+------------------------------------+| Utländsk nyckel | Namn på överordnat objekt | Refererat objektnamn ||------------------------+----------------------------+- ----------------------------|| FK_Artister_Land | CityKey | PK_Dimension_Payment_Method |+-------------------+-----------------------------+--- --------------------------+(1 rad påverkad)

Allt jag gjorde var att byta till en annan databas och sedan köra samma fråga igen.

Du kommer att märka att min FROM sats använder ett tredelat namn för att ange namnet på databasen (Music ). Detta gör att rätt främmande nyckel kan hittas. Detta är dock inte tillräckligt för att förhindra att problem uppstår.

Som det visar sig är WideWorldImportersDW databasen har objekt med samma object_id som används i Music databas. Det enda problemet är att de är helt olika objekt, med olika namn. Så resultaten i de två sista kolumnerna är falska. Det här är namnen på fel objekt, på fel databas. Min korsdatabasfråga har fått sina trådar korsade och returnerat fel objekt!

Detta är särskilt farligt, för om jag inte var uppmärksam, kan dessa resultat tyckas vara OK. Jag fick trots allt inget felmeddelande.

Om dessa objekt-ID:n inte fanns i den här databasen, skulle jag förmodligen ha fått ett NULL-värde (vilket kan göra det lättare att upptäcka att något är fel med resultaten).

Hur som helst är resultatet helt enkelt fel .

Exempel 3 – Korsdatabasfråga med KORREKT resultat

För att fixa det föregående exemplet (utan att ändra den aktuella databasen), måste vi ange ID:t för databasen som vi vill ha objektets namn från.

Så här:

ANVÄND WideWorldImportersDW;VÄLJ namn SOM [Främmande nyckel], OBJECT_NAME(parent_object_id, 5) SOM [Prent Object Name], OBJECT_NAME(referenced_object_id, 5) AS [Referenced Object Name]FRÅN Music.sys.foreign_keys_WHERE artistnamn ='FKry;

Resultat:

Ändrade databaskontext till 'WideWorldImportersDW'.+-------------------------+----------------- -----+---------------------------------+| Utländsk nyckel | Namn på överordnat objekt | Refererat objektnamn ||------------------------+----------------------------+- --------------------------|| FK_Artister_Land | Konstnärer | Land |+--------------------+---------------------+--- -----------------------+(1 rad påverkad)

Återigen, bara för att vara tydlig, den nuvarande databasen är WideWorldImportersDW , men objekten finns i en annan databas som heter Music , som har ett databas-ID på 5.

Exempel 4 – Hur man får databas-ID

Det är ganska troligt att du inte vet vad databasens ID är högst upp i huvudet. Du kommer förmodligen att känna till namnet på databasen, men inte dess ID.

Lyckligtvis kan du använda DB_ID() funktion för att returnera databasens ID, baserat på dess namn.

Därför kan vi modifiera det föregående exemplet enligt följande:

ANVÄND WideWorldImportersDW;VÄLJ namn SOM [Främmande nyckel], OBJECT_NAME(parent_object_id, DB_ID('Music')) AS [Parent Object Name], OBJECT_NAME(referenced_object_id, DB_ID('Music')) AS [Refered Object Name]FROM Music.sys.foreign_keysWHERE name ='FK_Artists_Country';

Resultat:

Ändrade databaskontext till 'WideWorldImportersDW'.+-------------------------+----------------- -----+---------------------------------+| Utländsk nyckel | Namn på överordnat objekt | Refererat objektnamn ||------------------------+----------------------------+- --------------------------|| FK_Artister_Land | Konstnärer | Land |+--------------------+---------------------+--- -----------------------+(1 rad påverkad)

  1. Hur skapar jag en tillfällig tabell i SQL?

  2. Hur NOT LIKE fungerar i MySQL

  3. Synkronisera offline SQLite databas med online MySQL databas

  4. Hur exporterar och importerar jag en .sql-fil från kommandoraden med alternativ?