Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] Wyzwalacz BEFORE blokujący pokrywanie się okresów
Forum PHP.pl > Forum > Bazy danych > MySQL
kiciafu
Witam,

posiadam taką tabelkę:
  1. ID INT
  2. ID_ZASOB INT
  3. OD DATETIME
  4. DO DATETIM
  5. OPIS VARCHAR


Chciałbym zablokować możliwość dodawania rekordu w którym dany zasób w określonym przedziale czasu może być wykorzystany tylko raz. Zrobiłem coś co działa ale nie poprawnie:

  1.  
  2. BEGIN
  3. IF (NEW.DO <= NEW.OD) THEN
  4. INSERT INTO ERROR VALUES(`Zła data`);
  5. END IF;
  6. IF NEW.OD BETWEEN (SELECT ZASOBY.OD FROM ZASOBY WHERE ZASOBY.ID_OS = NEW.ID_OS) AND (SELECT ZASOBY.DO FROM ZASOBY WHERE ZASOBY.ID_OS = NEW.ID_OS) THEN
  7. INSERT INTO ERROR VALUES(`Zły przedział`);
  8. END IF;
  9. END
  10.  


Takie coś działa tylko dla jednego rekordu z danym ID, jeżeli dodam kolejny rekord spełniający warunek to potem podzapytanie zwróci więcej wyników i nic z tego nie będzie. Myślałem żeby zastosować MAX ale też to nie da zamierzonego efektu.



Rozwiązanie:

  1.  
  2. BEGIN
  3. IF (NEW.DO <= NEW.OD) THEN
  4. INSERT INTO ERROR VALUES(`ZŁY PRZEDZIAŁ`);
  5. END IF;
  6. CREATE TEMPORARY TABLE IF NOT EXISTS `X` AS
  7. SELECT * FROM ZASOBY;
  8. SET @max1:= (SELECT MAX(ID)+1 FROM ZASOBY);
  9. INSERT INTO `X` (X.ID, X.ID_OS, X.OD, X.DO, X.OPIS) VALUES (@max1, NEW.ID_OS, NEW.OD, NEW.DO, NEW.OPIS);
  10. CREATE TEMPORARY TABLE IF NOT EXISTS `Y` AS
  11. SELECT * FROM ZASOBY;
  12.  
  13. INSERT INTO `Y` (Y.ID, Y.ID_OS, Y.OD, Y.DO, Y.OPIS) VALUES (@max1, NEW.ID_OS, NEW.OD, NEW.DO, NEW.OPIS);
  14. SET @a:=(SELECT COUNT(*) FROM (
  15. SELECT X.ID AS id1, '-', Y.ID AS id2 FROM X JOIN Y ON X.ID<Y.ID AND Y.OD<X.DO AND Y.DO>X.OD AND X.ID_OS = Y.ID_OS) AS E);
  16. IF @a>0 THEN
  17. INSERT INTO ERROR VALUES(`ZŁY PRZEDZIAŁ`);
  18. END IF;
  19. DROP TEMPORARY TABLES X,Y;
  20. END


Tabela ZASOBY musi posiadać przynajmniej jeden rekord wprowadzony przed ustawieniem wyzwalacza (ze względu na NULL w ID), Jak ktoś ma pomysł jak to zoptymalizować będę wdzięczny za sugestie.
mmmmmmm
zamiast
  1. IF NEW.OD BETWEEN (SELECT ZASOBY.OD FROM ZASOBY WHERE ZASOBY.ID_OS = NEW.ID_OS) AND (SELECT ZASOBY.DO FROM ZASOBY WHERE ZASOBY.ID_OS = NEW.ID_OS) THEN
  2. INSERT INTO ERROR VALUES(`Zły przedział`);
  3. END IF;

daj
  1. IF EXISTS(SELECT ZASOBY.ID_OS FROM ZASOBY WHERE ZASOBY.ID_OS = NEW.ID_OS NEW.OD BETWEEN ZASOBY.OD AND ZASOBY.DO) THEN
  2. INSERT INTO ERROR VALUES(`Zły przedział`);
  3. END IF;
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.