MySql Error: Tabelle kann nicht in gespeicherter function / Trigger aktualisiert werden, da sie bereits von einer statement verwendet wird, die diese gespeicherte function / diesen Trigger aufgerufen hat

Ich führe eine MySQL-Abfrage aus. Aber wenn eine neue Zeile von Formulareingabe hinzugefügt wird, erhalte ich diesen Fehler:

Error: Can't update table 'brandnames' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. 

Aus dem Code:

 CREATE TRIGGER `capital` AFTER INSERT ON `brandnames` FOR EACH ROW UPDATE brandnames SET bname = CONCAT( UCASE( LEFT( bname, 1 ) ) , LCASE( SUBSTRING( bname, 2 ) ) ) 

Was bedeutet dieser Fehler?

    Sie können eine Tabelle nicht ändern, während der INSERT-Trigger ausgetriggers wird. Die INSERT-Datei kann möglicherweise gesperrt werden, was zu einem Deadlock führen kann. Außerdem würde das Aktualisieren der Tabelle von einem Trigger bewirken, dass derselbe Trigger erneut in einer unendlichen rekursiven Schleife ausgetriggers wird. Aus diesen Gründen verhindert MySQL, dass Sie dies tun.

    Je nachdem, was Sie erreichen möchten, können Sie jedoch auf die neuen Werte zugreifen, indem Sie NEW.fieldname oder sogar die alten Werte – bei UPDATE – mit OLD verwenden.

    Wenn Sie eine Zeile mit dem Namen full_brand_name und die ersten beiden Buchstaben als Kurznamen im Feld small_name verwenden small_name , könnten Sie small_name verwenden:

     CREATE TRIGGER `capital` BEFORE INSERT ON `brandnames` FOR EACH ROW BEGIN SET NEW.short_name = CONCAT(UCASE(LEFT(NEW.full_name,1)) , LCASE(SUBSTRING(NEW.full_name,2))) END 

    Die korrekte Syntax ist:

     FOR EACH ROW SET NEW.bname = CONCAT( UCASE( LEFT( NEW.bname, 1 ) ) , LCASE( SUBSTRING( NEW.bname, 2 ) ) ) 

    Ein “BEFORE-INSERT” -Trigger ist die einzige Möglichkeit, Aktualisierungen derselben Tabelle auf einem Insert zu realisieren, und ist nur ab MySQL 5.5+ möglich. Der Wert eines Auto-Inkrement-Felds ist jedoch nur für einen “AFTER-INSERT” -Trigger verfügbar – im VORHER-Fall ist er standardmäßig auf 0 gesetzt. Daher wird der folgende Beispielcode, der einen zuvor berechneten Ersatzschlüsselwert basierend auf der Autoinkrementwert- id festlegen würde, kompilieren, aber nicht wirklich funktionieren, da NEW.id immer 0 ist:

     create table products(id int not null auto_increment, surrogatekey varchar(10), description text); create trigger trgProductSurrogatekey before insert on product for each row set NEW.surrogatekey = (select surrogatekey from surrogatekeys where id = NEW.id); 

    Ich habe das gleiche Problem und behebe durch Hinzufügen “neu”. bevor das Feld aktualisiert wird. Und ich poste hier den vollen Trigger für jemanden, der einen Trigger schreiben möchte

     DELIMITER $$ USE `nc`$$ CREATE TRIGGER `nhachung_province_count_update` BEFORE UPDATE ON `nhachung` FOR EACH ROW BEGIN DECLARE slug_province VARCHAR(128); DECLARE slug_district VARCHAR(128); IF old.status!=new.status THEN /* neu doi status */ IF new.status="Y" THEN UPDATE province SET `count`=`count`+1 WHERE id = new.district_id; ELSE UPDATE province SET `count`=`count`-1 WHERE id = new.district_id; END IF; ELSEIF old.province_id!=new.province_id THEN /* neu doi province_id + district_id */ UPDATE province SET `count`=`count`+1 WHERE id = new.province_id; /* province_id */ UPDATE province SET `count`=`count`-1 WHERE id = old.province_id; UPDATE province SET `count`=`count`+1 WHERE id = new.district_id; /* district_id */ UPDATE province SET `count`=`count`-1 WHERE id = old.district_id; SET slug_province = ( SELECT slug FROM province WHERE id= new.province_id LIMIT 0,1 ); SET slug_district = ( SELECT slug FROM province WHERE id= new.district_id LIMIT 0,1 ); SET new.prov_dist_url=CONCAT(slug_province, "/", slug_district); ELSEIF old.district_id!=new.district_id THEN UPDATE province SET `count`=`count`+1 WHERE id = new.district_id; UPDATE province SET `count`=`count`-1 WHERE id = old.district_id; SET slug_province = ( SELECT slug FROM province WHERE id= new.province_id LIMIT 0,1 ); SET slug_district = ( SELECT slug FROM province WHERE id= new.district_id LIMIT 0,1 ); SET new.prov_dist_url=CONCAT(slug_province, "/", slug_district); END IF; END; $$ DELIMITER ; 

    Hoffe, dass das jemandem hilft