Как создать триггер или процедуру в Oracle Express для автоматизации значений в столбце таблицы - PullRequest
0 голосов
/ 01 января 2019

Как я могу ввести значение в столбец line_total, которое будет сделано учетной записью (sales_line.line_total = product.unit_price * sales_line.line_qty)?

Я хотел бы иметь триггер или процедуру для автоматизации этого.Когда я ввожу значения в столбцы, он автоматически запускает триггер, выполняя это вычисление и вставляя результат в столбец sales_line.line_total.

. Я также хотел бы автоматизировать столбец sale.sale_total, который будетсумма значений столбца sales_line.line_total.Можете ли вы сделать триггер или процедуру для этих двух вопросов?

вы можете мне помочь?

CREATE TABLE product (
    product_id    NUMBER(4) NOT NULL,
    category_id   NUMBER(4) NOT NULL,
    p_desc        VARCHAR2(40),
    cpu           VARCHAR2(14),
    ram           VARCHAR2(14),
    capacity      VARCHAR2(14),
    screen_size   VARCHAR2(14),
    battery       VARCHAR2(14),
    unit_price    NUMBER(7, 2),
    colour        VARCHAR2(14),
    qty_stock     NUMBER(4)
);
ALTER TABLE product ADD CONSTRAINT product_pk PRIMARY KEY ( product_id );

CREATE TABLE sale (
    sale_id       NUMBER(4) NOT NULL,
    sale_date     DATE,
    customer_id   NUMBER(4) NOT NULL,
    employee_id   NUMBER(4) NOT NULL,
    sale_total    NUMBER(7, 2)
);

ALTER TABLE sale ADD CONSTRAINT sale_pk PRIMARY KEY ( sale_id );

CREATE TABLE sales_line (
    sale_id      NUMBER(4) NOT NULL,
    product_id   NUMBER(4) NOT NULL,
    line_qty     NUMBER(4),
    line_total   NUMBER(7, 2)
);

ALTER TABLE sales_line ADD CONSTRAINT index_3 PRIMARY KEY ( sale_id,
                                                            product_id );

ALTER TABLE product
    ADD CONSTRAINT product_p_category_fk FOREIGN KEY ( category_id )
        REFERENCES p_category ( category_id );

ALTER TABLE sale
    ADD CONSTRAINT sale_customer_fk FOREIGN KEY ( customer_id )
        REFERENCES customer ( customer_id );

ALTER TABLE sale
    ADD CONSTRAINT sale_employee_id_fk FOREIGN KEY ( employee_id )
        REFERENCES employee ( employee_id );

ALTER TABLE sales_line
    ADD CONSTRAINT sales_line_product_fk FOREIGN KEY ( product_id )
        REFERENCES product ( product_id );

ALTER TABLE sales_line
    ADD CONSTRAINT sales_line_sale_fk FOREIGN KEY ( sale_id )
        REFERENCES sale ( sale_id );

Вот триггеры, которые я написал до сих пор:

CREATE OR REPLACE TRIGGER trg_line_total_ai AFTER INSERT OR UPDATE ON sales_line
FOR EACH ROW
DECLARE
    lt_value NUMBER(7,2);
BEGIN
    SELECT product.unit_price INTO lt_value FROM product;
    UPDATE sales_line
    SET line_total = :NEW.line_qty * lt_value
   -- SET line_total = (line_qty * :NEW.unit_price)   
    WHERE product_id = :NEW.product_id;

    --UPDATE sales_line
      --  SET line_total = (line_qty * :OLD.unit_price)
        --WHERE product.product_id = :OLD.product_id;
END;


CREATE OR REPLACE TRIGGER trg_sale_total_ai AFTER INSERT OR UPDATE ON sales_line
FOR EACH ROW
BEGIN     
    UPDATE sale     
    SET sale_total = (sale_total + :NEW.line_total)   
    WHERE sale_id = :NEW.sale_id;

    UPDATE sale
        SET sale_total = (sale_total + :OLD.line_total)
        WHERE sale_id = :OLD.sale_id;
END;

Ответы [ 3 ]

0 голосов
/ 01 января 2019

Используйте следующий код вместо.Обратите внимание на ключевое слово «До» вместо «После» в определениях обоих триггеров

CREATE OR REPLACE TRIGGER trg_line_total_ai BEFORE INSERT OR UPDATE ON sales_line
    FOR EACH ROW
    DECLARE
        lt_value NUMBER(7,2);
    BEGIN
        SELECT product.unit_price INTO lt_value FROM product;
        UPDATE sales_line
        SET line_total = :NEW.line_qty * lt_value
       -- SET line_total = (line_qty * :NEW.unit_price)   
        WHERE product_id = :NEW.product_id;

        --UPDATE sales_line
          --  SET line_total = (line_qty * :OLD.unit_price)
            --WHERE product.product_id = :OLD.product_id;
    END;


    CREATE OR REPLACE TRIGGER trg_sale_total_ai BEFORE INSERT OR UPDATE ON sales_line
    FOR EACH ROW
    BEGIN     
        UPDATE sale     
        SET sale_total = (sale_total + :NEW.line_total)   
        WHERE sale_id = :NEW.sale_id;

        UPDATE sale
            SET sale_total = (sale_total + :OLD.line_total)
            WHERE sale_id = :OLD.sale_id;
    END;
0 голосов
/ 01 января 2019

У вас есть две основные проблемы.Первый (как отмечено в других ответах) заключается в том, что первым триггером должен быть триггер до , который изменяет записи на месте.Логика для триггера также может быть упрощена (как показано ниже)

Вторым вопросом является то, что вы должны вычитать old значения во втором триггере.Итак:

CREATE OR REPLACE TRIGGER trg_line_total_ai
    BEFORE INSERT OR UPDATE ON sales_line
FOR EACH ROW
BEGIN
    SELECT :NEW.line_qty * p.unit_price
    INTO :NEW.line_total
    FROM product p
    WHERE p.product_id = :NEW.product_id;
END;


CREATE OR REPLACE TRIGGER trg_sale_total_ai
    AFTER INSERT OR UPDATE ON sales_line
FOR EACH ROW
BEGIN     
    UPDATE sale     
        SET sale_total = (sale_total + :NEW.line_total)   
        WHERE sale_id = :NEW.sale_id;

    UPDATE sale
        SET sale_total = (sale_total - :OLD.line_total)
        WHERE sale_id = :OLD.sale_id;
END;

Обратите внимание, что второй триггер имеет два обновления.Это позволяет обновлять sale_id.Вы можете обернуть это в одно обновление, если хотите:

    UPDATE sale     
        SET sale_total = (sale_total + 
                          (CASE WHEN sale_id = :NEW.sale_id THEN :NEW.line_total ELSE 0 END) -
                          (CASE WHEN sale_id = :OLD.sale_id THEN :OLD.line_total ELSE 0 END)
                         )  
        WHERE sale_id IN (:OLD.sale_id, :NEW.sale_id);

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

0 голосов
/ 01 января 2019

Чтобы обновить sale_line, вы должны использовать триггер «до», тогда обновление по этой таблице не требуется.Только присвоить значение: New.line_total.Чтобы обновить продажи вы можете сделать это в триггере дамы.

...