2010-03-29 8 views
29

Ho una tabella contenente un url e una stringa che rappresenta i suoi parametri. Il problema è che voglio che un url e una stringa di parametri siano il vincolo univoco per la tabella, altrimenti nessuna voce può avere la stessa stringa di parametro AND. La stringa di parametri può essere di lunghezza arbitraria (più lunga di 800bytes ovvero la lunghezza massima per una chiave MySql, quindi non posso usare Unique (url, params) poiché genera un errore ...).Come interrompere l'operazione INSERT nel trigger MySql?

Ho pensato di utilizzare i trigger per eseguire questa operazione, ma come faccio a generare un'eccezione/generare un errore se il trigger rileva che l'inserto sta per inserire una voce duplicata? Immagino che mi piacerebbe avere una MySqlException lanciata come MySql con chiavi duplicate primarie ecc. Quindi posso prenderla nel mio codice C#.

Ho due pezzi nel trigger che ho bisogno di ottenere aiuto con: ... Annullare l'eccezione a C# ... Come faccio a lanciare un'eccezione etc a C#? ... Consenti inserimento ... - Come faccio a consentire l'inserimento solo se non vi sono voci duplicate?

Heres il codice di attivazione:

CREATE TRIGGER urls_check_duplicates 
BEFORE INSERT ON urls 
FOR EACH ROW 

BEGIN 
DECLARE num_rows INTEGER; 

SELECT COUNT(*) 
INTO num_rows 
FROM urls 
WHERE url = NEW.url AND params = NEW.params; 

IF num_rows > 0 THEN 
    ... ABORT/throw exception to C# ... 
ELSE 
    ... Allow insert ... 
END 
+0

da MySQL 5.5, forse anche prima, è possibile utilizzare i segnali, [vedi la mia risposta qui] [1] [1]: http://stackoverflow.com/questions/24/throw-error- in-mysql-trigger/7189396 # 7189396 – RuiDC

risposta

6

Se la definizione della tabella è per un valore NOT NULL, è possibile impostare NOVITÀ su NULL, il che non farebbe efficacemente l'inserimento. Potrebbe essere necessario attivare la modalità SQL stretta affinché funzioni correttamente.

67

Mi sono imbattuto in questo e anche se la soluzione funziona, in seguito mi sono imbattuto in ciò che mi sembra una soluzione migliore. Sospetto che questa non fosse un'opzione in risposta a questa domanda.

CREATE TRIGGER `TestTable_SomeTrigger` 
BEFORE UPDATE ON `test_table` 
FOR EACH ROW 
BEGIN 
    DECLARE msg VARCHAR(255); 
    IF (SomeTestToFail = "FAIL!") THEN 
     set msg = "DIE: You broke the rules... I will now Smite you, hold still..."; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 

    -- Do any other code here you may want to occur if it's all OK or leave blank it will be 
    -- skipped if the above if is true 
END$$ 

Questo ora restituirà un messaggio di errore bello (o diabolico!) Che è possibile intercettare. Per ulteriori informazioni su questo vedi: http://dev.mysql.com/doc/refman/5.5/en/signal.html

Spero che questo aiuti qualcun altro!

+2

Questo è davvero sorprendente. Ha funzionato per me – rishad2m8

+1

Grazie. Avevo bisogno di avere un tavolo e applicare intervalli non sovrapposti e questo mi ha permesso di farlo. – Kickstart

+1

Questa dovrebbe essere la risposta accettata ... UP VOTE! – smashing