使用编译错误创建触发器

时间:2011-10-19 08:06:02

标签: sql oracle triggers oracle10g

我写了这个触发器,在新购买时将数据库中的顶级客户折扣10%:

CREATE or REPLACE TRIGGER CLIENT_DISCOUNT
  BEFORE INSERT
  ON PURCHASE
  FOR EACH ROW
DECLARE
  CLIENTNO  NUMBER(5);
BEGIN
  SELECT (SELECT CLIENT.CLIENTNO, CLIENT.CNAME, TOTALS.TOTAL FROM CLIENT, 
    (SELECT CLIENTNO, SUM(AMOUNT) AS TOTAL FROM PURCHASE GROUP BY CLIENTNO) TOTALS WHERE CLIENT.CLIENTNO = TOTALS.CLIENTNO  AND ROWNUM <= 1 ORDER BY TOTALS.TOTAL DESC).CLIENTNO INTO CLIENTNO;
  IF :NEW.CLIENTNO = CLIENTNO THEN
    :NEW.AMOUNT = (:NEW.AMOUNT * 0.1);
  END IF;
END;

但是,当我执行此语句时,我会收到以下消息:

Warning: Trigger created with compilation errors.

有人可以告诉我我做错了吗?

谢谢, 亚历克斯。

更新 - 错误:

Errors for TRIGGER CLIENT_DISCOUNT:

LINE/COL
--------------------------------------------------------------------------------
ERROR
--------------------------------------------------------------------------------
4/3
PL/SQL: SQL Statement ignored

5/141
PL/SQL: ORA-00907: missing right parenthesis

7/17
PLS-00103: Encountered the symbol "=" when expecting one of the following:


LINE/COL
--------------------------------------------------------------------------------
ERROR
--------------------------------------------------------------------------------
   := . ( @ % ; indicator

8/3
PLS-00103: Encountered the symbol "END"

解决方案:

CREATE or REPLACE TRIGGER CLIENT_DISCOUNT
    BEFORE INSERT
    ON PURCHASE
    FOR EACH ROW
DECLARE
    vCLIENTNO  NUMBER(5);
BEGIN
    SELECT TOPCLIENT.CLIENTNO INTO vCLIENTNO FROM (SELECT CLIENT.CLIENTNO, CLIENT.CNAME, TOTALS.TOTAL FROM CLIENT, (SELECT CLIENTNO, SUM(AMOUNT) AS TOTAL FROM PURCHASE GROUP BY CLIENTNO) TOTALS WHERE CLIENT.CLIENTNO = TOTALS.CLIENTNO  AND ROWNUM <= 1 ORDER BY TOTALS.TOTAL DESC) TOPCLIENT;
    IF :NEW.CLIENTNO = vCLIENTNO THEN
        :NEW.AMOUNT := (:NEW.AMOUNT * 0.9);
    END IF;
END;
/

3 个答案:

答案 0 :(得分:5)

我没有你的桌子,所以我无法保证我找到了你所有的错误。但是,我可以说以下内容:

  1. 我认为你不能做SELECT (....).CLIENTNO。请改为SELECT x.CLIENTNO FROM (....) x
  2. 您最外面的SELECT没有FROM条款。请尝试添加FROM DUAL,因为此最外层SELECT未从任何表中进行选择。
  3. PL / SQL赋值运算符为:=,而不是=。要分配到:NEW.AMOUNT,您需要撰写:NEW.AMOUNT := (:NEW.AMOUNT * 0.1);
  4. 将金额乘以0.1可为客户提供90%的折扣,而不是10%的折扣。

答案 1 :(得分:1)

CREATE or REPLACE TRIGGER CLIENT_DISCOUNT
  BEFORE INSERT
  ON PURCHASE
  FOR EACH ROW
DECLARE
  vCLIENTNO  NUMBER(5);
BEGIN
  SELECT Z.CLIENTNO INTO vCLIENTNO FROM (SELECT CLIENT.CLIENTNO, CLIENT.CNAME, TOTALS.TOTAL FROM CLIENT, 
    (SELECT CLIENTNO, SUM(AMOUNT) AS TOTAL FROM PURCHASE GROUP BY CLIENTNO) TOTALS WHERE CLIENT.CLIENTNO = TOTALS.CLIENTNO  AND ROWNUM <= 1 ORDER BY TOTALS.TOTAL DESC) Z;
  IF :NEW.CLIENTNO = vCLIENTNO THEN
    :NEW.AMOUNT := (:NEW.AMOUNT * 1.091);
  END IF;
END;

答案 2 :(得分:1)

除了其他人识别的语法错误之外,很可能您正在获得一个变异触发器,因为您无法从正在插入的表中进行选择。

如果您可以更改数据模型,则可能需要在另一个表中标识顶级客户端,而不是在插入该表时尝试选择金额购买表的总和。