[ makempire @ 12.03.2007. 12:21 ] @
Koristio sam Access database, sa ON DELETE, i ON UPDATE actions postavlene Cascade.
U accessu sam imao definirani indekse za sva vklucena polja.

Sad, koristim SQL server 2005 (management studio). Definisao sam iste indekse kao kad accessu, no pojavla se ova poruka:
Introducing FOREIGN KEY constraint 'FK_PosSub_Rec' on table 'PosSub' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

U accessu nije problem koristite Cascade Update kod multiple cascade paths, ali u MSSQL je.
procitao sam da trebam koristiti triggers umesto constrains. ali ne znam kako
[ Fedya @ 12.03.2007. 14:30 ] @
Mozda ovo nije bas odgovor koji si ocekivao, ali sta sad :P
Ako ti treba uputstvo za trigere, rado cu ti pokazati i to, ali moje misljenje je da zaboravis na Cascade i da dizajniras tu bazu i aplikaciju malo bolje tako da ti cascade ne bude podrzan. Nemoj da pustas bazu da brise nista, vec napravi storovanu koja brise podatke iz svih povezanih tabela, ili nateraj aplikaciju da brise redom ili postavi bit u svim tabelama kojim ces reci da je zapis obrisan i ne pokazivati ga u aplikaciji... Po meni sve je bolje od cascade...

Ne znam sta drugi misle o Cascade, ali ja sa tim imam samo negativna iskustva.
[ goranvuc @ 12.03.2007. 14:51 ] @
Meni se cini da si ti tu nesto "zabrljao sa kljucevima" tj. negde si stavio kaskadni update ili brisanje, a da to nije potrebno. Proveri jos jednom sve relacije, multiple cascade je podrzan (zasto ne bi bio), ovde dobijas upozorenje jer izgleda da imas ciklicne kaskade. Necemo se valjda vracati u istoriju - trigeri za kaskadni update i brisanje su morali da se pisu zadnji put za MS SQL 7.0
[ makempire @ 13.03.2007. 07:49 ] @
Prvo hvala brzom odgovoru, oboje...
Ja sam iz Makedonije i ispricavam se sto moj srpski nije bas najbolji ali trudim se

Ipak bili ste u pravo - problem su: ciklicne kaskade


Nasao sam ovaj primer:
U kompanija ima employee ko je u sales department i je manager. U bazi, njgov Employee Type je Manager, a njegova Category je Sales. Employee Type Manager je isto u Sales Category.

U Accessu nije bilo problema... ali tu...
Mislim da jedino reshenje je Update i Delete triggers. Tu bi zelio pomos..

Fedya, mozda iskustva sa Cascade nisu ti najbolje, ali tu radi se za odromnoj bazi... i moramo priznati ja kod velike baze to je najbolji nacin.
goranvuc: MSSQL server: Disadvantage – Cascading Update Circular References are Not Supported like in Access

Opet hvala!
[ goranvuc @ 13.03.2007. 09:25 ] @
Ako dobro vidim iz tvoje seme, imas neku "cudnu" relaciju gde ti je neko polje iz tabele "Employee" strani kljuc u tabeli "EmployeeType", a iz seme nije jasno koja su polja u relaciji, ali po nekom "zdravom rezonu" polje "EmployeeTypeID" iz tabele "EmployeeType" bi trebalo da bude strani kljuc u tabeli "Employee" preko polja "TypeID", a kod tebe to nije slucaj. Zato sam ti i rekao da malo preispitas relacije, jer je retko moguce da postoji takav problem koji zahteva cirkularne relacije sa kaskadnim "apdejtom i dilitom" (sta bi na ovo rekao Vuk Karadzic).

Proveri ti to jos jednom, po meni je problem u modelu, a ne u MS SQL-u.
[ makempire @ 13.03.2007. 10:07 ] @
Ovo gore nije moj primer.
Guglao sam malo... ali moj e mnogu slicni i javlja se isti problem
relacie su uredu, kljucevi isto, jer sam ih uzeo iz staru programu u Access-u.

Sad, ako mi neko moze pomoci za triggere...

Code:
CREATE TRIGGER trig_del
ON recepti
FOR DELETE
BEGIN
DELETE FROM receptiSUB where IDN =  (SELECT idn FROM deleted)
END

jer ovo tocno?
[ DarkMan @ 13.03.2007. 12:12 ] @
Ja sam imao sledecu situaciju (primer):
Imamo dve tabele: RADNIK i NALOG.
U tabeli NALOG kljuc iz tabele radnik se referencira dva puta jer nam je potrebno ko je kreirao nalog i ko je realizovao nalog.
Ovde nije moguce koristiti cascade za delete za oba strana kljuca jer ce javljati gore ponenutu gresku.
Code:

use master
go
drop database PROBA
go
create database PROBA
go
use PROBA
go
create table RADNIK(
  ID int not null, 
  NAZIV varchar(30) not null, 
  constraint PK_RADNIK primary key  (ID)
)
go
create table NALOG(
  ID int not null,
  NAZIV varchar(30) not null, 
  RADNIK_KREIRAO int not null,
  RADNIK_REALIZOVAO int not null,
  constraint PK_NALOG primary key  (ID) 
)
go
alter table NALOG
   add constraint FK_RADNIK_KREIRAO foreign key (RADNIK_KREIRAO)
      references RADNIK (ID) on delete cascade
go
alter table NALOG
   add constraint FK_RADNIK_REALIZOVAO foreign key (RADNIK_REALIZOVAO)
      references RADNIK (ID) -- ne moze da se stavi on delete cascade jer izbacuje gresku
go
insert into RADNIK(ID,NAZIV) values(1,'r1')
insert into RADNIK(ID,NAZIV) values(2,'r2')
insert into RADNIK(ID,NAZIV) values(3,'r3')

insert into NALOG(ID,NAZIV,RADNIK_KREIRAO,RADNIK_REALIZOVAO) values(1,'proba',1,3)
insert into NALOG(ID,NAZIV,RADNIK_KREIRAO,RADNIK_REALIZOVAO) values(2,'proba',2,3)
go
select * from NALOG
select * from RADNIK
go
delete from RADNIK where ID = 1
go
select * from NALOG
select * from RADNIK
go

Brisanjem radnika ID=1 obrisace se i nalozi koje je on kreirao ali zato brisanjem radnika ID=3 dovodi do greske jer je on uvek realizovao naloge i nad tim stranim kljucem nemamo delete cascade.
Mislim da nije ni moguce ovo resiti koristici cascade.

Ja samo odustao od koriscenja kaskadnog brisanja (nisam hteo ni trigere) vec sam pravio stored procedure za brisanje vezanih podataka.
[ goranvuc @ 13.03.2007. 12:40 ] @
@Darkman, sve to sto si naveo stoji, ali ja imam primedbu na "prirodu problema". Zasto bi uopste zeleo da se kaskadno brisu svi nalozi ukoliko brisem radnika koji ih je kreirao ili ralizovao? Po meni, ovde ne da nije potrebno kaskadno brisanje, vec nije ni pozeljno (govorim iz ugla realne primene). Dakle, u realnom sistemu nema potrebe za kaskadnim brisanjem svih naloga pri pokusaju brisanja radnika, vec baza podataka ne sme da dozvoli brisanje radnika sve dok postoji makar jedan radni nalog od tog radnika.

Kaskadno brisanje ima najvise smisla i primene kod entiteta koji su potpuno zavisni, a najcesce je to kod "stavki dokumenata" da ih tako nazovem. U svim ostalim primerima treba razmisliti o smislu kaskadnog brisanja. Kaskadni UPDATE opet nema smisla stavljati tamo gde se nece menjati vrednost kljuca.

Jedini razlog kada treba iskljuciti opciju kaskadnih operacija je kada vam treba neki dodatni triger, pa kaskadna operacija "smeta", ali takve slucajeve svakako MS SQL "prijavljuje" tako da se ni oko toga ne treba previse uzbudjivati. Hvala bogu sto su kaskadne operacije dodali od verzije 2000, pre toga sam stalno morao da vodim racuna da li sam mozda u nekoj od mojih 200 tabela zaboravio da napisem triger za kaskadno brisanje, pa sam zbog zaboravnosti cak i imao program koji je po metashemi pravio neophodne trigere...

Dakle, kaskade slobodno tamo gde ima smisla, zato su i izmisljene - nema tu "bojim se, nisam siguran" i sl.
[ DarkMan @ 13.03.2007. 20:37 ] @
Primer je bio vise radi demonstracije kako se moze javiti data greska pri pokusaju postavljanja "on delete cascade".
U pravu si da primer bas i nije dobar, ali je mene vise interesovalo zasto je SQL serveru problem da se na oba polja stavi kaskadno brisanje.

[ goranvuc @ 13.03.2007. 21:41 ] @
Citat:
DarkMan:ali je mene vise interesovalo zasto je SQL serveru problem da se na oba polja stavi kaskadno brisanje.

Bojim se da cemo to morati da pitamo bracu iz MS

Salu na stranu, ja sam tvrdoglav u ubedjenju da su kaskadne operacije super stvar, samo ih treba koristiti na pravi nacin, tj. tamo gde to ima smisla.