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 sammaobject_id
som används iMusic
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 heterMusic
, 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)