Forum Stats

  • 3,759,181 Users
  • 2,251,510 Discussions
  • 7,870,526 Comments

Discussions

Trigger

Hola, tengo que hacer un Trigger para conseguir que "Las citas a una publicación deben ser siempre posteriores a ella", osea que una publicación_citada el año de codigo_publicacion sea mayor que el de codigo_publicacion_citada. Tengo este esquema de tablas y que no puedo modificar:

PUBLICACION(codigo_publicacion, titulo, año, tipo, medio)

AUTOR (login, nombre, apellidos, institución, pais)

AUTORIA (login, codigo_publicacion)

PUBLICACION_CITADA (codigo_publicacion, codigo_publicacion_citada)

Y no se como hacer un trigger que me funcione relacionando las dos tablas, básicamente tengo esto que adjunto

Create or replace trigger works_trg_01

Before insert or update on pubred

For each row

Declare

Cnt number;

Begin

Select count(1) into cnt

from pubred, pub_cita

where :new.cod_pub != cod_pub

And case when :new.año = año  then 1

Else 0 end = 0;

If cnt <> 0 then

Raise_application_error('-20001', 'Citas deben ser posteriores');

End if;

End works_trg_01;

/

Tagged:
Pabloc-Oracle

Answers

  • L. Fernigrini
    L. Fernigrini Data Engineer Sr Consultant Member Posts: 3,587 Silver Crown
    edited Dec 19, 2019 7:18AM

    El siguiente trigger puede funcionar, siempre y cuando no se cambie el año de la publicación, ahí si que el mismo no detectaria el problema. Incluyo todo el script (simplifiqué la tabla de publicaciones ya que solo nos interesa el año).

    Te recomiendo no usar caracteres especiales como la ñ en los nombres de tablas y columnas, te puede traer problemas (por eso usé "anio" en vez de "año".

    CREATE TABLE PUBLICACION(codigo_publicacion NUMBER, titulo VARCHAR2(100), anio NUMBER(4,0));

    CREATE TABLE PUBLICACION_CITADA (codigo_publicacion NUMBER, codigo_publicacion_citada NUMBER);

    --

    CREATE OR REPLACE TRIGGER tg_PUBLICACION_CITADA_iu

    BEFORE INSERT OR UPDATE ON PUBLICACION_CITADA

    FOR EACH ROW

    DECLARE

        vError NUMBER;

    BEGIN

        --

        SELECT COUNT(*)

        INTO vERROR

        FROM PUBLICACION po

        CROSS JOIN PUBLICACION pc

        WHERE po.codigo_publicacion = :NEW.codigo_publicacion

          AND pc.codigo_publicacion = :NEW.codigo_publicacion_citada

          AND pc.anio >= po.anio;

        --

        IF vError > 0 THEN

            RAISE_APPLICATION_ERROR ('-20001', 'Citas deben ser posteriores');

        END IF;

        --

    END tg_PUBLICACION_CITADA_iu;

    /

    INSERT INTO PUBLICACION VALUES (1, 'Titulo 1', 2010);

    INSERT INTO PUBLICACION VALUES (2, 'Titulo 2', 2010);

    INSERT INTO PUBLICACION VALUES (3, 'Titulo 3', 2011);

    INSERT INTO PUBLICACION VALUES (4, 'Titulo 4', 2012);

    --

    INSERT INTO PUBLICACION_CITADA VALUES (1,2);

    INSERT INTO PUBLICACION_CITADA VALUES (1,3);

    INSERT INTO PUBLICACION_CITADA VALUES (2,1);

    INSERT INTO PUBLICACION_CITADA VALUES (3,1);

    --

    SELECT * FROM PUBLICACION_CITADA;

    El resultado de los 4 INSERT en "publicacion_citada" y el SELECT a la misma tabla es el siguiente (probado en Oracle Live SQL):

    pastedImage_1.png

    Como veras, los tres primeros INSERT fallaron porque el año era menor o igual al de la publicación citada.

    Pabloc-Oracle
  • L. Fernigrini
    L. Fernigrini Data Engineer Sr Consultant Member Posts: 3,587 Silver Crown
    edited Dec 19, 2019 7:22AM

    Adicionalmente, cuando puedas, es buena idea cambiar tu nombre actual (415ece1e-3bed-441a-898c-93950f9c712f) por un nombre mas fácil de reconocer, acá se explica como hacerlo:

    Pabloc-OraclePabloc-Oracle