Ако някога ви се наложи да използвате OBJECT_NAME()
функция за получаване на името на обект от друга база данни в SQL Server, може да срещнете проблеми, ако не знаете как работи.
Вероятно знаете, че OBJECT_NAME()
приема object_id
аргумент, който казва на SQL Server от кой обект да получи името.
Това, което може да знаете или не, е, че тази функция също приема незадължителен database_id
аргумент, който казва на SQL Server коя база данни е object_id
принадлежи на.
По подразбиране SQL Server приема, че object_id
е в контекста на текущата база данни. В този случай заявка, която препраща към object_id
в друга база данни ще върне NULL или (още по-лошо) неправилни резултати.
Пример 1 – Локална заявка (от текуща база данни)
Първо, ето локална заявка, която връща името на обекта от текущата база данни:
ИЗПОЛЗВАЙТЕ музика;ИЗБЕРЕТЕ име КАТО [Външен ключ], OBJECT_NAME(parent_object_id) КАТО [Име на родителски обект], OBJECT_NAME(referenced_object_id) КАТО [Име на препоръчан обект]FROM Music.sys.foreign_keysWHERE name ='FK_Artists_preCountry';ИЗПОЛЗВАЙТЕ музика;>
Резултат:
Променен контекстът на базата данни на „Музика“.+-------------------+----------------- -----+-------------------------+| Външен ключ | Име на родителски обект | Име на препоръчан обект ||--------------------+---------------------+- -------------------------|| FK_Артисти_Държава | Художници | Държава |+--------------------+---------------------+--- -----------------------+(1 ред засегнат)
Тези резултати са верни.
Това не е заявка за кръстосана база данни. Това е само пример, който показва как се използва тази функция при получаване на името на обект от текущата база данни.
Пример 2 – Заявка за кръстосана база данни с ГРЕШНИ РЕЗУЛТАТИ!
Сега, ето заявка за кръстосана база данни, която дава неправилни резултати.
ИЗПОЛЗВАЙТЕ WideWorldImportersDW;ИЗБЕРЕТЕ име КАТО [Външен ключ], OBJECT_NAME(parent_object_id) КАТО [Име на родителски обект], OBJECT_NAME(referenced_object_id) КАТО [Име на препоръчан обект]FROM Music.sys.foreign_keysWHERE name =Резултат:
Променен контекстът на базата данни на 'WideWorldImportersDW'.+--------------------+---------------- -----+----------------------------+| Външен ключ | Име на родителски обект | Име на препоръчан обект ||--------------------+---------------------+- ----------------------------|| FK_Артисти_Държава | CityKey | PK_Dimension_Payment_Method |+--------------------+---------------------+--- -------------------------+(1 ред засегнат)Всичко, което направих, беше да премина към друга база данни, след което да изпълня отново същата заявка.
Ще забележите, че моят
FROM
клаузата използва име от три части, за да посочи името на базата данни (Music
). Това позволява да се намери правилният външен ключ. Това обаче не е достатъчно, за да предотврати възникването на проблеми.Както се оказва,
WideWorldImportersDW
базата данни има обекти със същияobject_id
които се използват вMusic
база данни. Единственият проблем е, че те са напълно различни обекти, с различни имена. Така че резултатите в последните две колони са фалшиви. Това са имената на грешните обекти в грешната база данни. Заявката ми за кръстосана база данни прекъсна проводниците си и върна грешните обекти!Това е особено опасно, защото ако не обръщах внимание, тези резултати може да изглеждат ОК. В крайна сметка не получих грешка.
Ако тези идентификатори на обекти не съществуваха в тази база данни, вероятно щях да получа стойност NULL (което може да улесни откриването, че нещо не е наред с резултатите).
Така или иначе резултатът е просто грешен .
Пример 3 – Заявка за кръстосана база данни с ТОЧНИ резултати
За да коригираме предишния пример (без да променяме текущата база данни), трябва да предоставим идентификатора на базата данни, от която искаме името на обекта.
Като това:
ИЗПОЛЗВАЙТЕ WideWorldImportersDW;ИЗБЕРЕТЕ име КАТО [Външен ключ], OBJECT_NAME(parent_object_id, 5) КАТО [Име на родителски обект], OBJECT_NAME(referenced_object_id, 5) КАТО [Име на препоръчан обект]FROM Music.sys.foreign_keys'FHERK name_keys'FHERK;Резултат:
Променен контекстът на базата данни на 'WideWorldImportersDW'.+--------------------+---------------- -----+-------------------------+| Външен ключ | Име на родителски обект | Име на препоръчан обект ||--------------------+---------------------+- -------------------------|| FK_Артисти_Държава | Художници | Държава |+--------------------+---------------------+--- -----------------------+(1 ред засегнат)Отново, само за да е ясно, текущата база данни е
WideWorldImportersDW
, но обектите са в друга база данни, нареченаMusic
, който има идентификатор на базата данни 5.Пример 4 – Как да получите идентификатора на базата данни
Много вероятно е да не знаете какъв е идентификационният номер на базата данни от върха на главата ви. Вероятно ще знаете името на базата данни, но не и нейния идентификатор.
За щастие можете да използвате
DB_ID()
функция за връщане на идентификатора на базата данни въз основа на нейното име.Следователно можем да модифицираме предишния пример, както следва:
ИЗПОЛЗВАЙТЕ WideWorldImportersDW;ИЗБЕРЕТЕ име КАТО [Външен ключ], OBJECT_NAME(parent_object_id, DB_ID('Music')) КАТО [Име на родителски обект], OBJECT_NAME(referenced_object_id, DB_ID('Music')) КАТО име [Referenced Object] Music.sys.foreign_keysWHERE name ='FK_Artists_Country';Резултат:
Променен контекстът на базата данни на 'WideWorldImportersDW'.+--------------------+---------------- -----+-------------------------+| Външен ключ | Име на родителски обект | Име на препоръчан обект ||--------------------+---------------------+- -------------------------|| FK_Артисти_Държава | Художници | Държава |+--------------------+---------------------+--- -----------------------+(1 ред засегнат)