Da prvo reformulisemo problem:
U tabelu Ucenik INSERTuje se novi red,.,
PK za tabelu Ucenik je Identity tipa, i mi ne znamo vrednost koja ce biti INSERTovana.
Da bismo uneli novi red u tabelu [Fakultet], potrebno je da znamo koji smo to identity dodelili novom redu u tabeli Ucenik.
Funkcija Curent_INsert nije dobar izbor. Treba upotrebiti Scope_Identity(). Izvod iz Books Online kazjue zasto:
Citat:
IDENT_CURRENT is similar to the SQL Server 2000 identity functions SCOPE_IDENTITY and @@IDENTITY. All three functions return last-generated identity values. However, the scope and session on which last is defined in each of these functions differ:
IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope.
@@IDENTITY returns the last identity value generated for any table in the current session, across all scopes.
SCOPE_IDENTITY returns the last identity value generated for any table in the current session and the current scope.
The IDENT_CURRENT function returns NULL when the function is invoked on an empty table or on a table that has no identity column.
Ako vise korisnika radi na bazi, moze se desiti da je jos neko INSERTovao red u tabelu [Ucenik] i tada nam Ident_Current moze vratiti PK koji je taj drugi korisnik kreirao. To ne bi vljalo, zar ne
Treba koristiti SCOPE_IDENTITY(), jer vraca poslednji identity generisan za bilo koju tabelu u tekucoj sesiji. Ako procitam SCOPE_IDENTITY() odmah posle INSERT naredbe, dobicu identity koji generisala bas ta MOJA naredba, a ne neka druga.
Ukratko, pravilo glasi:
1) da dobijem identiti, za bilo koju tabelu, a koji sam JA kreirao, koristim SCOPE_IDENTITY() odmah iza INSERT naredbe
2) da dobijem identity za odredjenu tabelu , a koji je kreirao bilo ko, ja ili neko drugi, korsitim IDENT_CURRENT tamo gde zelim da vidim vrednost identity
U zadatom primeru to bi izgledalo ovako:
Code:
DECLARE @UcenikId INT
INSERT INTO ucenik (Ime) Values ('Pera')
;
SET @UcenikId = Scope_identity()
;
INSERT INTO fakultet (UcenikID, Adresa)
Values (@UcenikId,"Nikole Tesle 3")
;
Postoji situacija kada SCOPE_IDENTITY() i IDENT_CURRENT() daju prividno isti rezultat. To je kada niko drugi ne pristupa tabeli Ucenik osim onoga ko pise program. A to se desava UVEK kad smo jos uvek u fazi razvoja - niko drugi osim doticnog programera ne brlja po bazi, pa se dobije privid da SCOPE_IDENTITY() i IDENT_CURRENT() daju isti rezultat. Zato se ljudi prevare pa pomisle da je IDENT_CURRENT isto sto i SCOPE_IDENTITY(), a nije. Takve greske se tesko otkrivaju - kod radi, nista ne puca, samo sto se ponakad, ne uvek, adresa dodeli pogresnom studentu. Najgori je kod koji skoro uvek radi, ali ponekad, veome retko, zabrlja ponesto. IDENT_CURENT garantuje tu vrstu glavobolje.
Nadam se da je pomoglo.