Как создать программу PL / SQL для обновления платы за обучение, когда статус активен?

#oracle #plsql

#Oracle #plsql

Вопрос:

Я новичок в PL / SQL, и у меня есть таблица под названием STUDENT, и она содержит следующие столбцы: REGNO, ИМЯ, FNAME, МЕСТО ЖИТЕЛЬСТВА, СБОРЫ, СТАТУС. что я хочу сделать, так это при создании новой записи, и если, например, место жительства студента, DOMICILE = 'TEXAS' и STATUS = 'ACTIVE' тогда я хочу предоставить скидку 50% на СБОРЫ. Вот мой код:

 CREATE OR REPLACE TRIGGER MYTRIGGER
BEFORE INSERT ON STUDENT
FOR EACH ROW
BEGIN
IF :NEW.DOMICILE = 'TEXAS' AND :NEW.STATUS = 'ACTIVE' THEN
UPDATE STUDENT SET FEES = FEES - 0.50 * FEES;
END IF;
END MYTRIGGER;
/
  

триггер создается, но он не работает должным образом..
пример:

 SQL> INSERT INTO STUDENT VALUES(1,'MARK','SMITH','TEXAS',5000,'ACTIVE');

1 row created.

SQL> SELECT * FROM STUDENT;

     REGNO NAME                           FNAME                          DOMICILE                          FEES STATUS
---------- ------------------------------ ------------------------------ ------------------------------ ---------- --------------------
         1 MARK                           SMITH                          TEXAS                                5000 ACTIVE

SQL> INSERT INTO STUDENT VALUES(2,'JAMES','FORD','TEXAS',5000,'ACTIVE');

1 row created.

SQL> INSERT INTO STUDENT VALUES(3,'SAM','MILLER','NEW JERSEY',5000,'ACTIVE');

1 row created.

SQL> SELECT * FROM STUDENT;

     REGNO NAME                           FNAME                          DOMICILE                          FEES STATUS
---------- ------------------------------ ------------------------------ ------------------------------ ---------- --------------------
         1 MARK                           SMITH                          TEXAS                                2500 ACTIVE
         2 JAMES                          FORD                           TEXAS                                5000 ACTIVE
         3 SAM                            MILLER                         NEW JERSEY                           5000 ACTIVE

SQL>
  

есть предложения?

Комментарии:

1. «это не работает должным образом»: пожалуйста, объясните, что вы имеете в виду под этим. Если вы получаете сообщение об ошибке, пожалуйста, отредактируйте свой вопрос, чтобы включить полную информацию об ошибке.

2. @LukeWoodward Хорошо, я отредактировал вопрос, вы можете проверить пример в вопросе.

Ответ №1:

Вам не нужно update заявление там, все, что вам нужно, это просто установить новое значение в :NEW.FEES:

 CREATE OR REPLACE TRIGGER MYTRIGGER
BEFORE INSERT ON STUDENT
FOR EACH ROW
BEGIN
IF :NEW.DOMICILE = 'TEXAS' AND :NEW.STATUS = 'ACTIVE' THEN
  :NEW.FEES := 0.50 * :NEW.FEES;
END IF;
END MYTRIGGER;
/
  

Комментарии:

1. Ну, это дало следующую ошибку: Warning: Trigger created with compilation errors. SQL> show error; Errors for TRIGGER MYTRIGGER: LINE/COL ERROR -------- ----------------------------------------------------------------- 3/13 PLS-00103: Encountered the symbol "=" when expecting one of the following: := . ( @ % ; indicator The symbol ":= was inserted before "=" to continue. SQL>

2. @BHS извините, исправлена опечатка — добавлено ‘:’

Ответ №2:

Ваш триггер работает просто отлично, как написано. Но, очевидно, не то, что вы хотите и не ожидали. То, что вы хотите, на 1/2 меньше платы за входящую строку. Однако это ваше ожидание неверно. На самом деле ваше заявление об обновлении снижает плату на 1/2 для когда-либо существующей строки в таблице. Поскольку входящая строка еще не существует, она НЕ участвует в обновлении. Вот почему, похоже, он работает с некоторыми, но не со всеми вставками.(На самом деле я был удивлен, поскольку ожидал исключения «ORA-04091: таблица изменяется …»). Причина этого в том, что в вашем заявлении об обновлении нет предложения WHERE, поэтому оно обновляет каждую строку. Смотрите здесь скрипку, которая показывает, что происходит, отображая таблицу после каждой вставки, чтобы увидеть, что на самом деле сделал этот оператор. Часто полезный метод, когда результаты не соответствуют ожиданиям. @SayanMalakshinov прав: не обновляйте, а просто выполняйте задание.

 :new.fees := :new.fees * .5;