2008-11-27 12 views

Respuesta

6
`CREATE TRIGGER `category_before_ins_tr` BEFORE INSERT ON `category` 
    FOR EACH ROW 
BEGIN 
    **SET @tableId= (SELECT id FROM dummy LIMIT 1);** 

END;`; 
+1

Lo he editado para el formateo, por lo que es posible que desee comprobar para asegurarse de que sigue siendo sintácticamente correcto. –

1

o simplemente puede incluir la instrucción SELECT en el SQL que está invocando el gatillo, por lo que su pasado como una de las columnas de la fila (s) de disparo. Siempre que esté seguro, devolverá infaliblemente solo una fila (de ahí un valor). (Y, por supuesto, no debe devolver un valor que interactúe con la lógica en el desencadenador, pero eso es cierto en cualquier caso).

40

Puede declarar variables locales en desencadenantes MySQL, con la sintaxis DECLARE.

He aquí un ejemplo:

DROP TABLE IF EXISTS foo; 
CREATE TABLE FOO (
    i SERIAL PRIMARY KEY 
); 

DELIMITER // 
DROP TRIGGER IF EXISTS bar // 

CREATE TRIGGER bar AFTER INSERT ON foo 
FOR EACH ROW BEGIN 
    DECLARE x INT; 
    SET x = NEW.i; 
    SET @a = x; -- set user variable outside trigger 
END// 

DELIMITER ; 

SET @a = 0; 

SELECT @a; -- returns 0 

INSERT INTO foo() VALUES(); 

SELECT @a; -- returns 1, the value it got during the trigger 

Cuando se asigna un valor a una variable, debe asegurarse de que la consulta devuelve un solo valor, no un conjunto de filas o un conjunto de columnas. Por ejemplo, si su consulta arroja un valor único en la práctica, está bien, pero tan pronto como devuelve más de una fila, obtiene "ERROR 1242: Subquery returns more than 1 row".

Puede usar LIMIT o MAX() para asegurarse de que la variable local esté configurada en un único valor.

CREATE TRIGGER bar AFTER INSERT ON foo 
FOR EACH ROW BEGIN 
    DECLARE x INT; 
    SET x = (SELECT age FROM users WHERE name = 'Bill'); 
    -- ERROR 1242 if more than one row with 'Bill' 
END// 

CREATE TRIGGER bar AFTER INSERT ON foo 
FOR EACH ROW BEGIN 
    DECLARE x INT; 
    SET x = (SELECT MAX(age) FROM users WHERE name = 'Bill'); 
    -- OK even when more than one row with 'Bill' 
END// 
+0

¿Es posible almacenar un conjunto de resultados en una variable, o tiene que emitir consultas por separado? – sunwukung

+0

No, una variable solo puede almacenar un valor. Debe declarar un tipo de datos SQL para la variable, al igual que para una columna de una tabla.No hay ningún tipo de datos en MySQL que almacene un conjunto de resultados. –

+0

Es una pena que el usuario no esté presente para aceptar esta respuesta, porque es la correcta. –

5
CREATE TRIGGER clearcamcdr AFTER INSERT ON `asteriskcdrdb`.`cdr` 
FOR EACH ROW 
BEGIN 
    SET @INC = (SELECT sip_inc FROM trunks LIMIT 1); 
    IF NEW.billsec >1 AND NEW.channel LIKE @INC 
    AND NEW.dstchannel NOT LIKE "" 
    THEN 
    insert into `asteriskcdrdb`.`filtre` (id_appel,date_appel,source,destinataire,duree,sens,commentaire,suivi) 
     values (NEW.id,NEW.calldate,NEW.src,NEW.dstchannel,NEW.billsec,"entrant","",""); 
    END IF; 
END$$ 

No intentar esto @ home

0

Quiero poner esta solución porque tenía dificultades para encontrar lo que necesitaba. Esta publicación me acercó lo suficiente (+1 para eso gracias), y aquí está la solución final para reorganizar los datos de columna antes de insertar si los datos coinciden con una prueba.

Nota: esto es de un proyecto legado heredé donde:

  1. la clave única es un compuesto de rridprefix + rrid
  2. Antes de que me hice cargo no había ninguna restricción prevenir duplicar claves únicas
  3. Necesitamos combinar dos tablas (una llena de duplicados) en la tabla principal que ahora tiene la restricción en la clave compuesta (por lo que la fusión falla porque la tabla ganadora no permitirá los duplicados de la tabla sucia)
  4. on duplicate key es menos que ideal debido a que las columnas son demasiado numerosos y pueden cambiar

De todos modos, aquí es el disparador que pone duplicados de las llaves en una columna legado tiempo que nos permite almacenar el legado, los malos datos (y no activa la combinación de tablas ganadoras, clave única).

BEGIN 
    -- prevent duplicate composite keys when merging in archive to main 
    SET @EXIST_COMPOSITE_KEY = (SELECT count(*) FROM patientrecords where rridprefix = NEW.rridprefix and rrid = NEW.rrid); 

    -- if the composite key to be introduced during merge exists, rearrange the data for insert 
    IF @EXIST_COMPOSITE_KEY > 0 
    THEN 

    -- set the incoming column data this way (if composite key exists) 

    -- the legacy duplicate rrid field will help us keep the bad data 
    SET NEW.legacyduperrid = NEW.rrid; 

    -- allow the following block to set the new rrid appropriately 
    SET NEW.rrid = null; 

    END IF; 

    -- legacy code tried set the rrid (race condition), now the db does it 
    SET NEW.rrid = (
    SELECT if(NEW.rrid is null and NEW.legacyduperrid is null, IFNULL(MAX(rrid), 0) + 1, NEW.rrid) 
    FROM patientrecords 
    WHERE rridprefix = NEW.rridprefix 
); 
END 
Cuestiones relacionadas