这是我需要做的一个简单例子。事实上,我希望通过在plsql中使用游标从另一个表中复制它来更新一个表中的值。
我把表f和表b作为两个例子:
f=
1|Thom
2|Bob
3|Steven
5|Arthur
b=
7|Nataly
9|Alfred
,我需要在前两行中插入b&#39的拖曳线:
create table f (a number, b varchar2(10));
insert into f values (1,'Thom');
insert into f values (2,'Bob');
insert into f values (3,'Steven');
insert into f values (5,'Arthur');
commit;
create table b (c number, d varchar2(10));
insert into b values (7,'Nataly');
insert into b values (9,'Alfred');
commit;
create or replace procedure wco as
cursor c_f is
select a,b from f for update;
v_a f.a%type;
v_b f.b%type;
cursor c_b is
select c,d from b;
v_c b.c%type;
v_d b.d%type;
begin
open c_f;
open c_b
loop
fetch c_f into v_a, v_b;
exit when c_f%ROWCOUNT=c_b%RROWCOUNT;
update f set a=v_c and b=v_d where current of c_f;
end loop;
close c_d:
close c_f;
end;
/
exec wco;
select * from f;
drop table f;
预期结果(我希望有什么):
7|Nataly
9|Alfred
3|Steven
5|Arthur
但我现在所拥有的(因此)是:
1|Thom
2|Bob
3|Steven
5|Arthur
我如何解决这个问题,我是PLSQL的初学者,如果你能帮助我,我将非常感激。
答案 0 :(得分:0)
你的程序编译,但有错误;
为了看到编译错误
编译后运行show errors;
。
将open c_b
更改为open c_b;
(最后缺少分号)
将close c_d:
更改为close c_b;
(正确的名称是c_b和分号而不是冒号)
将exit when c_f%ROWCOUNT=c_b%RROWCOUNT;
更改为c_f%ROWCOUNT=c_b%ROWCOUNT;
(错误%RROWCOUNT;
)
update f set a=v_c and b=v_d where current of c_f;
这是错误的SQL语法。
应该是update table_name set column=value, column=value
;
为变量提供描述性名称非常重要,因此理解逻辑会更容易。
据我所知,你只想从源表中复制第二行。
create table source_table (
id number,
name varchar2(10));
/
insert into source_table values (1,'Thom');
insert into source_table values (2,'Bob');
insert into source_table values (3,'Steven');
insert into source_table values (5,'Arthur');
/
create table target_table (
id number,
name varchar2(10));
/
insert into target_table values (7,'Nataly');
insert into target_table values (9,'Alfred');
/
create or replace procedure copy_tables
AS
begin
FOR source_row IN (select id, name
from source_table
offset 2 rows)
LOOP
insert into target_table
values(source_row.id, source_row.name);
END LOOP;
end;
/
exec copy_tables;
/
select id, name from target_table;
/
答案 1 :(得分:0)
你不需要PL / SQL;它可以在一个MERGE语句中实现:
merge into f tgt
using (select coalesce(b1.id, f1.id) id,
coalesce(b1.name, f1.name) name,
f1.f_rowid
from (select id,
name,
rowid f_rowid,
row_number() over (order by id) rn
from f) f1
full outer join (select id,
name,
row_number() over (order by id) rn
from b) b1
on f1.rn = b1.rn) src
on (tgt.rowid = src.f_rowid)
when matched then
update set tgt.id = src.id,
tgt.name = src.name
where tgt.id != src.id
or tgt.name != src.name
when not matched then
insert (tgt.id, tgt.name)
values (src.id, src.name);
有关测试详细信息,请参阅https://livesql.oracle.com/apex/livesql/file/content_FBPR7YCLFVWO7NGDXTLSP1R97.html(两个示例;目标表包含更多且行数少于源表的行。)
如果需要,可以将上述插入添加到过程中,例如:
create procedure populate_target_table as
begin
merge into f tgt
using (select coalesce(b1.id, f1.id) id,
coalesce(b1.name, f1.name) name,
f1.f_rowid
from (select id,
name,
rowid f_rowid,
row_number() over (order by id) rn
from f) f1
full outer join (select id,
name,
row_number() over (order by id) rn
from b) b1
on f1.rn = b1.rn) src
on (tgt.rowid = src.f_rowid)
when matched then
update set tgt.id = src.id,
tgt.name = src.name
where tgt.id != src.id
or tgt.name != src.name
when not matched then
insert (tgt.id, tgt.name)
values (src.id, src.name);
end;
/