Hát igen, függőségek. Ez az a téma, amivel ki lehet kergetni a világból egy SQL Server DBA-t. Mindenki tudja, hogy az SQL Server 2005-ben függőségek kezelése szánalmas, egyáltalán nem megbízható.
Egy egyszerű példával világítom meg.
create view dbo.VA as select * from Production.Product go create view dbo.VB as select * from VA go
VB függ VA-tól, tiszta ügy. A gond az, hogy megalterezve VA-t eltűnik az az infó, hogy VB függ VA-tól.
alter view dbo.VA as select * from Production.Product
Ez eszement dolog, de így van (nem tudom ellenőrizni, mert nincs a közelemben SQL 2005, ha valaki tudja validálni, kérem tegye meg).
2008-ban már normálisan mennek a függőségek. Ennek az az oka, hogy nem csak id szerint tárolják őket, hanem név szerint is. A régebbi verziók csak id-t használtak, így nem tudták letárolni a késleltetett névfeloldás miatt időlegesen hiányzó függőségeket (mondjuk ez nem menti fel őket az előbbi példa esetében).
2008-ban a függőségeket a sys.sql_expression_dependencies rendszertábla tárolja, és két függvény segít lekérdezni belőlük.
drop view dbo.VA drop view dbo.VB drop proc dbo.PA drop proc dbo.PB go create view dbo.VA as select * from Production.Product go select OBJECT_NAME(referencing_id), referenced_entity_name, referenced_id from sys.sql_expression_dependencies where referencing_id = OBJECT_ID('dbo.VA')
referencing_object referenced_entity_name referenced_id ------------------------------ ------------------------------ ------------- VA Product 1461580245
Szépen van név és id is, hisz létezett a Product tábla. Eddig ok.
create view dbo.VB as select * from VA go select OBJECT_NAME(referencing_id) referencing_object, referenced_entity_name, referenced_id from sys.sql_expression_dependencies where referencing_id in (OBJECT_ID('dbo.VA'), OBJECT_ID('dbo.VB'))
referencing_object referenced_entity_name referenced_id ------------------------------ ------------------------------ ------------- VA Product 1461580245 VB VA 992722589
Ez is rendben van. Most jön a régi problémás pont:
alter view dbo.VA as select * from Production.Product go select OBJECT_NAME(referencing_id) referencing_object, referenced_entity_name, referenced_id from sys.sql_expression_dependencies where referencing_id in (OBJECT_ID('dbo.VA'), OBJECT_ID('dbo.VB'))
És a kimenet jó!
------------------------------ ------------------------------ ------------- VA Product 1461580245 VB VA 992722589
Jöhet a késeltetett névfeloldás tesztje.
create proc dbo.PA as exec dbo.PB go select OBJECT_NAME(referencing_id) referencing_object, referenced_entity_name, referenced_id from sys.sql_expression_dependencies where referencing_id in (OBJECT_ID('PA'))
The module 'PA' depends on the missing object 'dbo.PB'. The module will still be created; however, it cannot run successfully until the object exists. referencing_object referenced_entity_name referenced_id ------------------------------ ------------------------------ ------------- PA PB NULL
Látható, hogy a referenced_id NULL, mert még nem létezik PB, de név alapján felvették a függőséget. Kiváló! Mikor lesz kitöltve az id?
create proc dbo.PB as go select OBJECT_NAME(referencing_id) referencing_object, referenced_entity_name, referenced_id from sys.sql_expression_dependencies where referencing_id in (OBJECT_ID('PA'))
referencing_object referenced_entity_name referenced_id ------------------------------ ------------------------------ ------------- PA PB 1040722760
A reference_id most már jó, mert létezik a hivatkozott objektum.
Nézzük a nézeteket. Kire hivatkozik egy ojjektum? sys.dm_sql_referenced_entities nézet:
select OBJECT_NAME(referenced_id) referenced_object, * from sys.dm_sql_referenced_entities('dbo.PA', 'OBJECT')
referenced_object referencing_minor_id referenced_server_name referenced_database_name referenced_schema_name referenced_entity_name referenced_minor_name referenced_id referenced_minor_id referenced_class referenced_class_desc is_caller_dependent is_ambiguous ------------------------------ -------------------- ------------------------------ ------------------------------ ------------------------------ ------------------------------ ------------------------------ ------------- ------------------- ---------------- ------------------------------ ------------------- ------------ PB 0 NULL NULL dbo PB NULL 1040722760 0 1 OBJECT_OR_COLUMN 0 0
Látható, hogy PA PB-re hivatkozik.
Ki hivatkozik PB-re? sys.dm_sql_referencing_entities függvény:
select * from sys.dm_sql_referencing_entities('dbo.PB', 'OBJECT')
referencing_schema_name referencing_entity_name referencing_id referencing_class referencing_class_desc is_caller_dependent ------------------------------ ------------------------------ -------------- ----------------- ------------------------------ ------------------- dbo PA 1024722703 1 OBJECT_OR_COLUMN 0
Pontos lista, milyen függőségeket tárol a szerver.
Néha nem egyértelmű egy függőség. Az alábbi példában:
CREATE PROCEDURE dbo.p1 AS SELECT column_a, Sales.GetOrder() FROM Sales.MySales;
A Sales.GetOrder() lehet egy Sales nevű oszlop a MySales táblában, ami egy UDT, és van neki egy GetOrder metódusa, de lehet egy UDF, ami a Sales sémában van, és GetOrder a neve. (Az SQL Server 2005 korábbi beta verziójában még a C++-os :: volt a típust és metódust elválasztó karakter, ha ezt meghagyták volna, most nem lenne ez a félreérthetőség.)
A függőségeket jegyzik adatbázisok (3 tagú nevekkel hivatkozva más objektumokra) sőt szerverek között is (4 tagú nevek, linked szerverek), nem csak egy adatbázison belül. Emellett kétféle függőség van, schema-bound objektumok és nem schema-bound objektumok esetén. A NEM séma kötött objektumokról NINCS oszlopszintű függőségi infó a sys.sql_expression_dependencies táblában, de a sys.dm_sql_referenced_entities ezekről is összeszedi az infókat, ezért ha teljeskörű függőségi infóra van szükség, inkább a függvény használatát javaslom.
És látá Isten, hogy ez jó. (Remélem, majd elválik. :)
Could you hire me? Contact me if you like what I’ve done in this article and think I can create value for your company with my skills.
LEAVE A COMMENT
3 COMMENTS
Végre eljutott idáig az M$ is. És látá isten, hogy ez jó. Ezért megteremté, és magáévá tevé.
Jövőre lehet, hogy a bibliában úgy lészen, hogy
‘Misten a 2323884884. napon (Túlcsordulás hiba. Accept, Decline) megteremté a megbízható függőségeket, és látá, hogy ez jó, és kiterjeszté az egész világra.’
Szóval végre megy. Kerál’.
Nem néztem, de mi van a függvényeken belüli tábla-mező hivatkozások függőségeivel? Eddig nem volt gondom vele, mert inkább más db-ket használtam, de most talán már megfontoling, mert linq driverek elég gyenguszok még másokhoz…
(Lehet, hogy én is belekerültem a Mátrixba?)
Üdv.
PB
Sor szintű trigger-futtatás nem lesz sosenemlesz MSSQL-ban? Vagy csak lemaradtam…? (lehet, hogy már van?)
Az oszlopszintű függőségekkel nem láttam problémát, de majd elválik.
Sor szintű trigger nincs még mindig.
Pediglen akkor lenne igazán ‘nagykorú’ a cuccos, ha lenne benne, de lehet, hogy már más a stratégia. ORMapper végleg?
‘majmöglássuk’ – (ecceriember)