题目是这样的:有一张表emp,字段有员工编号staffno,员工姓名staffname,入职时间indate,员工工资salay;写一个存储过程给员工加工资,如果入职时间在2006年前就加工资400,如果入职时间在2007就加工资200,如果入职时间在2007年后就加100,写一个存储过程,带游标逐行读取:
我首先建了一张表add_sala,写了一个存储过程如下:
create or replace procedure addsalay is
staffno add_sala.staffno% type ;
staffname  add_sala.staffname% type;
salay  add_sala.salay%type;
indate add_sala.indate%type;cursor c1 is select * from add_sala;
begin
 open c1;
 loop
   fetch c1 into staffno,staffname,salay,indate ;
  
   if substr(indate,8,9)<=06
     then update add_sala t
    --   set t.staffno:=v_staffno,
      --t.staffname:=v_staffname,
       set t.salay =salay+400--,
      -- t.indate=v_date
      where substr(indate,8,9)<=06
     and t.staffno =staffno
      
       ;
       elsif substr(indate,8,9)=07
     then update add_sala t
       set --t.staffno=v_staffno,
       --t.staffname=v_staffname,
       t.salay=salay+200--,
      -- t.indate=v_date
      where substr(indate,8,9)=07
       ;
       else 
       update add_sala t
       set --t.staffno=v_staffno,
       --t.staffname=v_staffname,
       t.salay=salay+100--,
      -- t.indate=v_date
      where substr(indate,8,9)>07
;
end if;
exit when c1%notfound;
end loop;end addsalay;然后发现,只要满足条件的有多少条就会更新多少次,然后我把循环写在游标读取后面报错,所以请教各位大虾,帮忙修改或者写个存储过程,非常感谢!

解决方案 »

  1.   

    substr(indate,8,9),
    indate是什么类型的?日期还是字符?
    游标打开了也没有关闭。
    set t.salay =salay+400,    这个不能有逗号
      

  2.   

    这里没必要用游标,直接用三条update语句就可以了
      

  3.   

    有必要用存储过程吗?case when 就完全可以实现你这个需求啊。
      

  4.   

    create or replace procedure emp_up
    IS 

    cursor c_emp is select * from emp;
    begin
    for r_emp IN c_emp LOOP
    IF r_emp.indate < to_date('01-01-2007','dd-mm-yyyy') THEN
    UPDATE emp
     SET salary = salary + 400
    WHERE staffno = r_emp.staffno;
    ELSIF r_emp.indate <= to_date('31-12-2007','dd-mm-yyyy') THEN
    UPDATE emp
    SET salary = salary + 200
    WHERE staffno = r_emp.staffno;
    ELSE
    UPDATE emp
    SET salary = salary + 100
    WHERE staffno = r_emp.staffno;
    END IF;
    END LOOP;
    END;
    不知道这样行不行,虽然只用sql语句就可以搞定,你看看,我在我机子上测试可以。
      

  5.   


    UPDATE TABLE_DESC T
       SET T.SAL = (CASE WHEN T.INDATE <= TO_DATE('2006', 'yyyy') THEN T.SAL + 400 WHEN TO_CHAR(T.INDATE, 'yyyy') = '2007' THEN T.SAL + 200 ELSE T.SAL + 100 END);
    commit;
    这个用语句更简单些。
      

  6.   

    同意,这边用游标是比较麻烦的。而且你的代码中游标有open单却没有close
      

  7.   

    不太明白楼主为什么用游标处理,游标的效率不会太高,也影响系统性能的。
    能用sql语句最好还是用sql就就可以了。