【问题标题】:Cannot to create trigger properly无法正确创建触发器
【发布时间】:2019-12-16 23:36:49
【问题描述】:

Oracle 顶点,PL_Sql。 这是我的触发器:

CREATE OR REPLACE TRIGGER NoMoreThanOneHorse
    BEFORE INSERT OR UPDATE OF Jockey_ID
    ON Horses
    FOR EACH ROW
DECLARE
    NumOfHorsesForJockey NUMBER(4);
BEGIN
    SELECT COUNT(*) INTO NumOfHorsesForJockey FROM Horses
        WHERE Jockey_ID = :NEW.Jockey_ID AND Horse_ID <> :NEW.Horse_ID;
    IF NumOfHorsesForJockey > 0
        THEN RAISE_APPLICATION_ERROR (-20445, 'Нельзя закрепить за лошадью уже занятого жокея!');
        END IF;
END NoMoreThanOneHorse;

但每次我尝试创建它时都会出现此错误:ORA-24344:编译错误 ORA-06512 成功。我想这是因为语法不好

【问题讨论】:

  • 添加显示错误;在您的 pl/sql 块的末尾。它将在结果页面上显示确切的错误。
  • @Novice_Techie,我知道为什么,但它没有显示任何错误,只有我之前描述过的一个
  • 尝试使用END;而不是 END NoMoreThanOneHorse;在最后一行。
  • @Novice_Techie,同样的错误:c

标签: sql oracle plsql triggers


【解决方案1】:

我不知道编译时错误可能是什么 - 它对我来说编译得很好。但在运行时,您可能会收到“ORA-04091 Table HORSES is mutating, trigger cannot see it”错误。您无法在 HORSES 表上定义的 ROW 触发器中从 HORSES 中获取数据。

您需要将其更改为 AFTER STATEMENT 触发器,您可以通过在触发器定义中删除 FOR EACH ROW 并将触发点从 BEFORE 更改为 AFTER 来实现。问题是在语句触发器中,您无权访问:NEW:OLD 数据,但您并不真正需要它。每个执行的语句只调用一次语句触发器。所以你的触发器应该是这样的:

CREATE OR REPLACE TRIGGER NoMoreThanOneHorse
    AFTER INSERT OR UPDATE OF Jockey_ID
    ON Horses
DECLARE
    nMaxHorses  NUMBER;
BEGIN
    SELECT MAX(HORSE_COUNT)
      INTO nMaxHorses
      FROM (SELECT JOCKEY_ID, COUNT(*) AS HORSE_COUNT
              FROM Horses
              GROUP BY Jockey_ID);

    IF nMaxHorses > 1 THEN
      RAISE_APPLICATION_ERROR (-20445, 'Нельзя закрепить за лошадью уже занятого жокея!');
    END IF;
END NoMoreThanOneHorse;

你真的不在乎哪个骑师被分配了太多的马,只在乎有一个骑师骑过不止一匹马。

db<>fiddle here

【讨论】:

  • 如果这是一个真正的问题而不是家庭作业,除非表非常小并且很少插入,否则每次插入新行时对表进行全扫描并将数据分组是会很慢(而且很贵)。如果您想使用触发器,则需要一个行级触发器,它将更改的行放入一个集合中,并使用该集合来缩小语句级触发器运行的查询范围。
  • @JustinCave - 虽然 OP 可能 正在为赛道编写软件,但我强烈怀疑这是一项家庭作业,这就是我建议使用语句触发器的原因。 I agree that in the real world a compound trigger would be a better solution.
  • @BobJarvisReinstateMonica - 同意。只是为任何可能拥有真实系统的未来读者指出这一点。
  • @BobJarvisReinstateMonica - 让我享受我的幻想世界,好吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-13
  • 2019-04-14
  • 2022-06-16
  • 1970-01-01
相关资源
最近更新 更多