我的冒号分隔值列表存储在我的Oracle数据库的varchar2
列ORDER_PARTS_LIST
中。
(我知道将数据存储在这样的列表中可能不是最佳做法,但现在只是忽略这一事实。)
以下是相关的表格列:
ORDER_TABLE(
ORDER_NUMBER number,
ORDER_PARTS_LIST varchar(4000))
PARTS_TABLE(
PART_NUMBER varchar(20),
ASSIGNED_ORDER_NUMBER number)
我有一个条件触发器:
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}} {1}}。
最后,ORDER中的所有PARTS都应该使用该ORDER的NUMBER标记。
这是否有意义?
我不确定如何正确定义此触发器中的变量以便它运行并且老实说我对触发器是否会按照我认为它应该执行的操作有一些疑问。任何建议或帮助获得触发器功能,就像我已经定义它应该是伟大的。提前谢谢。
答案 0 :(得分: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将找到ids 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;
答案 1 :(得分:0)
您正在ORDER_TABLE上创建触发器。由于ORDER_TABLE不包含名为PART_NUMBER的列,因此Oracle无法找到标识符“PART_NUMBER”,因为它属于PARTS_TABLE。
您需要在触发器中编写单独的查询才能访问PARTS_TABLE中的PART_NUMBER。
答案 2 :(得分:-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;