create or replace TRIGGER log_worlds BEFORE UPDATE OR INSERT ON worlds
DECLARE
ac VARCHAR2(50);
tab VARCHAR2(50);
world VARCHAR2(50);
BEGIN
IF UPDATING THEN
ac:='Aktualizacja';
END IF;
IF INSERTING THEN
ac:='Nowe';
END IF;
tab:='WORLDS';
world:='world_';
world:=world||cast(NEW_WORLD.NEXTVAL as VARCHAR2(10));
INSERT INTO log(ACTION_DATE,ACTION,TAB_NAME,ADDED_WORLD) VALUES(SYSDATE,ac,tab,world);
INSERT INTO worlds(WORLD_NAME) VALUES(world);
END;有人能帮我吗,错误信息是关于第14行的?此触发器用于向日志表添加新值,并在APEX应用程序对表发出DML时更改worlds表的主键值。
发布于 2012-05-24 20:31:36
你得到的错误提示你的代码中有一些语法错误,我不能立即找到。然而,我预计会出现另一个错误,因为Oracle不允许在触发器处于on状态时在触发器内执行DML语句(select、insert、update、delete)。您的触发器位于表世界中,因此不允许在触发器内的表世界中插入记录。
发布于 2012-05-24 20:43:41
直接的语法错误是,假设NEW_WORLD是您创建的序列,您需要执行如下操作
SELECT world ||
cast( new_world.nextval as varchar2(10) )
INTO world
FROM dual;而不是直接引用CAST中的序列。
不过,我还不清楚你的触发器应该做什么。它至少会产生一个无限循环。WORLDS上的每个INSERT都将触发触发器,这将在INSERT上生成一个WORLDS,这将导致触发器触发,以此类推。也许您打算将其作为行级触发器,而不是更改:new.world_name值的语句级触发器?如果是这样的话,你可能想要类似这样的东西
create or replace TRIGGER log_worlds
BEFORE UPDATE OR INSERT ON worlds
FOR EACH ROW
DECLARE
ac VARCHAR2(50);
tab VARCHAR2(50);
world VARCHAR2(50);
BEGIN
IF UPDATING THEN
ac:='Aktualizacja';
END IF;
IF INSERTING THEN
ac:='Nowe';
END IF;
tab:='WORLDS';
world:='world_';
select world || cast(new_world.nextval as varchar2(10)
into world
from dual;
INSERT INTO log(ACTION_DATE,ACTION,TAB_NAME,ADDED_WORLD)
VALUES(SYSDATE,ac,tab,world);
:new.world_name := world;
END;这假设world_name实际上不是主键。如果world_name是主键,那么在更新行时修改主键值就没有意义了--只有在执行INSERT时才可能分配主键。
发布于 2012-05-24 20:44:25
我想应该是这一行:
world:=world||cast(NEW_WORLD.NEXTVAL as VARCHAR2(10));如果您将其替换为:
world := world||to_char(NEW_WORLD.NEXTVAL);应该能行得通。
顺便说一句:直接在赋值中使用nextval调用在11.x之前的版本上不起作用(这里不确定x的值)。
在10.x中,您需要声明一个变量,然后使用:
SELECT to_char(new_world.nextval)
into world_num;
world := world || world_num;https://stackoverflow.com/questions/10737520
复制相似问题