PL/SQL中未更新的行

PL/SQL中未更新的行,sql,oracle,plsql,sql-update,Sql,Oracle,Plsql,Sql Update,我想将给定部门的用户工资更新10K,如果他们的名字中没有,否则n*10K,其中n是saraly类别,从1到5。但不知何故,updatequery并没有更新行 我创建一个游标,并将它们提取到rec变量中。然后检查名称是否有“T”,否则我将inc变量设置为salary category并相应地更新行 CREATE OR REPLACE PROCEDURE sal_increase(p_deptno INTEGER) IS cursor curs is select empno, e.en

我想将给定部门的用户工资更新10K,如果他们的名字中没有,否则n*10K,其中n是saraly类别,从1到5。但不知何故,updatequery并没有更新行

我创建一个游标,并将它们提取到rec变量中。然后检查名称是否有“T”,否则我将inc变量设置为salary category并相应地更新行

CREATE OR REPLACE PROCEDURE sal_increase(p_deptno INTEGER) IS 

    cursor curs is select empno, e.ename, e.sal, sc.category  , lowest_sal, highest_sal
        from emp2 e 
        join nikovits.sal_cat sc on lowest_sal <= sal and sal <= highest_sal
        where deptno = p_deptno FOR UPDATE; 
        

    rec curs%ROWTYPE;
    i integer := 1;
    i_out varchar2(30);
    inc integer := 1;
    has_t integer := 0;
    
begin
    
    OPEN curs;
    
    loop
        FETCH curs INTO rec;
        EXIT WHEN curs%NOTFOUND;
        has_t := 0;
        for i in 1..length(rec.ename) loop
            i_out := substr(rec.ename,i,1);
            if i_out = 'T' then
                has_t := 1;
            end if;
        end loop;
        
        if has_t = 0 then
             inc := rec.category;
        end if;
        
        if has_t = 1 then
            DBMS_OUTPUT.PUT_LINE(rec.ename||' has T, increment is 10000');
        else
            DBMS_OUTPUT.PUT_LINE(rec.ename||' Doesnt have T, salery category is '|| rec.category ||' increment is '|| inc ||'*10000');
        end if;
        DBMS_OUTPUT.PUT_LINE('update begins...');
        UPDATE emp2 e1 SET sal = sal + (inc * 10000) WHERE CURRENT OF curs;
        DBMS_OUTPUT.PUT_LINE('After update'||rec.ename||'"salary: '||rec.sal);
    end loop;
    
    CLOSE curs;
    
end;

/

set serveroutput on
execute sal_increase(20);
select empno, e.ename, e.sal, sc.category  , lowest_sal, highest_sal
        from emp2 e 
        join nikovits.sal_cat sc on lowest_sal <= sal and sal <= highest_sal where deptno = 20;


事实证明,在PL/SQL中使用游标更新表不起作用,因为游标看不到新值,所以正确的anwser应该是

CREATE OR REPLACE PROCEDURE sal_increase(p_deptno INTEGER) IS 


    i integer := 1;
    i_out varchar2(30);
    inc integer := 1;
    has_t integer := 0;

begin


    for rec in (
        select empno, e.ename, e.sal, sc.category  , lowest_sal, highest_sal
        from emp2 e 
        join nikovits.sal_cat sc on lowest_sal <= sal and sal <= highest_sal
        where deptno = p_deptno
    ) loop
        has_t := 0;
        for i in 1..length(rec.ename) loop
            i_out := substr(rec.ename,i,1);
            if i_out = 'T' then
                has_t := 1;
            end if;
        end loop;

        if has_t = 0 then
             inc := rec.category;
        end if;

        if has_t = 1 then
            DBMS_OUTPUT.PUT_LINE(rec.ename||' has T, increment is 10000');
        else
            DBMS_OUTPUT.PUT_LINE(rec.ename||' Doesnt have T, salery category is '|| rec.category ||' increment is '|| inc ||'*10000');
        end if;
        DBMS_OUTPUT.PUT_LINE('update begins...');
        UPDATE emp2 e1 SET sal = sal + (inc * 10000)
        where e1.empno = rec.empno and e1.deptno = p_deptno;
        DBMS_OUTPUT.PUT_LINE('After update'||rec.ename||'"salary: '||rec.sal);
        rollback;
    end loop;


end;

/
set serveroutput on
execute sal_increase(20);
select empno, e.ename, e.sal
        from emp2 e  where deptno = 20;

rollback;


您不需要PL/SQL块。仅使用一条Update语句就足够了:

UPDATE emp2 e1 
   SET sal = sal + 
             (
              SELECT 10000 * case when instr(e.ename,'T')>0 then 1 else sc.category end 
                FROM emp2 e
                JOIN sal_cat sc
                  ON lowest_sal <= sal
                 AND sal <= highest_sal
               WHERE empno = e1.empno             
             )
  WHERE deptno = :p_deptno;

如果员工的工资系数等于1,如果他的名字包含一个字母T,如果你不介意,你能分享创建脚本表emp2和sal_cat吗?我没有,但是添加了图像整个for循环你必须检查名称是否包含“T”可以替换,希望ROLLBACK是故意留在你的脚本中的,你知道它为什么在那里,对吧?@micklesh是的,我不想破坏表的内容。我知道,我不是在运行它。我必须用PL/SQL来完成。这就是任务。但你是对的。我已经发布了使用PL/SQL的工作解决方案,请将此语句放到您的过程中。无需将光标与mess@FəridQənbərli一起使用。顺便说一句,不要忘记在参数p_deptno.Wow之前删除冒号。结果是更好的解决方案!