paolo@bimodesign.com | +34 608 61 64 10

DB Relational

        

MySQL: Una alternativa al CONSTRAINT CHECK

Visto che, come indicato nel manuale The CHECK clause is parsed but ignored by all storage engines, non si puo' utilizzare il CONSTRAINT ...CHECK in MySQL. Nel caso in cui dobbiamo farne uso (in realta' sono pochi i casi in cui non si abbiano alternative al suo uso), possiamo utilizzare uno tra questi due metodi, dove il secondo e' pero' limitato alle versioni successive alla 5.5

Ipotizziamo di voler limitare il valore di un campo INT a valori non superiori a 500.
La prima delle due possibilita' e' quella di creare il campo che conterra' questo valore, come NOT NULL e quindi creare un trigger che, quando il valore in inserimento e' maggiore di 500, lo sostituisca con NULL e quindi di fatto lo scarti.
Ricordo che non e' possibile utilizzare la DELETE in trigger BEFORE INSERT ;)
Questa la tabella

CREATE TABLE IF NOT EXISTS `prueba` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `total` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

e questo il semplicissimo TRIGGER

DELIMITER $$

DROP TRIGGER IF EXISTS trigger_prueba $$

CREATE TRIGGER trigger_prueba BEFORE INSERT ON prueba FOR EACH ROW BEGIN
  DECLARE total_value INT;

  SET total_value = new.total;

  IF total_value > 500
  THEN
    SET new.total = total_value;
  ELSE
    SET new.total = NULL;
  END IF;
END $$

DELIMITER ;

La seconda opzione, piu' pulita della precedente, ma disponibile solo a partire dalla versione 5.5 e' quella di introdurre un SIGNAL se il controllo ha avuto esito negativo, con conseguente messaggio di errore.
Questo il codice, mentre vi rimando alla documentazione ufficiale per maggiori dettagli.

DELIMITER $$

DROP TRIGGER IF EXISTS trigger_prueba $$

CREATE TRIGGER trigger_prueba BEFORE INSERT ON prueba FOR EACH ROW BEGIN
  DECLARE total_value INT;
  DECLARE msg VARCHAR(255);

  SET total_value = new.total;

  IF total_value > 500
  THEN
     SET msg = 'Messaggio di errore!!';
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
  END IF;

  SET new.total = total_value;

END $$

DELIMITER ;