我来做触发器:SQL> create table test(a varchar2(6),b integer,c integer);表已创建。SQL> create or replace trigger tr1
  2  before insert on test  
  3  for each row
  4  declare
  5  l_c integer;
  6  begin
  7    if :new.b<=9 then
  8       l_c:=substr(:new.a,1,instr(:new.a,'-')-1)||:new.b;
  9    else
 10       l_c:=substr(:new.a,instr(:new.a,'-')+1)||:new.b;
 11    end if;
 12    select l_c into :new.c from dual;  
 13  end tr1;
 14  /触发器已创建
SQL> begin
  2  insert into test(a,b) values('1-2',9);
  3  insert into test(a,b) values('1-2',10);
  4  end;
  5  /PL/SQL 过程已成功完成。SQL> select * from test;A               B          C
------ ---------- ----------
1-2             9         19
1-2            10        210已选择2行。

解决方案 »

  1.   

    我在orcale的窗体模式下建立上述触发器,可是提示“new或old引用不允许在表层触发器中”
    在窗体模式,如何实现这个功能呢?
      

  2.   

    行级触发:
    你漏了“for each row”...
      

  3.   

    我加上了“for each row”现在可以不报错了
    但是 我打开表,向里面加入一条新数据(只写字段A、B的值),点击“应用”,C字段 全部的值被更新成一样的了,而且新加那条字段中的C字段值并没有更新,再加一条数据,重复以上动作,上次加的数据的字段C中的值才被更新。我的触发器如下(orcale窗体下写的,没有使用命令行模式):
    for each row
      declare
       l_c integer;
        begin
         if :new.b<=9 then
            l_c:=substr(:new.a,1,instr(:new.a,'-')-1)||:new.b;
          else
            l_c:=substr(:new.a,instr(:new.a,'-')+1)||:new.b;
         end if;    update  test set c=to_number(l_c);  end ;
    哪里不对劲呢?
      

  4.   

    你的最后一句"update  test set c=to_number(l_c);"没有加行条件限制,就会对test表的所有行进行更新。把这一句直接改为":new.c:=to_number(l_c);"即可
      

  5.   

    我按你的说法:
    你的最后一句"update  test set c=to_number(l_c);"没有加行条件限制,就会对test表的所有行进行更新。把这一句直接改为":new.c:=to_number(l_c);"即可
    把最后一句改为了:new.c:=to_number(l_c);,没什么编译错误,但是在表中加入新的行,按“应用”,提示“通信通道的文件结束”,再按“应用”,提示“未连接到Oracle”,然后好像和oracle断开了,奇怪?
      

  6.   

    我用的是oracle9.2.0.1.0正式版呀
    重联只要执行就那样。
    我查网上说什么
    ORACLE的触发器分为两类:行触发器(For Each Row)和表触发器,在行触发器中,不得将Insert/Update/Delete语句作用于自身数据表;在表触发器中,不得使用:New/:Old语句。 是不是和这用关系,请问这个你在oracle的视窗模式下(不是命令行)试成功了吗
      

  7.   

    “ORACLE的触发器分为两类:行触发器(For Each Row)和表触发器,在行触发器中,不得将Insert/Update/Delete语句作用于自身数据表;在表触发器中,不得使用:New/:Old语句。”...没有违背上面的原则啊,我是在oracle8.1.7的sqlplus中做的,过程在上面,不会有问题的,难道跟版本有关??你的程序没有其他代码吧,把你触发器的全代码贴出来看看....
      

  8.   

    我想实现的功能就是我的描述
    我的触发器全部代码如下:
    for each row
      declare
       l_c integer;
        begin
         if :new.b<=9 then
            l_c:=substr(:new.a,1,instr(:new.a,'-')-1)||:new.b;
          else
            l_c:=substr(:new.a,instr(:new.a,'-')+1)||:new.b;
         end if;   :new.c:=to_number(l_c);
      end ;
    其实基本就是你教我的那些,但这些是写在orcale的窗体模式下的,不是在命令行中写的触发器
    触发器设置是:
    之前,
    触发触发器
    (勾取的是)插入
    其他均是默认值我本身使用 update  test set c=to_number(l_c);更新的,但这个缺少限制条件,执行后全部更新了字段C的值,但却不更新新加的那行数据,奇怪?我觉的只要实现 那一行数据是新加入的,就只更新那一行数据 这一功能就行
      

  9.   

    我在sqlplus里测试没有问题:SQL> begin
      2  insert into test(a,b) values('1-2',9);
      3  insert into test(a,b) values('1-2',10);
      4  insert into test(a,b) values('2-4',8);
      5  insert into test(a,b) values('2-4',12);
      6  insert into test values('3-5',7,34235);
      7  insert into test values('3-5',14,'');
      8  end;
      9  /PL/SQL 过程已成功完成。SQL> select * from test;A               B          C
    ------ ---------- ----------
    1-2             9         19
    1-2            10        210
    2-4             8         28
    2-4            12        412
    3-5             7         37
    3-5            14        514已选择6行。    你的“orcale的窗体”是指什么软件啊,是pl/sql developer还是dba studio还是其他?我怀疑是你使用的这“orcale的窗体”有什么不对劲的地方...
      

  10.   

    你的“orcale的窗体”是指什么软件啊就是使用Enterprise Manager Console登录到oracle的桌面窗体,这个桌面窗体可能就是把命令行做成视窗形式了把,就是和sql server类似的那种操作模式,不是使用纯命令的