[ srLooks @ 06.07.2011. 07:09 ] @
Imam problem sa postavljanjem ogranicenja nad vrednostima ne kljucnih obelezja.Postoji tabela u kojoj treba da definisem neke vrednosti. Vrednosti jedne torke ne smeju da budu kontradiktorne same sa sobom. Npr, ako postoji tabela Predmet, i ako u toj tabeli pored primarnog obelezja postoje i obelezja "obavezan" i "izborni" predmet, kako naterati MySQL da zabrani evidentciju " izbornog" predmeta ako postoji "obavezan" predmet? Dakle, u tabeli ne sme da postoji jedan predmet koji je u isto vreme i "obavezan" i "izborni" . Dakle, moze biti ili "obavezan" ili "izborni".

Tabela Predmet
{
sifPredmeta varchar(10) PRIMARY KEY not null,
naziv varchar(45) not null,
obavezan varchar(8) not null,
izborni varchar(8) not null
}


Vrednosti za obelezja "Obavezan" i "izborni" bi bili 1 ili 0 u zavisnoti od toga da li je predmet OBAVEZAN ili IZBORNI. Dakle, ako je predmet OBAVEZAN onda je vrednost 1 , dok bi u tom slucaju vrednost Obelezja IZBORNI bila 0, i obrnuto.




[Ovu poruku je menjao srLooks dana 06.07.2011. u 11:13 GMT+1]
[ bogdan.kecman @ 06.07.2011. 09:32 ] @
ako sam uspeo da dekodiram tu cudnu terminologiju koju vidim prvi put (obelezje je kljuc ili polje?) jedini nacin da odradis testiranje vrednosti unutar tabele je trigerom (na insert i na update proveris da li se vrednosti poklapaju sa pravilima koja imas)

http://stackoverflow.com/quest...nsert-under-certain-conditions


e sad ako koristis mysql 5.5 onda mozes da koristis signal dakle nesto ovako:

Code:

mysql> drop table t1;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE `t1` (
    ->   `f1` int primary key auto_increment not null,
    ->   `f2` int DEFAULT NULL,
    ->   `f3` int DEFAULT NULL
    -> ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.03 sec)

mysql> 
mysql> drop trigger tt;
ERROR 1360 (HY000): Trigger does not exist
mysql> 
mysql> delimiter $$
mysql> CREATE
    -> TRIGGER `tt`
    -> BEFORE INSERT ON `t1`
    -> FOR EACH ROW
    -> begin
    ->     declare mystate condition for sqlstate '7CL02';
    ->     if New.f3 > New.f2 then
    ->         SIGNAL SQLSTATE '55555';
    ->     end if;
    -> end
    -> $$
Query OK, 0 rows affected (0.00 sec)

mysql> 
mysql> delimiter ;
mysql> 
mysql> insert into t1 values (1,1,1), (2,2,2), (3,3,3), (4,4,5), (5,5,4);
ERROR 1644 (55555): Unhandled user-defined exception condition
mysql> select * from t1;
Empty set (0.00 sec)

mysql> 
mysql> insert into t1 values (1,1,1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values (2,2,2);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values (3,3,3);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values (4,4,5);
ERROR 1644 (55555): Unhandled user-defined exception condition
mysql> insert into t1 values (5,5,4);
Query OK, 1 row affected (0.00 sec)

mysql> 
mysql> select * from t1;
+----+------+------+
| f1 | f2   | f3   |
+----+------+------+
|  1 |    1 |    1 |
|  2 |    2 |    2 |
|  3 |    3 |    3 |
|  5 |    5 |    4 |
+----+------+------+
4 rows in set (0.00 sec)

[ biske86 @ 06.07.2011. 12:41 ] @
Samo malo pojašnjenja ako nije problem.

Code (sql):
DECLARE mystate condition FOR sqlstate '7CL02';


Ovo nigde ne pozivamo kasnije. Nismo nikad pozvali to kao:

Code (sql):
SIGNAL mystate


Šta znači ovaj kod '7CL02'? Nisam mogao da ga nađem na sajtu mysqla.


Ako bi smo hteli da postavimo našu poruku umesto ovog "Unhandled user-defined exception condition" trebali bi ispod SIGNAL SQLSTATE '55555' da stavimo SET MESSAGE_TEXT='Greška! Vrednost trećeg parametra ne može biti veća od drugog'. Da li je ovo tačno?
[ bogdan.kecman @ 06.07.2011. 12:58 ] @
7CL02 ne znaci nista to je neki kod iz nekog primera .. tj cela ta linija je beskorisna ostala iz nekog primera

full sintaksa za signal je na linku koji sam stavio, ako hoces poruku i kod greske moze:

Code:

mysql> drop trigger tt;
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter $$
mysql> create trigger tt 
    -> before insert on t1
    -> for each row
    -> begin
    ->   if New.f3 > New.f2 then
    ->     signal SQLSTATE '55555' SET MESSAGE_TEXT = 'greska', MYSQL_ERRNO = 1001;
    ->   end if;
    -> end $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> 
mysql> insert into t1 values (null, 5,6);
ERROR 1001 (55555): greska
mysql> insert into t1 values (null, 6,5);
Query OK, 1 row affected (0.00 sec)



obrati samo paznju na:
Citat:

SQLSTATE values that begin with '01' are signals in the warning class. The warning does not terminate the procedure, and can be seen with SHOW WARNINGS after the procedure returns.
[ biske86 @ 06.07.2011. 16:32 ] @
A ako želimo da prekinemo proceduru koji tip signala stavljamo?
[ vilyu @ 06.07.2011. 17:02 ] @
Ja bih jednostavno koristio samo jedno polje: obavezan (1,0). Ako je 1 onda je obavezan, ako je 0 onda je izborni. Eventualno jos jedna vrednost da opise stanje "nedefinisano".
[ biske86 @ 06.07.2011. 18:56 ] @
Citat:
vilyu: Ja bih jednostavno koristio samo jedno polje: obavezan (1,0). Ako je 1 onda je obavezan, ako je 0 onda je izborni. Eventualno jos jedna vrednost da opise stanje "nedefinisano".

Mislim da pročamo o različitim stvarima. Ja sam pitao za klasu kodova, kao što je objašnjeno na ovoj strani, koju je Bogdan ostavio:
http://dev.mysql.com/doc/refma...al-condition-information-items
Znači klasa 01 je upozorenje, klasa 02 kaže da nešto nije nađeno, itd.
[ bogdan.kecman @ 06.07.2011. 19:28 ] @
ako se ja dobro secam, svaki SIGNAL ce prekinuti ako ga hendlujes, dakle mozes da imas handler pa kad cimnes signal da ga ishendlas .. ali svaki ce prekinuti
[ vilyu @ 06.07.2011. 19:38 ] @
@biske86: Odgovarao sam na prvu poruku u temi. Izvinjavam se sto sam upao tebi i Bogdanu u diskusiju.
[ bogdan.kecman @ 06.07.2011. 19:50 ] @
Citat:
vilyu:Odgovarao sam na prvu poruku u temi.


nisi odgovorio na pitanje (kako da spreci insert ako slog ne odgovara nekom uslovu) vec si mu rekao "nevalja ti koncept, uradi to drugacije pa ti ne treba uslov", sto bi bio vise nego valjan odgovor da je OP postavio kako mu stvarno izgleda tabela i sta tacno radi (ja pretpostavljam sta radi i slazem se sa tobom 100% da mu je database model los no posto ga nije postavio ja necu da gledam u suljpa)

Citat:
vilyu:Izvinjavam se sto sam upao tebi i Bogdanu u diskusiju.


zasto mislis da smo biske i ja bogom dani da samo mi odgovaramo i da niko ne sme da nam upada u diskusiju :D .. samo napred, nista lose nisi uradio da treba da se izvinjavas (quote rulez za to da uvek budes siguran da je svima jasno na sta mislis kada nesto pises :D )
[ biske86 @ 06.07.2011. 20:31 ] @
Da, da, ja nisam imao primedbu na to sto si komentarisao, već sam samo rekao da tvoj odgovor nije vezan za ovo što pričamo. Nadam se da kolega nije loše shvatio, stvarno mi to nije bila namera.
[ loonies @ 07.07.2011. 09:51 ] @
Evo i ja da upadnem.. :)

Da li je moguce da to kontrolises na aplikacionom nivou?
[ bogdan.kecman @ 07.07.2011. 20:18 ] @
trigeri i refencijalni integritet sluze da loseg programera sprecis da napravi sran.e; uvek je sve sto trigeri i ref integritet moguce odraditi na app nivou, problem je sto ako neko napravi gresku na jednom mestu u aplikaciji (od npr mogucih 10) ti tu gresku vidis tek posle xyz vremena kada je baza vec u totalnom haosu..
[ loonies @ 07.07.2011. 23:30 ] @
Takvog programera treba otpustiti :)

TDD FTW