2010-10-07 25 views
7

Có cách nào để thực hiện việc này không?MySQL TRÊN KHÓA TỪ KHÓA vào bảng kiểm tra hoặc nhật ký

INSERT IGNORE INTO some_table (one,two,three) VALUES(1,2,3) 
ON DUPLICATE KEY (INSERT INTO audit_table VALUES(NOW(),'Duplicate key ignored') 

tôi thực sự không muốn sử dụng PHP cho điều này :(

Cảm ơn!

+1

Tôi đoán "không", trừ khi bạn sử dụng một thủ tục lưu trữ để thực hiện logic này. –

Trả lời

8

Nếu bạn muốn xem xét sử dụng một thủ tục lưu trữ, bạn có thể sử dụng một DECLARE CONTINUE HANDLER Dưới đây là một ví dụ:

CREATE TABLE users (
    username VARCHAR(30), 
    first_name VARCHAR(30), 
    last_name VARCHAR(30), 
    PRIMARY KEY (username) 
); 

CREATE TABLE audit_table (timestamp datetime, description varchar(255)); 

DELIMITER $$ 
CREATE PROCEDURE add_user 
     (in_username VARCHAR(30), 
     in_first_name VARCHAR(30), 
     in_last_name VARCHAR(30)) 
    MODIFIES SQL DATA 
BEGIN 
    DECLARE duplicate_key INT DEFAULT 0; 
    BEGIN 
     DECLARE EXIT HANDLER FOR 1062 SET duplicate_key = 1; 

     INSERT INTO users (username, first_name, last_name) 
       VALUES (in_username, in_first_name, in_last_name); 
    END; 

    IF duplicate_key = 1 THEN 
     INSERT INTO audit_table VALUES(NOW(), 'Duplicate key ignored'); 
    END IF; 
END$$ 
DELIMITER ; 

Hãy thêm một số dữ liệu, cố gắng để chèn một khóa trùng lặp:

CALL add_user('userA', 'Bob', 'Smith'); 
CALL add_user('userB', 'Paul', 'Green'); 
CALL add_user('userA', 'Jack', 'Brown'); 

Kết quả:

SELECT * FROM users; 
+----------+------------+-----------+ 
| username | first_name | last_name | 
+----------+------------+-----------+ 
| userA | Bob  | Smith  | 
| userB | Paul  | Green  | 
+----------+------------+-----------+ 
2 rows in set (0.00 sec) 

SELECT * FROM audit_table; 
+---------------------+-----------------------+ 
| timestamp   | description   | 
+---------------------+-----------------------+ 
| 2010-10-07 20:17:35 | Duplicate key ignored | 
+---------------------+-----------------------+ 
1 row in set (0.00 sec) 

Nếu kiểm toán là rất quan trọng về mặt kĩ cơ sở dữ liệu, bạn có thể muốn chỉ cấp cho các quyền EXECUTE để người dùng cơ sở dữ liệu của bạn chỉ có thể gọi các thủ tục được lưu trữ.

+0

Thủ tục lưu trữ hoặc trình kích hoạt (như MatTheCat được đề xuất) sẽ giải quyết vấn đề này nhưng hầu hết các nhà cung cấp dịch vụ lưu trữ sẽ không chấp nhận SP hoặc trình kích hoạt trên máy chủ của họ, không biết tại sao, tôi đoán một số loại bảo mật vấn đề. – ricardocasares

+0

@ricardocasares: Tôi sẽ coi đó là cơ hội để chuyển đổi nhà cung cấp dịch vụ lưu trữ :) –

+0

Cảm ơn bạn rất nhiều Daniel !! Tôi sẽ xem xét để chuyển đổi lưu trữ;) và cảm ơn rất nhiều cho ví dụ tuyệt vời đó! – ricardocasares

0

ON DUPLICATE KEY được sử dụng để cập nhật hàng, không để chèn vào bảng khác, bạn phải sử dụng hai truy vấn tùy theo kết quả đầu tiên của

EDIT:.. bạn có thể sử dụng một kích hoạt quá

+0

"bạn phải sử dụng hai truy vấn theo kết quả đầu tiên." Bạn có thể giải thích thêm một chút hoặc cho tôi một ví dụ về điều này không ?? Cảm ơn bạn rất nhiều! – ricardocasares

+0

Quên điều này bạn sẽ phải sử dụng PHP ^^ 'Sử dụng một kích hoạt hoặc thử giải pháp của Daniel. – MatTheCat

+0

Cảm ơn câu trả lời của bạn Mat;) – ricardocasares

0

Không chắc chắn nếu điều này sẽ làm việc nhưng nhìn vào NẾU tuyên bố cho MySQL

Pseudo-code

IF(SELECT id_key_index FROM tbl WHERE id_key_index = $index) THEN (UPDATE SECOND TBL); 
    ELSE 
     INSERT ... 
    END IF; 
+0

Cảm ơn bạn Phill, tôi sẽ thử! – ricardocasares

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