Триггер, созданный с ошибками компиляции
Я написал этот триггер, чтобы дисконтировать топ-клиента в базе данных на 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 ответа:
У меня нет ваших таблиц, поэтому я не могу гарантировать, что нашел все ваши ошибки. Однако я могу сказать следующее:
- я не верю, что вы можете сделать
SELECT (....).CLIENTNO
. ПопробуйтеSELECT x.CLIENTNO FROM (....) x
вместо этого.- ваш самый внешний
SELECT
не имеет предложенияFROM
. Попробуйте добавитьFROM DUAL
, так как этот внешнийSELECT
не выбирает ни из одной таблицы.- оператор присваивания PL/SQL-это
:=
, а не=
. Чтобы назначить:NEW.AMOUNT
, нужно написать:NEW.AMOUNT := (:NEW.AMOUNT * 0.1);
.- умножение суммы на 0,1 дает клиенту скидку 90%, а не 10%.
Попробуйте
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;
Помимо синтаксических ошибок, выявленных другими, скорее всего, вы получаете мутирующий триггер, поскольку не можете выбрать из таблицы, в которую вставляете.
Если вы можете изменить модель данных, возможно, вам нужно определить главного клиента в другой таблице, а не пытаться выбрать таблицу сумма сумм покупки, когда вы также вставляете в эту таблицу.