1. ホーム
  2. sql

[解決済み] トリガーがコンパイルエラーで作成される

2022-02-07 05:06:03

質問

新規購入時にデータベース内のトップクライアントを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.

どなたか、私が何を間違えているのか教えていただけませんか?

ありがとうございます。 アレックス

UPDATE - エラーです。

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;
/

解決方法は?

あなたのテーブルが手元にないので、すべてのエラーを発見できたかどうかは保証できません。 しかし、次のことは言えます。

  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倍すると、クライアントは10%割引ではなく、90%割引になります。