Oracle触发器:SELECT INTO,未找到数据

问题描述 投票:1回答:1

我有一张下表描述了每个行星使用百分比组成的化学元素。

CREATE TABLE elem_in_planet
(
    id_planet INTEGER,
    element_symbol CHAR(2),
    percent_representation NUMBER CONSTRAINT NN_elem_in_planet NOT NULL,

    CONSTRAINT PK_elem_in_planet PRIMARY KEY (id_planet, element_symbol),
    CONSTRAINT FK_planet_has_elem FOREIGN KEY (id_planet) REFERENCES planet (id_planet),
    CONSTRAINT FK_elem_in_planet FOREIGN KEY (element_symbol) REFERENCES chemical_element (element_symbol)
);

我正在尝试创建一个触发器,当用户向行星添加新元素并且该行星中的元素总数超过100%时向用户发出警告。我想到了这个。

CREATE OR REPLACE TRIGGER elem_in_planet_check
    AFTER INSERT OR UPDATE ON elem_in_planet
    FOR EACH ROW
DECLARE
    sum_var NUMBER;
    PRAGMA autonomous_transaction;
BEGIN
    SELECT SUM(percent_representation)
    INTO sum_var
    FROM elem_in_planet
    WHERE id_planet = :NEW.id_planet
    GROUP BY id_planet;

    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            sum_var := 0;

    IF sum_var > 100 THEN
        DBMS_OUTPUT.put_line('WARNING: Blah blah.');
    END IF;
END;
/

此代码似乎每次都抛出NO_DATA_FOUND异常,即使我插入了测试数据,并且当我单独运行SQL查询时,它也按预期运行。

我是新来的,不明白我在做什么错。

谢谢您的任何建议。

sql oracle plsql database-trigger
1个回答
0
投票

删除PRAGMA autonomous_transaction,否则您将看不到表中插入的数据(您只会在:NEW记录中看到它。See also this question

也请注意,您的IF语句位于EXCEPTION .. WHEN no_data_found THEN块中。它不会执行,除非有这样的异常(在sum_var始终为零的情况下。这是触发器的更正确的版本:

CREATE OR REPLACE TRIGGER elem_in_planet_check
    AFTER INSERT OR UPDATE ON elem_in_planet
    FOR EACH ROW
DECLARE
    sum_var NUMBER;
BEGIN
    SELECT SUM(percent_representation)
    INTO sum_var
    FROM elem_in_planet
    WHERE id_planet = :NEW.id_planet;

    IF sum_var > 100 THEN
        DBMS_OUTPUT.put_line('WARNING: Blah blah.');
    END IF;

-- This is probably no longer necessary unless some other trigger prevents the insertion
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        NULL;
END;
/
© www.soinside.com 2019 - 2024. All rights reserved.