c4 2021
c4 2021
#de fapt incercarea de inserare a unei valori intr-o coloana virtuala va genera o
eroare.
===================================================================================
============
--> daca regula de validare e relativ simpla se poate impune folosind un CHECK
CONSTRAINT
--> daca regula de validare e mai complicata se foloseste un TRIGGER
CHECK CONSTRAINT
conditia de validare este verificata de cate ori se insereaza o linie nou sau se
updateaza o linie deja existenta.
fie tabelul
CREATE TABLE t1
(
v1 INT,
v2 INT,
v3 INT
);
trebuie ca expresia sa aiba valoarea de adevar T saul NULL pentru ca regula sa fie
validata. ATENTIE deci ca
valorile nule ale expresiei valideaza acest constraint, spre exemplu, constructia
urmatoare insereaza date in tabel.
#fiecare constraint folosit in tabel poarta un nume care ulterior (vedem mai
tarziu) poate fi folosit pentru a modifica/sterge acel constraint fara a sterge
tabelul.
test
insert into clienti1(nume, an_nastere) values('Dan',1990);
) ;
test
insert into clienti1(nume, an_nastere) values('Ean',1990);
data_inreg>='2012-1-1'
#se pot face constructii logice mai complexe, folosind operatori de flow control,
dar in acest caz e mai bine sa se creeze un trigger. In tabelul de mai jos impun ca
daca anul nasterii este >1947 atunci trebuie introdus obligatoriu si un nume.
Trigerii sunt functii definite dupa crearea unui tabel si care se executa atunci
cand se intampla un eveniment (inserare, updatare, stergere) in tabelul respectiv.
Triggerul poate fi setat sa se execute inainte (BEFORE) sau dupa(AFTER) evenimentul
respectiv.
Ei pot fi folositi nu numai pentru validarea inputului dar si pentru alte actiuni
in baza.
END;//
DELIMITER ;
EXEMPLE TRIGGERI:
Fie un tabel
drop table if exists produse;
CREATE TABLE produse (
id_produs int unsigned NOT NULL AUTO_INCREMENT,
nume VARCHAR(20),
pret double NOT NULL,
data_inreg Date,
PRIMARY KEY( id_produs)
) ;
DELIMITER //
CREATE TRIGGER valideaza_pret_la_inserare BEFORE INSERT ON produse
FOR EACH ROW
BEGIN
IF (NEW.pret<=0)
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'pretul trebuie sa fie strict pozitiv';
END IF;
END;
//
DELIMITER ;
Acum definim un trigger care sa permita numai preturi strict pozitive la updatare
in tabelul produse.
DELIMITER //
CREATE TRIGGER valideaza_pret_la_updatare BEFORE UPDATE ON produse
FOR EACH ROW
BEGIN
IF (NEW.pret<=0)
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'pretul trebuie sa fie strict pozitiv';
END IF;
END;
//
DELIMITER ;
DELIMITER //
create procedure valideaza(in pret double)
begin
IF (pret<=0)
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'pretul trebuie sa fie strict pozitiv';
END IF;
end
//
DELIMITER ;
DELIMITER //
CREATE OR REPLACE TRIGGER valideaza_pret_la_inserare BEFORE INSERT ON produse
FOR EACH ROW
BEGIN
call valideaza(NEW.pret);
END;
//
DELIMITER ;
DELIMITER //
CREATE OR REPLACE TRIGGER valideaza_pret_la_inserare BEFORE UPDATE ON produse
FOR EACH ROW
BEGIN
call valideaza(NEW.pret);
END;
//
DELIMITER ;
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'pretul trebuie sa fie strict pozitiv si cu
exact 2 zecimale';
END IF;
END;
//
DELIMITER ;
#scriem un trigger pentru a accepta numai nume formate din exact 4 caractere
END;
//
DELIMITER ;
#scriem un trigger pentru a accepta numai nume care incep cu D(mic sau mare)
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'numele trebuie sa inceapa cu D mare sau
mic';
END IF;
END;
//
DELIMITER ;
IF (ascii(mid(NEW.nume,1,1)) <> 68 )
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'numele trebuie sa inceapa cu D mare';
END IF;
END;
//
DELIMITER ;
insert into produse(nume, pret) values('dan',15.1);
insert into produse(nume, pret) values('Dan',15.1);
#acceptam numai nume care contin numai litere. Verificam ca acestea au codul ascii
fie intre 97-
122 fie intre 65 si 90
DECLARE k INT;
set k=0;
iteratie:LOOP
set k=k+1;
if(k> length(NEW.nume)) then
LEAVE iteratie;
end if;
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'numele trebuie sa contina numai litere';
END IF;
END LOOP;
END;
//
DELIMITER ;
#Scriem un trigger care va insera data curenta daca o data anume nu a fost inserata
pentru produs
DELIMITER //
CREATE TRIGGER adauga_data1 BEFORE INSERT ON produse
FOR EACH ROW
BEGIN
IF (NEW.data_inreg is null)
THEN
set NEW.data_inreg=curdate();
END IF;
END;
//
DELIMITER ;
IF (k >=5 )
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'am depasit nr maxim de linii din tabel';
END IF;
END;
//
DELIMITER ;
#afisam instructiunea de creare a primului trigger
show create trigger valideaza_pretul_la_inserare;
#afisam toti triggerii asociati bazei in care lucram in acest moment si care contin
in ei secventa valideaza