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.

April 9, 2008 / by Zsolt Soczó

SQL Server 2008 újdonságok 34. – Megbízható függőségek

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

  • balage April 9, 2008

    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?)

  • Soczó Zsolt April 9, 2008

    Az oszlopszintű függőségekkel nem láttam problémát, de majd elválik.

    Sor szintű trigger nincs még mindig.

  • balage April 9, 2008

    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)