【问题标题】:Oracle - How to force user to INSERT multiple rowOracle - 如何强制用户插入多行
【发布时间】:2014-06-07 01:37:33
【问题描述】:

我在学术作业中使用 Oracle 11gR2。有一个限制,一个房间必须有 3 - 5 人。我知道我可以编写这样的触发器来检查房间是否超过 5 人:

CREATE TABLE People
(
  PID INTEGER PRIMARY KEY
);

CREATE TABLE Room
(
  RID INTEGER PRIMARY KEY
);

CREATE TABLE Living
(
  RID INTEGER,
  PID INTEGER,
  CONSTRAINT Living_PK PRIMARY KEY (RID, PID),
  CONSTRAINT Living_FK_RID FOREIGN KEY (RID) REFERENCES Room(RID),
  CONSTRAINT Living_FK_PID FOREIGN KEY (PID) REFERENCES People(PID)
);

CREATE OR REPLACE TRIGGER Living_BIU
  BEFORE INSERT OR UPDATE ON Living
  REFERENCING NEW AS NEW OLD AS OLD
  FOR EACH ROW
DECLARE
  Count NUMBER;
BEGIN
  SELECT COUNT(*)
    INTO Count
    FROM Living
    WHERE RID = :NEW.RID;
  IF(Count > 5)
  THEN
    RAISE_APPLICATION_ERROR(-20002, 'Too many people in a room.');
  END IF;
END Living_BI;

但我无法检查数字是否小于 3,因为这样我就无法在 Living 中插入任何东西。所以我的问题是如何创建一个触发器来强制用户一次插入多于 3 行且少于 5 行?

【问题讨论】:

    标签: sql oracle triggers oracle-sqldeveloper


    【解决方案1】:

    按照标准的序言,这不是你在现实世界中真正做这种事情的方式......

    您实际上需要在此处使用语句级触发器。如果您不介意每次检查每个房间对性能的影响

    CREATE OR REPLACE TRIGGER Living_AIUD
      AFTER INSERT OR UPDATE OR DELETE
      ON Living
    DECLARE
      Count NUMBER;
    BEGIN
      FOR x IN (SELECT rid, count(*) cnt
                  FROM living
                 GROUP BY rid
                HAVING COUNT(*) < 3)
      LOOP
        RAISE_APPLICATION_ERROR(-20002, 'Too few people in room ' || x.rid);
      END LOOP;
    END Living_AIUD;
    

    如果您不想每次都检查每个房间,您需要一个包含 rid 值集合的包、一个初始化集合的 before 语句触发器和一个添加的行级触发器集合的 :new.rid 值。然后,您的 after 语句触发器将遍历集合中的元素并检查这些房间中的人数。

    【讨论】:

    • 对不起,我是这方面的新手,你能解释一下什么是“包”和“集合”吗?
    • @Tr1et - 您可以在此线程 stackoverflow.com/questions/23115966/… 中看到此类方法的示例我在回答中概述了更简单、效率更低的方法。
    • 那么当 APPLICATION_ERROR 上升时,该行是插入还是阻塞?
    • @Tr1et - 如果引发错误,则语句将失败,并且该语句已完成的工作将回滚。
    • 好的,我现在明白了,所以唯一的缺点是检查所有房间,但这是否意味着当一个房间人太少时我不能插入其他房间?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    • 2013-01-04
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多