it-swarm-fr.com

Requête concernant la combinaison d'une mise à jour et une requête d'insertion dans une seule requête dans MySQL

je souhaite suivre l'historique des modifications d'un utilisateur, de sorte que chaque fois qu'il change de profil, je dois prendre les anciennes données et stocker dans l'histoire et mettre à jour avec de nouvelles données.

Je peux utiliser un select pour obtenir les anciennes données, un insert à l'historique et enfin un update pour modifier les données.

puis-je avoir toutes ces personnes dans une seule requête dans MySQL sans utiliser des procédures stockées, des déclencheurs, etc. comme utiliser des serrures, etc. Si cela me donne un petit échantillon.

9
Saravanan

Pour ce faire sans risque de bloquer un autre utilisateur essayant de mettre à jour le même profil en même temps, vous devez verrouille la ligne dans t1 Tout d'abord, utilisez-le ne transaction (comme Rolando souligne dans les commentaires à votre question):

start transaction;
select id from t1 where id=10 for update;
insert into t2 select * from t1 where id=10;
update t1 set id = 11 where id=10;
commit;

Je ne crois pas qu'il existe un moyen de combiner les trois déclarations. La chose la plus proche de cela ne vous aide pas vraiment, et c'est un choix défini. Votre meilleur pari est un déclencheur. Vous trouverez ci-dessous un échantillon d'un déclencheur que j'utilise souvent pour maintenir un tel sentier d'audit (construit avec PHP):

$trigger = "-- audit trigger --\nDELIMITER $ \n".
    "DROP TRIGGER IF EXISTS `{$prefix}_Audit_Trigger`$\n".
    "CREATE TRIGGER `{$prefix}_Audit_Trigger` AFTER UPDATE ON `$this->_table_name` FOR EACH ROW BEGIN\n";

foreach ($field_defs as $field_name => $field) {
    if ($field_name != $id_name) {
       $trigger .= "IF (NOT OLD.$field_name <=> NEW.$field_name) THEN \n".'INSERT INTO AUDIT_LOG ('.
                    'Table_Name, Row_ID, Field_Name, Old_Value, New_Value, modified_by, DB_User) VALUES'.
                    "\n ('$this->_table_name',OLD.$this->_id_name,'$field_name',OLD.$field_name,NEW.$field_name,".
                    "NEW.modified_by, USER()); END IF;\n";
    }
}
$trigger .= 'END$'."\n".'DELIMITER ;';
1
Bryan Agee