Oracle更新所有记录的过程
您好,我正在尝试使用Oracle中的存储过程更新表中的特定记录, 但它会更新所有记录,而不是特定记录。 这是执行存储过程之前的EMP表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
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”中一样。关上它。