2010-03-29 25 views
29

Mam tabelę zawierającą adres URL i ciąg reprezentujący jego parametry. Problem polega na tym, że chcę, by URL i parametrstring były unikatowym ograniczeniem dla tabeli - aka żadne wpisy nie mogą mieć tego samego adresu url i parametru. Łańcuch parametrów może mieć dowolną długość (dłuższą niż 800 bajtów, co jest maksymalną długością klucza MySql, więc nie mogę używać Unique (adresu URL, parametrów), ponieważ powoduje błąd ...).Jak przerwać operację WSTAW w wyzwalaczu MySql?

Myślałem o użyciu wyzwalaczy, aby to zrobić, ale jak mam wyjątek/podnieść błąd, jeśli spust odkrywa wkładka ma zamiar wstawić duplikat wpisu? Wyobrażam sobie, że chciałbym mieć wyrzucony MySqlException jak MySql ze zduplikowanymi kluczami głównymi itp., Więc mogę go złapać w moim C# code.

Mam dwie sztuki w spustu Potrzebuję uzyskać pomoc z: ... Przerwać wyrzucać wyjątek do C# ... Jak rzucić wyjątek itp do C#? ... Pozwól wstawić ... - jak mogę zezwolić na wstawianie, jeśli nie ma duplikatu wpisu?

Herezje kod wyzwalacza:

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

z MySQL 5.5, ewentualnie wcześniej, można użyć sygnałów [zobacz moją odpowiedź tutaj] [1] [1]: http://stackoverflow.com/questions/24/throw-error- in-mysql-trigger/7189396 # 7189396 – RuiDC

Odpowiedz

6

Jeśli definicja tabeli jest wartością NOT NULL, można ustawić nowy na NULL, które nie zostałyby skutecznie zrobić wkładkę. Aby to działało poprawnie, konieczne może być włączenie ścisłego trybu sql.

67

natknąłem się tego i choć rozwiązanie działa mi później natknąłem się co czuje do mnie jak lepszego rozwiązania. Podejrzewam, że nie było to możliwe, gdy pierwotnie udzielono odpowiedzi na to pytanie.

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$$ 

Spowoduje to wyświetlenie komunikatu o błędzie (lub złym!), Który można pułapkować. Aby uzyskać więcej informacji na ten temat, zobacz: http://dev.mysql.com/doc/refman/5.5/en/signal.html

Mam nadzieję, że to pomoże komuś innemu!

+2

To jest naprawdę niesamowite. Pracował dla mnie. – rishad2m8

+1

Dziękuję. Musiałem mieć stół i wymusić niepokrywające się zakresy, co pozwoliło mi to zrobić. – Kickstart

+1

To powinna być zaakceptowana odpowiedź ... UP GŁOSUJ! – smashing