2010-10-07 8 views
7

Esiste un modo per ottenere questo risultato?MySQL ON DUPLICATE KEY inserito in una tabella di controllo o registro

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

Io davvero non voglio utilizzare PHP per questo :(

Grazie!

+1

Credo che "no", a meno che non si utilizza una stored procedure per eseguire questa logica. –

risposta

8

Se si vuole considerare l'utilizzo di una stored procedure, è possibile utilizzare un DECLARE CONTINUE HANDLER Ecco un esempio:

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 ; 

Aggiungiamo alcuni dati, cercando di inserire una chiave duplicata:

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

Risultato:

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) 

Se il controllo è importante a livello di database, si può decidere per concedere le autorizzazioni EXECUTE solo affinché gli utenti del database possano chiamare solo stored procedure.

+0

Una procedura memorizzata o un trigger (come proposto da MatTheCat) risolverà questo problema ma la maggior parte dei provider di hosting non accetterà SP o trigger sui propri server, non so perché, suppongo un qualche tipo di sicurezza problema. – ricardocasares

+0

@ricardocasares: lo considererei un'opportunità per cambiare provider di hosting :) –

+0

Grazie mille Daniel !! Prenderò in considerazione di cambiare hosting;) e grazie mille per il grande esempio! – ricardocasares

0

ON DUPLICATE KEY viene utilizzato per aggiornare la riga, di non inserire in un'altra tabella, è necessario utilizzare due query secondo il risultato della prima

EDIT:.. è possibile utilizzare un trigger troppo

+0

"devi utilizzare due query in base al risultato del primo." Puoi spiegare un po 'di più o darmi un esempio di questo ?? Grazie mille! – ricardocasares

+0

Hai dimenticato questo dovresti usare PHP ^^ 'Usa un trigger o prova la soluzione di Daniel. – MatTheCat

+0

Grazie per le vostre risposte Mat;) – ricardocasares

0

Non sono sicuro se questo avrebbe funzionato, ma guardare in istruzione IF per MySQL

pseudo-codice

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

Grazie Phill, ci proverò! – ricardocasares

Problemi correlati