2012-01-26 3 views
1

У меня есть список значений, разделенных двоеточиями, которые хранятся в столбце varchar2 моей базы данных Oracle.Триггер базы данных Oracle APEX - проблемы со ссылками на столбцы базы данных

(Я понимаю, что хранение данных в виде списка, как это может быть не лучшая практика, но сейчас просто игнорировать этот факт.)

Вот соответствующие столбцы таблицы:

ORDER_TABLE(
    ORDER_NUMBER number, 
    ORDER_PARTS_LIST varchar(4000)) 

PARTS_TABLE(
    PART_NUMBER varchar(20), 
    ASSIGNED_ORDER_NUMBER number) 

I имеет условный триггер:

create or replace trigger "ORDER_PARTS_T1" 
BEFORE 
insert or update or delete on "ORDER_TABLE" 
for each row 
begin 
    if :new.ORDER_PARTS_LIST LIKE '%'+PART_NUMBER+'%' then 
    update PARTS_TABLE set ASSIGNED_ORDER_NUMBER = :ORDER_NUMBER; 
    end if; 

end; 

Когда я запускаю этот триггер я получаю следующее сообщение об ошибке:

PLS-00201: identifier 'PART_NUMBER' must be declared 

Что должно произойти в том, что проверяет триггер, который PART_NUMBERs в PARTS_TABLE, включены в ORDER_PARTS_LIST, в ORDER_TABLE, а затем вставляет ORDER_NUMBER для растерянного строки в ORDER_TABLE, в ASSIGNED_ORDER_NUMBER колонку, от PARTS_TABLE.

В конце концов, все ДЕТАЛИ в ЗАКАЗЕ должны быть помечены этим НОМЕРОМ ЗАКАЗА.

Это делает ЛЮБОЙ смысл ???

Я точно не знаю, как правильно определить переменные в этом триггере, чтобы он работал, и, честно говоря, у меня есть несколько сомнений относительно того, будет ли триггер делать то, что, как мне кажется, даже если они работают. ЛЮБЫЕ предложения или помощь в получении пускового функционала, как я определил, это должно быть здорово. Заранее спасибо.

ответ

1

Вы можете сделать сопоставление строк, чтобы проверить каждую строку:

create or replace trigger "ORDER_PARTS_T1" 
BEFORE 
insert or update on "ORDER_TABLE" 
for each row 
begin 
    update PARTS_TABLE p 
    set p.ASSIGNED_ORDER_NUMBER = :new.ORDER_NUMBER 
    where instr(':' || :new.ORDER_PARTS_LIST || ':' 
      ,':' || p.PART_NUMBER || ':') > 0; 
end; 

Так, например, если ORDER_PARTS_LIST является '123:456:789', то INSTR будет найти спички для ид 123, 456 и 789, но не 124, 45 или 8, например.

Когда части удаляются из заказа вам потребуется другой триггер NULL соответствующие поля в PARTS_TABLE:

create or replace trigger "ORDER_PARTS_T1" 
BEFORE 
update on "ORDER_TABLE" 
for each row 
begin 
    update PARTS_TABLE p 
    set p.ASSIGNED_ORDER_NUMBER = NULL 
    where instr(':' || :new.ORDER_PARTS_LIST || ':' 
      ,':' || p.PART_NUMBER || ':') = 0 
    and instr(':' || :old.ORDER_PARTS_LIST || ':' 
      ,':' || p.PART_NUMBER || ':') > 0; 
end; 
+0

Большое спасибо, сэр! Работал как шарм! – Spags

+0

Как раз в качестве продолжения ... вы упомянули удаление, и я думаю, что вы правы, на самом деле нет причин для включения в него, поскольку записи, скорее всего, не будут удалены из базы данных. Однако есть вероятность, что PART_NUMBERS можно удалить из ORDER до того, как он будет отправлен для обработки. Есть ли простой способ обновить PARTS_TABLE для учетной записи, если часть была удалена из заказа? Мне нужен отдельный триггер с использованием OLD & NEW и т. Д.? – Spags

+0

Возможно - я отредактировал свой ответ с предложением. –

-1

Не совсем уверен, как это все совмещается (похоже, это не составит для одной и той же части на несколько заказов), но, похоже, что вы пытаетесь сделать что-то вроде этого:

create or replace trigger "ORDER_PARTS_T1" 
BEFORE 
insert or update or delete on "ORDER_TABLE" 
for each row 
begin 
    update parts_table 
    set assigned_order_number = :new.ORDER_NUMBER 
    where part_number in (:new.order_parts_list); 
end; 
+0

Ммм ... это, кажется, работает, если только один PART_NUMBER выбран, но если кратные есть он не выбран. Он не бросает ошибки, но просто не записывает значения. – Spags

+0

@ Danimal37, к сожалению, вы не можете ожидать, что инструкция IN волшебным образом превратит один параметр (': new.order_parts_list') в список, как вы могли ожидать. Вот почему он будет работать, только если выбрано только одно значение. –

+0

Правильно ... вам, вероятно, нужно будет обернуть каждый элемент в одинарные кавычки, чтобы он работал правильно. –

0

Вы создаете триггер на ORDER_TABLE. Поскольку ORDER_TABLE не содержит столбца с именем PART_NUMBER, Oracle не может найти идентификатор 'PART_NUMBER', поскольку он принадлежит PARTS_TABLE.

Для доступа к PART_NUMBER в PARTS_TABLE вам нужно будет написать отдельный запрос в своем триггере.

Смежные вопросы