触发不结束执行或输入

时间:2017-03-27 23:20:48

标签: sql database oracle

我必须在插入或更新某个关系之前检查关系A中的特定行属性是否等于或大于关系B中的相应行属性。我写了一个触发器:

尝试:

CREATE TRIGGER CandyCons AFTER INSERT, UPDATE ON Rel_A
AS
IF EXISTS (
          SELECT * FROM Rel_A A, Rel_B B WHERE A.ID = B.ID AND A.candy > B.too_much
          )
BEGIN
    RAISERROR ('Stop eating!', 16, 1);
    ROLLBACK TRANSACTION;
    RETURN; 
END;

我无法执行此操作。当我运行它时,我开始获得如下行号:

query
12
13
14
15
......... and so on

我该怎么办?

3 个答案:

答案 0 :(得分:2)

END;之后的行上,输入一个斜杠(/)告诉SQLPlus执行当前命令缓冲区。

另见When do I need to use a semicolon vs a slash in Oracle SQL?

(您的代码可能存在其他问题,其他答案可能会解决这些问题。但我相信这是您实际告诉SQLPlus编译和创建触发器的直接问题。)

答案 1 :(得分:1)

这可以使用行级TRIGGER来完成,如下例所示。

首先创建表格:

CREATE TABLE REL_B(ID NUMBER NOT NULL PRIMARY KEY, TOO_MUCH NUMBER);
CREATE TABLE REL_A(ID NUMBER NOT NULL REFERENCES REL_B(ID), CANDY NUMBER);

然后添加一些测试数据:

INSERT INTO REL_B VALUES (1,10);
INSERT INTO REL_B VALUES (2,20);
COMMIT;

然后创建你的TRIGGER:

CREATE OR REPLACE TRIGGER CANDYCONS
  AFTER INSERT OR UPDATE ON REL_A
  FOR EACH ROW
  DECLARE
    V_COUNT_TOO_MUCH_CANDY NUMBER := 0;
    BEGIN
    SELECT COUNT(*) INTO V_COUNT_TOO_MUCH_CANDY
      FROM REL_B
      WHERE REL_B.ID = :NEW.ID
      AND :NEW.CANDY > REL_B.TOO_MUCH;
    IF (V_COUNT_TOO_MUCH_CANDY > 0)
      THEN
      RAISE_APPLICATION_ERROR(-20144,'Stop eating!');
    END IF;
  END;
  /

然后测试:

没关系:

INSERT INTO REL_A VALUES (1,9);
INSERT INTO REL_A VALUES (1,10);

但这被阻止了:

INSERT INTO REL_A VALUES (1,11);
Error starting at line : 1 in command -
INSERT INTO REL_A VALUES (1,11)
Error report -
ORA-20144: Stop eating!

答案 2 :(得分:0)

我相信你打算这样:

Meteor.userId()

等待。 Oracle不支持CREATE TRIGGER CandyCons ON Rel_A BEFORE INSERT, UPDATE AS IF EXISTS (SELECT 1 FROM Rel_B B WHERE :NEW.ID = B.ID AND :NEW.candy > B.too_much ) BEGIN RAISERROR ('Stop eating!', 16, 1); ROLLBACK TRANSACTION; RETURN; END; 。它需要if exists。所以:

then