Uwarunkowanie danych

0

Cześć,

mam za zadanie aby np. w kolumnie Ilosc wartość była większa niż 0. Nie byłoby problemu gdybym mógł sobie to sprawdzić na poziomie aplikacji, jednak tym razem mam mieć sprawdzanie danych na poziomie bazy danych. A więc napisałem sobie triggera.

CREATE TABLE sprzedaz (
	Id INT AUTO_INCREMENT PRIMARY KEY,
	KlientID INT,
	ProduktNumer VARCHAR( 100 ),
	Ilosc INT NOT NULL,
	Cena FLOAT NOT NULL,
	Data TIMESTAMP DEFAULT NOW(),
);

CREATE TABLE sprzedaz_check (
	Id INT AUTO_INCREMENT PRIMARY KEY,
	KlientID INT,
	ProduktNumer VARCHAR( 100 ),
	Ilosc INT NOT NULL,
	Cena FLOAT NOT NULL,
	Data TIMESTAMP DEFAULT NOW(),
);

DROP TRIGGER IF EXISTS before_sprzedaz_insert;

DELIMITER |
CREATE TRIGGER before_sprzedaz_insert
BEFORE INSERT ON sprzedaz_check
FOR EACH ROW
BEGIN
DECLARE amount INTEGER;
IF NEW.Ilosc = 0 THEN SET amount=1;
ELSE SET amount=NEW.Ilosc;
END IF;
INSERT INTO sprzedaz VALUES( NULL, NEW.KlientID, NEW.ProduktNumer, amount, NEW.Cena, NEW.Data );
END|
DELIMITER ;

Problem jest tego typu, że pisząc triggera nie mogłem operować na tabeli, z której został wywołany trigger, a więc byłem zmuszony (chyba) stworzyć nową tabelę (sprzedaz_check) i do niej wrzucac dane, a jeśli dane się zgadzają to przerzucam je do tabeli sprzedaz (no prawie, tak naprawdę to koryguję, ale to nieistotne). Jednak rozwiązanie jest niechlujne i bardzo nieoptymalne (bo po co dublować wartości), moża to jakoś inaczej rozwiązać?

Pozdrawiam i dzięki za pomoc.

//edit

może pytanie z innej beczki, czy jest możliwe aby po sprawdzeniu danych w triggerze anulować dodanie rekordu, jeśli będą złe? Jeśli to się da to cała reszta na górze jest już wtedy bez znaczenia ;)

0
nwnuinr napisał(a)

może pytanie z innej beczki, czy jest możliwe aby po sprawdzeniu danych w triggerze anulować dodanie rekordu, jeśli będą złe?

Nie da się po prostu anulować transakcji (rollback)? Wydaje mi się, że to standardowa możliwość w bazach.

0

W MySQL na razie nie można z triggera wyzwalanego na danej tabeli modyfikować danych w tej tabeli. W innych systemach bazodanowych można.

0
 CREATE TRIGGER mytabletriggerexample
BEFORE INSERT
FOR EACH ROW BEGIN
IF(NEW.important_value) < (fancy * dancy * calculation) THEN
    DECLARE dummy INT;

    SELECT 'Your meaningful error message goes here' INTO dummy 
        FROM mytable
      WHERE mytable.id=new.id
END IF; END;

Brzydkie, aczkolwiek ciekawe (i działające) obejście problemu autora wątku. Na dodatek z bonusem w postaci zwracanej informacji o błędzie.
(źródło: http://www.brokenbuild.com/blog/2006/08/15/mysql-triggers-how-do-you-abort-an-insert-update-or-delete-with-a-trigger/)

1 użytkowników online, w tym zalogowanych: 0, gości: 1