2010-03-29 33 views
29

Tôi có một bảng có chứa một url và một chuỗi đại diện cho các tham số của nó. Vấn đề là tôi muốn một url và một chuỗi tham số là ràng buộc duy nhất cho bảng - aka không có mục nào có thể có cùng chuỗi url và tham số. Chuỗi tham số có thể có độ dài tùy ý (dài hơn 800byte hoặc lâu hơn là độ dài tối đa cho khóa MySql, vì vậy tôi không thể sử dụng Unique (url, params) vì nó ném lỗi ...).Làm thế nào để hủy bỏ hoạt động INSERT trong kích hoạt MySql?

Tôi đã nghĩ đến việc sử dụng trình kích hoạt để thực hiện việc này, nhưng làm cách nào để ném một ngoại lệ/tăng lỗi nếu trình kích hoạt phát hiện ra chèn là sắp chèn mục nhập trùng lặp? Tôi tưởng tượng tôi muốn có một MySqlException ném như MySql không trùng lặp với các phím chính vv vì vậy tôi có thể bắt nó trong mã C# của tôi.

Tôi có hai phần trong trình kích hoạt tôi cần trợ giúp: ... Hủy bỏ ngoại lệ cho C# ... Làm cách nào để ném ngoại lệ, v.v ... sang C#? ... Cho phép chèn ... - làm thế nào để tôi chỉ cho phép chèn nếu không có mục trùng lặp?

Heres mã kích hoạt:

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

từ MySQL 5.5, có thể là trước đó, bạn có thể sử dụng tín hiệu, [xem câu trả lời của tôi ở đây] [1] [1]: http://stackoverflow.com/questions/24/throw-error- in-mysql-trigger/7189396 # 7189396 – RuiDC

Trả lời

6

Nếu định nghĩa bảng của bạn là giá trị NOT NULL, bạn có thể đặt NEW thành NULL, có hiệu quả không làm việc chèn. Bạn có thể phải bật chế độ sql nghiêm ngặt để điều này hoạt động bình thường.

67

Tôi đã xem qua điều này và mặc dù giải pháp hoạt động sau này tôi bắt gặp những gì cảm thấy với tôi như một giải pháp tốt hơn. Tôi nghi ngờ đây không phải là một lựa chọn khi câu hỏi này ban đầu được trả lời.

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

Điều này sẽ trả về một thông báo lỗi đẹp (hoặc ác!) Mà bạn có thể bẫy. Để biết thêm thông tin về điều này, hãy xem: http://dev.mysql.com/doc/refman/5.5/en/signal.html

Tôi hy vọng điều này sẽ giúp người khác!

+2

Điều này thực sự tuyệt vời. Đã làm cho tôi. – rishad2m8

+1

Cảm ơn bạn. Tôi cần phải có một bảng và thực thi các phạm vi không trùng lặp và điều này cho phép tôi làm điều đó. – Kickstart

+1

Đây phải là câu trả lời được chấp nhận ... UP VOTE! – smashing

Các vấn đề liên quan