2017-09-13 5 views
0

Je suis en train d'exécuter cette requête dans une base de données via phpmyadminMySQL trigger BEFORE INSERT pour activer les clés primaires en double insère dans les mises à jour

create trigger avoid_duplicated_sharing 
before insert on sharingevents 
for each row 
begin 
    if (select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0) then 
     delete from sharingevents where shared_note_id = NEW.shared_note AND shared_to = NEW.shared_to 
    END IF; 
END 

Mais phpmyadmin me donne l'erreur suivante:

MySQL said: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END IF' at line 7

Deux questions:

  • Qu'est-ce qui ne va pas avec mon script?
  • Après un déclencheur BEFORE INSERT, l'opération Will INSERT sera-t-elle effectuée? Dans le cas où il n'a pas je vais devoir enlever INSERT INTO SharingEvents (SELECT * FROM NEW);
+0

Vous n'êtes pas tourner l'insert dans une mise à jour, vous tournez dans le même insert. – Barmar

+0

Vous avez raison, j'ai changé la requête à: 'supprimer from sharingevents où (shared_note = NEW.shared_note_id AND shared_to = NEW.shared_to);' – Maximetinu

+0

Quel est le problème avec 'INSERT INTO ... ON DUPLICATE KEY UPDATE' ou Requêtes 'INSERT IGNORE'? Ne correspondent-ils pas à votre cas d'utilisation? – Mjh

Répondre

0

Utilisation exists:

if (exists (select 1 from sharingevents where shared_note_id = new.shared_note_id AND shared_to = new.shared_to) > 0) then 
    insert into sharingevents (shared_note_id,shared_to,permission_level) 
     values (NEW.shared_note_id,NEW.shared_to,NEW.permission_level); 
end if; 

Ou, mieux encore, ajouter un index unique sur sharingevents(shared_note-id, shared_to) puis utilisez:

insert into sharingevents (shared_note_id, shared_to, permission_level) 
     values (NEW.shared_note_id, NEW.shared_to, NEW.permission_level) 
     on duplicate key update shared_note_id = values(shared_note_id); 

Cela ignorera toutes les mises à jour où les paires existent déjà dans la table. Non if requis.

+0

Même erreur:/ '# 1064 - Vous avez une erreur dans votre syntaxe SQL; vérifier le manuel qui correspond à votre version du serveur MariaDB pour la bonne syntaxe à utiliser près 'puis insérer dans sharingevents (shared_note_id, shared_to, permission_level)' à la ligne 5' – Maximetinu

+0

Les parenthèses sont déséquilibrées, et vous n'avez pas besoin d'utiliser '> 0' pour tester le résultat de 'exists()'. – Barmar

+0

Votre deuxième recommandation est bonne, mais il faudrait probablement changer le code de l'application qu'il ne veut pas toucher, donc il l'automatise avec le déclencheur. – Barmar

0

count(shared_note_id, shared_to) est une syntaxe invalide. Vous pouvez uniquement mettre plusieurs noms de colonnes à l'intérieur COUNT() lorsque vous utilisez count(DISTINCT ...). Dans votre cas, vous n'avez pas besoin de mettre des noms de colonnes, utilisez simplement COUNT(*) pour compter le nombre de lignes correspondant à la condition.

Voir count(*) and count(column_name), what's the diff? pour plus d'informations sur le moment où vous devez mettre les noms de colonnes dans COUNT()

Malheureusement, résolvez les erreurs de syntaxe ne sera pas vraiment résoudre votre problème, parce que vous ne pouvez pas utiliser un déclencheur pour faire un changement à la même table. De l'FAQ:

Can triggers access tables?
A trigger can access both old and new data in its own table. A trigger can also affect other tables, but it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.

Vous aurez besoin de recoder les appelants d'utiliser INSERT ... ON DUPLICATE KEY UPDATE, ou quelque chose d'équivalent, pour y parvenir.

+0

J'ai fait ce changement et oui, c'était une erreur! Merci. Mais même alors, cela ne fonctionne pas. Maintenant, il me donne une erreur à l'END IF – Maximetinu

0

je résous avec le code suivant:

delimiter $$ 

create trigger avoid_duplicated_sharing 
before insert on sharingevents 
for each row 
begin 
    if (select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0) then 
     delete from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to; 
    end if; 
END$$ 

Le problème était le delimiter.

Même ainsi, mon déclencheur ne fonctionne pas. Lorsque les inserts d'application clés primaires dupliqués MySQL lance l'erreur suivante:

#1442 - Can't update table 'sharingevents' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

+0

Les déclencheurs ne sont pas autorisés à modifier la même table sur laquelle ils sont déclenchés. – Barmar