respuesta - Error de MySql: no se puede actualizar la tabla en la función/desencadenador almacenado porque ya está siendo utilizada por la instrucción que invoca esta función/disparador almacenado
mysqld exe consume mucha memoria (4)
Estoy ejecutando una consulta de MySQL. Pero cuando se agrega una nueva fila desde la entrada del formulario, obtengo este error:
Error: Can''t update table ''brandnames'' in stored function/trigger because it is
already used by statement which invoked this stored function/trigger.
Del código:
CREATE TRIGGER `capital` AFTER INSERT ON `brandnames`
FOR EACH
ROW UPDATE brandnames
SET bname = CONCAT( UCASE( LEFT( bname, 1 ) ) , LCASE( SUBSTRING( bname, 2 ) ) )
¿Qué significa este error?
La sintaxis correcta es:
FOR EACH ROW SET NEW.bname = CONCAT( UCASE( LEFT( NEW.bname, 1 ) )
, LCASE( SUBSTRING( NEW.bname, 2 ) ) )
No puede cambiar una tabla mientras se dispara el disparador INSERTAR. El INSERT podría hacer un bloqueo que podría provocar un punto muerto. Además, la actualización de la tabla desde un desencadenador provocaría que el mismo activador vuelva a disparar en un ciclo recursivo infinito. Ambas razones explican por qué MySQL le impide hacer esto.
Sin embargo, dependiendo de lo que esté tratando de lograr, puede acceder a los nuevos valores usando NEW.fieldname o incluso los valores anteriores (si está ACTUALIZANDO) con OLD.
Si tuviera una fila llamada full_brand_name
y quisiera usar las primeras dos letras como un nombre corto en el campo small_name
, podría usar:
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
Tengo el mismo problema y soluciono agregando "nuevo". antes de que el campo se actualice Y publico activador completo aquí para que alguien quiera escribir un disparador
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 ;
Espero que esto ayude a alguien
Un activador "ANTES DE INSERTAR" es la única forma de realizar actualizaciones de la misma tabla en una inserción, y solo es posible desde MySQL 5.5+. Sin embargo, el valor de un campo de incremento automático solo está disponible para un desencadenante "DESPUÉS DE INSERTAR"; por defecto, es 0 en el caso ANTES. Por lo tanto, se compilará el siguiente código de ejemplo que establecería un valor de clave sustituta calculado previamente basado en el id
valor de incremento automático, pero no funcionaría realmente ya que NEW.id siempre será 0:
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);