2010-10-07 17 views
7

Existe-t-il un moyen d'accomplir ceci?MySQL ON DUPLICATE KEY insérer dans un audit ou une table de journal

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

Je ne veux vraiment pas utiliser PHP pour ce :(

Merci!

+1

Je suppose que « non », à moins que vous utilisez une procédure stockée pour effectuer cette logique. –

Répondre

8

Si vous voulez envisager d'utiliser une procédure stockée, vous pouvez utiliser un DECLARE CONTINUE HANDLER Voici un exemple:

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 ; 

Ajoutons quelques données, en essayant d'insérer une clé en double:

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

Résultat:

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) 

Si l'audit est important au niveau de la base de données, vous pouvez pour accorder les autorisations EXECUTE uniquement afin que les utilisateurs de votre base de données puissent uniquement appeler des procédures stockées.

+0

Une procédure stockée ou un déclencheur (comme proposé par MatTheCat) résoudra ce problème mais la plupart des hébergeurs n'accepteront pas les SP ou les triggers sur leurs serveurs, je ne sais pas pourquoi, je suppose que problème. – ricardocasares

+0

@ricardocasares: Je traiterais cela comme une opportunité de changer de fournisseur d'hébergement :) –

+0

Merci beaucoup Daniel !! Je vais envisager de changer d'hébergement;) et merci beaucoup pour ce bel exemple! – ricardocasares

0

Duplicate KEY est utilisé pour mettre à jour la ligne, ne pas insérer dans une autre table, vous devez utiliser deux requêtes selon le premier résultat de

EDIT:.. vous pouvez utiliser un déclencheur trop

+0

"vous devez utiliser deux requêtes selon le résultat du premier." Pouvez-vous expliquer un peu plus loin ou donnez-moi un exemple de ceci? Merci beaucoup! – ricardocasares

+0

Oublié cela vous devriez utiliser PHP ^^ 'Utilisez un déclencheur ou essayez la solution de Daniel. – MatTheCat

+0

Merci pour vos réponses Mat;) – ricardocasares

0

Je ne sais pas si cela fonctionnerait, mais examiner instruction IF pour MySQL

pseudo-code

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

Merci Phill, je vais essayer! – ricardocasares