ошибка запуска oracle

#sql #oracle #triggers #ora-00904 #ora-00933

#sql #Oracle #триггеры #ora-00904 #ora-00933

Вопрос:

У меня есть две таблицы, TableA и TableB. Я хочу установить триггер. Как только вставка происходит в TableA, это может вызвать некоторые события в TableB.

Две таблицы выглядят следующим образом, например,

  • Столбцы таблицы: (product_id, product_name, производство)
  • Столбцы TableB: (покупатель, product_id)

Что я хочу сделать, так это: после вставки новой строки в таблицу A, если ее product_name равно null, затем запустите обновления в TableB. Обновите ‘ product_id TableB’ до этого нового вставленного product_id, если строки в TableB имеют то же производство, что и новое вставленное производство.

 CREATE TRIGGER t1     

AFTER INSERT ON tableA    
FOR EACH ROW WHEN (NEW.product_name is NULL)

BEGIN

    UPDATE tableB 
       SET tableB.product_id = :NEW.product_id 
     WHERE tableB.product_id IN (SELECT tableA.product_id 
                                   FROM tableA 
                                  WHERE tableA.manufacture = :NEW.manufacture);

END;
  

Он всегда жалуется на несколько ошибок в SQL developer:

 Error(2,2): PL/SQL: SQL Statement ignored
Error(2,120): PL/SQL: ORA-00933: SQL command not properly ended
Error(2,36): PL/SQL: ORA-00904: "NEW"."product_id": invalid identifier
Error: PLS-00801: internal error [ph2csql_strdef_to_diana:bind]
  

Обновить:

 CREATE TABLE "tableA"
  (
    "PRODUCT_ID"      NUMBER PRIMARY KEY,
    "PRODUCT_NAME"    VARCHAR2(50 BYTE) DEFAULT NULL,
    "MANUFACTURE" VARCHAR2(50 BYTE) DEFAULT NULL
)

CREATE TABLE "tableB"
(
    "BUYER_ID"      NUMBER PRIMARY KEY,
    "PRODUCT_ID"    NUMBER DEFAULT NULL
)
  

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

1. Ознакомьтесь с этим сообщением , в котором приведен пример, аналогичный тому, что вы пытаетесь сделать.

2. проблема в том, что я думаю, что синтаксис правильный. Я не понимаю, почему oracle жалуется.

3. Можете ли вы также опубликовать инструкции create table ..? Это поможет воспроизвести вашу точную проблему..

4. Я опубликовал их. Спасибо

5. Вероятно, было бы лучше использовать хранимую процедуру для выполнения вставки в A и условного обновления в B. Такого рода работу трудно отследить до триггера, если у вас возникнут проблемы позже. У вас также могут возникнуть трудности с выбором из A внутри триггера — я не думаю, что известно, будет ли запрос к A включать вставляемую в данный момент строку, поэтому Oracle не позволит вам избежать двусмысленности. (Но может зависеть от версии — не уверен!)

Ответ №1:

Вы получаете все эти ошибки одновременно или разные ошибки при попытке выполнить разные действия? ORA-00904 (и, возможно, связанный с ним ORA-00933) появится, если вы опустили : перед NEW.product_id , а PLS-00801 может появиться из-за наличия пробела между ними
(т. Е. : NEW.product_id . Не уверен, как вы могли бы получить оба одновременно.

В том виде, в каком она опубликована сейчас, она выглядит нормально — вы все еще получаете сообщение Errors: check compiler log после TRIGGER T1 compiled — или вы просматриваете старые ошибки в окне журнала компилятора разработчика SQL? Если вы не уверены, щелкните правой кнопкой мыши в окне журнала компилятора и выберите «Очистить» перед повторным запуском, чтобы увидеть, какие ошибки (если таковые имеются) действительно генерируются текущим кодом.

Ответ №2:

Вы создали таблицы со смешанными именами «TableA» и «TableB». Обычно это плохая практика в Oracle и приводит к проблемам при обращении к таблицам в коде, потому что на них нужно ссылаться в правильном регистре, заключенном в двойные кавычки:

 CREATE TRIGGER t1     

AFTER INSERT ON "tableA"    
FOR EACH ROW WHEN (NEW.product_name is NULL)

BEGIN

    UPDATE "tableB" 
       SET "tableB".product_id = :NEW.product_id 
     WHERE "tableB".product_id IN (SELECT "tableA".product_id 
                                   FROM "tableA" 
                                  WHERE "tableA".manufacture = :NEW.manufacture);

END;
  

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

1. Поскольку триггер не будет компилироваться с другими подобными ошибками, я предположил, что имена таблиц были изменены непоследовательно для публикации, и все настоящие имена должны быть заглавными. В любом случае, конечно, стоит указать.

2. Да, вероятно, это не опубликованная проблема, но именно это произошло, когда я попытался воссоздать проблему, используя опубликованный код. И эти инструкции CREATE TABLE выглядят как копирование и вставка из SQL Developer, хотя, возможно, настоящие имена таблиц впоследствии были введены в смешанном регистре.

Ответ №3:

В SQL * Plus вам необходимо завершать CREATE TRIGGER инструкцию с помощью / в одной строке.

В зависимости от вашего инструмента SQL вам может потребоваться использовать другой способ установки альтернативного разделителя.

Ответ №4:

Измените предложение where в вашем вложенном операторе select с WHERE «TableA».manufacture = :NEW.manufacture на WHERE «TableA».manufacture = NEW.manufacture