Триггер успешно скомпилирован, но не запускается - PullRequest
1 голос
/ 26 октября 2019

Я создаю базу данных, которая поддерживает оригинальную версию «Settlers of Catan», и хотя большая часть ее работает как задумано, этот триггер не работает.

Я работаю над Oracle 18c через SQLРазработчик вместе с Netbeans для связанного Java-приложения (это будет обсуждаться в другом вопросе).

Это следующие таблицы:

CREATE TABLE giocatore(
    numero INT,
    colore VARCHAR2(20),
    punto_partenza INT,
    punti_vittoria INT DEFAULT 0,
    vittorioso CHAR(1) DEFAULT 'f',
    quant_clay INT,
    quant_wool INT,
    quant_wheat INT,
    quant_wood INT,
    quant_rock INT,
    CONSTRAINT player_pk PRIMARY KEY(numero)
    );
CREATE TABLE esagono(
    numero INT,
    tipo VARCHAR2(30),
    terreno VARCHAR2(10),
    punti_vittoria INT,
    gettone INT,
    matprod VARCHAR2(20),
    quant_mat INT,
    occupato_da INT,
    occupato_in_turno INT,
    CONSTRAINT hexa_pk PRIMARY KEY(numero),
    CONSTRAINT ocp_fk FOREIGN KEY(occupato_in_turno) REFERENCES turno (numero_turno),
    CONSTRAINT mat_fk FOREIGN KEY(matprod) REFERENCES materia_prima (tipo),
    CONSTRAINT occ_fk FOREIGN KEY(occupato_da) REFERENCES giocatore (numero)
    );
CREATE TABLE materia_prima(
    tipo VARCHAR2(20),
    quantita INT,
    CONSTRAINT type_pk PRIMARY KEY(tipo)
    );
CREATE TABLE turno(
    numero_turno INT,
    val_dadi INT,
    CONSTRAINT turn_pk PRIMARY KEY(numero_turno)
    );

А вот и сам триггер:

create or replace TRIGGER generate_prime
AFTER INSERT ON turno
DECLARE valextracted INT; produced esagono.matprod%TYPE; quantity INT; occupied esagono.occupato_da%TYPE;
BEGIN
    SELECT val_dadi
    INTO valextracted
    FROM turno
    WHERE ROWNUM = 1
    ORDER BY numero_turno DESC;
    FOR record IN (SELECT matprod, quant_mat, occupato_da INTO produced, quantity, occupied FROM esagono WHERE gettone = valextracted)
    LOOP
        UPDATE materia_prima
        SET quantita = quantita + quantity
        WHERE tipo = produced;
        IF produced = 'Argilla' THEN
            UPDATE giocatore
            SET quant_clay = quant_clay + quantity
            WHERE numero = occupied;
        ELSIF produced = 'Grano' THEN
            UPDATE giocatore
            SET quant_wheat = quant_wheat + quantity
            WHERE numero = occupied;
        ELSIF produced = 'Lana' THEN
            UPDATE giocatore
            SET quant_wool = quant_wool + quantity
            WHERE numero = occupied;
        ELSIF produced = 'Legno' THEN
            UPDATE giocatore
            SET quant_wood = quant_wood + quantity
            WHERE numero = occupied;
        ELSIF produced = 'Minerali' THEN
            UPDATE giocatore
            SET quant_rock = quant_rock + quantity
            WHERE numero = occupied;
        END IF;
    END LOOP;
END;

Я ожидаютриггер для обновления GIOCATORE количественных / шерстяных / пшеничных / деревянных / каменных рядов и строки количественных показателей MATERIA_PRIMA в соответствии с количественным параметром ESAGONO, но этого не происходит. Есть идеи?

1 Ответ

0 голосов
/ 26 октября 2019

Мне кажется, я основал вашу проблему. Вы должны заменить эту часть:

FOR record IN (SELECT matprod
                  , quant_mat
                  , occupato_da 
           INTO produced
                , quantity
                , occupied 
           FROM esagono 
           WHERE gettone = valextracted)
LOOP

На это:

    FOR record IN (SELECT matprod
                          , quant_mat
                          , occupato_da 
                   FROM esagono 
                   WHERE gettone = valextracted)
    LOOP
        produced := record.matprod;
        quantity := record.quant_mat;
        occupied := record.occupato_da;

Вот триггер, который работает:

create or replace TRIGGER generate_prime
AFTER INSERT ON turno
DECLARE 
   valextracted INT; 
   produced esagono.matprod%TYPE; 
   quantity INT; 
   occupied esagono.occupato_da%TYPE;
BEGIN
    SELECT val_dadi
    INTO valextracted
    FROM turno
    WHERE ROWNUM = 1
    ORDER BY numero_turno DESC;

    FOR record IN (SELECT matprod
                          , quant_mat
                          , occupato_da 
                   FROM esagono 
                   WHERE gettone = valextracted)
    LOOP
        produced := record.matprod;
        quantity := record.quant_mat;
        occupied := record.occupato_da;

        UPDATE materia_prima
        SET quantita = quantita + quantity
        WHERE tipo = produced;

        IF produced = 'Argilla' THEN
            UPDATE giocatore
            SET quant_clay = quant_clay + quantity
            WHERE numero = occupied;
        ELSIF produced = 'Grano' THEN
            UPDATE giocatore
            SET quant_wheat = quant_wheat + quantity
            WHERE numero = occupied;
        ELSIF produced = 'Lana' THEN
            UPDATE giocatore
            SET quant_wool = quant_wool + quantity
            WHERE numero = occupied;
        ELSIF produced = 'Legno' THEN
            UPDATE giocatore
            SET quant_wood = quant_wood + quantity
            WHERE numero = occupied;
        ELSIF produced = 'Minerali' THEN
            UPDATE giocatore
            SET quant_rock = quant_rock + quantity
            WHERE numero = occupied;
        END IF;
    END LOOP;
END;

Надеюсь, это поможет!

...