各位大侠,问题如下:
ORACLE数据库中有两个表STUD_INFO和STUD_INFO1,栏位完全相同,两个表在同一个数据库的同一个方案下,现在想通过触发器实现以下功能:
当表STUD_INFO中INSERT了新的数据的后,表STUD_INFO1也要自动INSERT这些数据,我写的TRIGGER如下:
Create or replace trigger mytrigger01
after insert
on stud_info
for each row
declare
v_count1 number;
v_count2 number;
begin
select count(stid) into v_count1 from stud_info;--stid表示学生学号,是primary key
select count(stid) into v_count2 from stud_info1;
if (v_count1>v_count2) then
insert into stud_info1 (select * from stud_info minus select * from stud_info1);
END IF;
END;
此触发器可以正确编译,但当我往stud_info表中INSERT数据的时候,ORACLE提示这个触发器执行过程中有误,
但ORACLE并未给出是哪里错了,所以想请教各位高手,究竟是错在什么地方?另外我觉得我这个触发器的写法还有漏洞,未对
其他情况进行处理或者做exception处理,如果这个也能帮忙完善一下,小弟在这里真要感激涕零了!
我的INSERT语句如下:
insert into stud_info
values
('95025','王力','男','计算机系','20',null,null)
/
我确定这个INSERT语句是正确的,因为当我把这个触发器DROP了以后,就可以正常INSERT了.

解决方案 »

  1.   

    “mytrigger01执行过程中出错”,就这个错误信息了.
      

  2.   

    Create or replace trigger mytrigger01
    after insert
    on stud_info
    for each row
    declare
    v_count1 number:=0;
    v_count2 number:=0;
    begin
    /*
    不明白你为什么要这样判断一下?你的要求不就是在插入stud_info表时,同时也向stud_info1表中插入相同的数据吗?你可以直接向STUD_INFO1中插入数据就行了呀?
    select count(stid) into v_count1 from stud_info;--stid表示学生学号,是primary key
    select count(stid) into v_count2 from stud_info1;
    if (v_count1>v_count2) then
    insert into stud_info1 (select * from stud_info minus select * from stud_info1);
    END IF;
    */
    INSERT INTO STUD_INFO1(ID,NAEM,SEX,DEPT,AGE,COL1,COL2)VALUES(:NEW.ID,:NEW.NAME,:NEW.SEX,:NEW.DEPT,:NEW.AGE,:NEW.COL1,:NEW.COL2);--此处的id,name,sex,dept,age,col1,col2都是我猜测--的你STUD_INFO表中的字段名称
    END;
      

  3.   

    编译是成功的
    sorry,漏掉了一些错误:
    12:39:54  ORA-04091: 表 SCOTT.STUD_INFO 发生了变化, 触发器/函数不能读它
    12:39:54  ORA-06512: 在 "SCOTT.MYTRIGGER01", line 5
    12:39:54  ORA-04088: 触发器 'SCOTT.MYTRIGGER01' 执行过程中出错
      

  4.   

    上面的异常应该是这个引起的:
    select count(stid) into v_count1 from stud_info;--stid表示学生学号,是primary key
      

  5.   

    我做判断是为了防止STUD_INFO1中已经有STUD_INFO中插入的新记录了,也许我这样思考的方向不对,我试试强哥的方法.
      

  6.   

    在declare下面加上PRAGMA AUTONOMOUS_TRANSACTION;试试!
      

  7.   


    你这两个表中的数据本来就应该是同步的(排除认为向STUD_INFO1表中添加数据的情况),因为你的STUD_INFO中的id是主键,肯定不要插入相同的id值;而且STUD_INFO1表中的数据记录来源于STUD_INFO表,所以肯定STUD_INFO1表中的id也不会有相同的值。
      

  8.   


    --加个自治事务pragma autonomous_transaction ;
    Create or replace trigger mytrigger01
    after insert
    on stud_info
    for each row
    declare
    v_count1 number;
    v_count2 number;
    pragma autonomous_transaction;
    begin
    select count(stid) into v_count1 from stud_info;--stid表示学生学号,是primary key
    select count(stid) into v_count2 from stud_info1;
    if (v_count1>v_count2) then
    insert into stud_info1 (select * from stud_info minus select * from stud_info1);
    END IF;
    commit;--要这样写
    END;
      

  9.   


    其实也可以这样
    merge into stud_info1 a using stud_info b on(a.stid=b.stid)
    when not matched then
    insert(a.stid,a.name,a.col...) values(b.stid,b.name,b.col...)
      

  10.   

    我刚刚验证了一下,结果如下:
    (1)加入自治事务pragma autonomous_transaction;后,向STUD_INFO中INSERT数据已经不会报错,但不会有新的记录INSERT到STUD_INFO1.
    (2)使用:NEW可以实现向STUD_INFO中INSERT数据后,也向STUD_INFO1中INSERT相同的数据.
    感谢各位的热心帮忙.
    不过我总觉得要加个判断,虽说从逻辑上来讲,STUD_INFO1的数据是从STUD_INFO而来,不存在重复的可能.可万一有人人为地事先向STUD_INFO1中塞了STUD_INFO中INSERT的新纪录,ORACLE就要报错了.是否可以在INSERT到STUD_INFO的时候,发现STUD_INFO1中已经存在了相同的STID,然后更新STUD_INFO1中对应的这个STID的所有内容,而不是报错不允许数据向STUD_INFO中INSERT?
      

  11.   

    在各位的大力帮忙下,我把trigger更新了一下,可以正常起作用,但不知道是否有什么漏洞?
    如下:
    DECLARE
    V_COUNT NUMBER;
    begin
    SELECT COUNT(STID) INTO V_COUNT FROM STUD_INFO1 WHERE STID=:NEW.STID;
    IF V_COUNT>0 THEN
    UPDATE STUD_INFO1 SET STNAME=:NEW.STNAME,STSEX=:NEW.STSEX,STDEPT=:NEW.STDEPT,STAGE=:NEW.STAGE,
    INTIME=:NEW.INTIME,STATUS=:NEW.STATUS WHERE STID=:NEW.STID;
    ELSE
    INSERT INTO STUD_INFO1
    (STID,STNAME,STSEX,STDEPT,STAGE,INTIME,STATUS)
    VALUES
    (:NEW.STID,:NEW.STNAME,:NEW.STSEX,:NEW.STDEPT,:NEW.STAGE,:NEW.INTIME,:NEW.STATUS);
    END IF;
    END;
      

  12.   

    stid是主键  如果STUD_INFO1中已经存在了数据 触发器报错 insert就不会执行这不也是正常的吗
    所以不需要加入任何额外的判断了
      

  13.   

    OK
    Create or replace trigger mytrigger01
    after insert
    on stud_info
    for each row
    declare
    v_count1 number;
    v_count2 number;
    pragma autonomous_transaction;
    begin
    select count(stid) into v_count1 from stud_info;--stid表示学生学号,是primary key
    select count(stid) into v_count2 from stud_info1;
    if (v_count1>v_count2) then
    insert into stud_info1 (select * from stud_info minus select * from stud_info1);
    END IF;
    commit;--要这样写
    END;
    以上语句为何不能向STUD_INFO1中自动INSERT内容(无报错),我研究了半天也没研究懂,盼高人指教!