Oracle更新所有记录的过程

Oracle更新所有记录的过程,oracle,function,stored-procedures,oracle11g,Oracle,Function,Stored Procedures,Oracle11g,您好,我正在尝试使用Oracle中的存储过程更新表中的特定记录, 但它会更新所有记录,而不是特定记录。 这是执行存储过程之前的EMP表 ID, NAME, DEPT, SAL 1 pc New 100000000 2 pc1 qwe 1 3 pc2 New 2 4 pc4 asf 3 5 pc5 New 4 6 pc6 qwe 5 7 pc7 New 6 8 pc8 COMP 8 9 pc9

您好,我正在尝试使用Oracle中的存储过程更新表中的特定记录, 但它会更新所有记录,而不是特定记录。 这是执行存储过程之前的EMP表

ID, NAME, DEPT, SAL
1   pc    New   100000000
2   pc1   qwe   1
3   pc2   New   2
4   pc4   asf   3
5   pc5   New   4
6   pc6   qwe   5
7   pc7   New   6
8   pc8   COMP  8
9   pc9   New   9
10  pc10  New   7
11  pc11  qwe   11
12  pc12  New   12
13  pc13  New   13
14  pc14  qwe   14
Connecting to the database testDB.
isValid 1 : 0
isValid 2 : 0
isValid 3 : 0
isValid 4 : 0
isValid 5 : 0
isValid 6 : 0
isValid 7 : 0
isValid 8 : 1
updating 8
isValid 9 : 0
isValid 10 : 0
isValid 11 : 0
isValid 12 : 0
isValid 13 : 0
isValid 14 : 0
Process exited.
Disconnecting from the database testDB.

ID, NAME, DEPT, SAL
1   pc      IT  100000000
2   pc1     IT  1
3   pc2     IT  2
4   pc4     IT  3
5   pc5     IT  4
6   pc6     IT  5
7   pc7     IT  6
8   pc8     IT  8
9   pc9     IT  9
10  pc10    IT  7
11  pc11    IT  11
12  pc12    IT  12
13  pc13    IT  13
14  pc14    IT  14
检查是否为EMP的职能属于COMP部门

create or replace FUNCTION ISCOMPGUY 
(
  EMPID IN NUMBER 
) RETURN NUMBER AS

dept varchar(20);

cursor getDept IS select dept from emp where id=EMPID;

BEGIN
    open getDept; FETCH getDept INTO dept;
    IF DEPT = 'COMP' THEN 
        return 1;
    ELSE
        return 0;
    END IF;
END ISCOMPGUY;
根据ISCOMPGUY函数更新记录的过程

CREATE OR REPLACE PROCEDURE UPATEEMP AS 

isValid number :=0;

cursor getCompGuys IS select id from emp;-- where dept='COMP';
BEGIN
    for emp in getCompGuys loop
        isValid := iscompguy(emp.id);
        dbms_output.put_line ('isValid '|| emp.id || ' : ' || isValid );
        if isValid = 1 then
            dbms_output.put_line ('updating ' ||emp.id);
                UPDATE EMP set dept='IT' where id = emp.id;
        end if;        
     end loop;
END UPATEEMP;
但当我运行程序时,它会更新所有记录 程序执行后程序和EMP表的输出

ID, NAME, DEPT, SAL
1   pc    New   100000000
2   pc1   qwe   1
3   pc2   New   2
4   pc4   asf   3
5   pc5   New   4
6   pc6   qwe   5
7   pc7   New   6
8   pc8   COMP  8
9   pc9   New   9
10  pc10  New   7
11  pc11  qwe   11
12  pc12  New   12
13  pc13  New   13
14  pc14  qwe   14
Connecting to the database testDB.
isValid 1 : 0
isValid 2 : 0
isValid 3 : 0
isValid 4 : 0
isValid 5 : 0
isValid 6 : 0
isValid 7 : 0
isValid 8 : 1
updating 8
isValid 9 : 0
isValid 10 : 0
isValid 11 : 0
isValid 12 : 0
isValid 13 : 0
isValid 14 : 0
Process exited.
Disconnecting from the database testDB.

ID, NAME, DEPT, SAL
1   pc      IT  100000000
2   pc1     IT  1
3   pc2     IT  2
4   pc4     IT  3
5   pc5     IT  4
6   pc6     IT  5
7   pc7     IT  6
8   pc8     IT  8
9   pc9     IT  9
10  pc10    IT  7
11  pc11    IT  11
12  pc12    IT  12
13  pc13    IT  13
14  pc14    IT  14
尽管输出表明其仅针对emp.id=8进行更新,但所有记录都将得到更新


提前谢谢。

我认为您在某种程度上混淆了数据库:

UPDATE EMP set dept='IT' where id = emp.id;
那么emp.id在这里等于什么呢?系统认为这是for循环中的
emp
,还是语句本身中对
emp
表的引用。我怀疑它在解析时首先将更本地的
emp
表引用放在首位,在这种情况下,更新要求更新其中的id=id,例如所有行


我将更改循环变量上的别名,因为通过在新变量中获取emp.id并将其传递给update命令,可以解决重新测试

Got的问题

CREATE OR REPLACE PROCEDURE UPATEEMP AS 

isValid number :=0;
eid number;

cursor getCompGuys IS select id from emp;-- where dept='COMP';
BEGIN
    for emp in getCompGuys loop
        isValid := iscompguy(emp.id);
        eid := emp.id;
        dbms_output.put_line ('isValid '|| emp.id || ' : ' || isValid );
        if isValid = 1 then
            dbms_output.put_line ('updating ' ||emp.id);
            UPDATE EMP set dept='IT' where id = eid;
        end if;        
     end loop;
END UPATEEMP;

我可能只是对此进行了评论,但我认为,用光标和函数调用这种简单操作的方法是绝对无关紧要的,也是次优的解决方案太重要了。

看起来您实际上想要的是这样一个update语句

UPDATE emp
    SET
        dept = 'IT'
    WHERE dept = 'COMP';
这比通过游标循环所有值并编写不必要的代码更高效、更高效

如果您想要显示更新了哪些ID,那么您可能需要做的就是使用
返回BULK COLLECT to
语句来存储和获取集合中的ID

CREATE OR REPLACE PROCEDURE upateemp AS
    TYPE empidtyp IS
        TABLE OF emp.id%TYPE;
    empids   empidtyp;
BEGIN
    UPDATE emp
    SET
        dept = 'IT'
    WHERE dept = 'COMP' RETURNING id BULK COLLECT INTO empids; --store the updated ids in a collection

    FOR i IN 1..empids.count LOOP --loop through collection elements
        dbms_output.put_line('isValid ' || empids(i) ); 
    END LOOP;

END upateemp;
/
执行

SET SERVEROUTPUT ON
BEGIN
 EXEC upateemp;
END;
/
isValid 8


PL/SQL procedure successfully completed.

你最好把emp的
改成另一个名字,因为emp是table,把它命名为另一个东西,例如,
对于ec in.
顺便问一下,你在哪里添加提交?不要留下打开的游标,就像在你的函数“ISCOMPGUY”中一样。关上它。