问题1:报错:未找到任何数据
错误截图:
基础数据准备:
declare
v_dname scott.dept.dname%type;
begin
select t.dname
into v_dname
from scott.dept t
where t.deptno = 50; -- 不存在 deptno=50 的记录
dbms_output.put_line(v_dname);
end;
原因分析
未找到任何数据:不存在 deptno = 50 的记录
解决办法
解决办法1:使用 “聚合函数”(简单、粗暴,但要 ‘心中有数’)
declare
v_dname scott.dept.dname%type;
begin
select MAX(t.dname) -- 记录不存在时,为空
into v_dname
from scott.dept t
where t.deptno = 50; -- 不存在 deptno=50 的记录
dbms_output.put_line(v_dname); -- 输出空
end;
解决办法2:捕获异常(所以在写该语句时,要特别留意!)
declare
v_dname scott.dept.dname%type;
begin
select t.dname
into v_dname
from scott.dept t
where t.deptno = 50; -- 不存在 deptno=50 的记录
dbms_output.put_line(v_dname);
exception
when others then
dbms_output.put_line(sqlerrm);
dbms_output.put_line(dbms_utility.format_error_backtrace);
end;
问题2:数据同步前后数据不匹配
图示:source_table、source_table2 以 sno 相同的记录同步至 tartget_table
基础数据准备:
create table scott.source_table (
sno number(10),
sname varchar2(50)
);
create table scott.source_table2 (
sno number(10),
address varchar2(50)
);
create table scott.target_table (
sno number(10),
sname varchar2(50),
address varchar2(50)
);
insert into scott.source_table(sno, sname) values(1, '瑶瑶');
insert into scott.source_table(sno, sname) values(2, '优优');
insert into scott.source_table(sno, sname) values(3, '倩倩');
insert into scott.source_table(sno, sname) values(4, '朝爷');
insert into scott.source_table(sno, sname) values(5, '姥姥');
insert into scott.source_table2(sno, address) values(1, '赤壁');
insert into scott.source_table2(sno, address) values(3, '牌洲');
insert into scott.source_table2(sno, address) values(4, '嘉鱼');
commit;
同步数据脚本:(简易版)
--************************************************************************
-- 功能说明:把表 scott.source_table、scott.source_table2 中的数据
-- 同步至表 scott.target_table
-- 备注 : 简化程序,仅为说明现象
--************************************************************************
declare
v_address scott.source_table2.address%type;
v_count number(1);
begin
for i in (select st.sno, st.sname from scott.source_table st) loop
select count(1)
into v_count
from scott.source_table2 st2
where st2.sno = i.sno;
-- 变量赋值,报错点!(报错场景:当 v_count = 0 时)
if v_count >= 1 then
select st2.address
into v_address
from scott.source_table2 st2
where st2.sno = i.sno;
end if;
-- 插入 "目标表"
insert into scott.target_table
(sno, sname, address)
values
(i.sno, i.sname, v_address);
end loop;
-- 最后提交数据
commit;
end;
原因分析
1. 当 sno = 1 时,能够查询到 address = '赤壁',此时 v_address = '赤壁'
2. 当 sno = 2 时,查询不到 address,此时 v_address 还是 '赤壁'('并未初始化')
所以,问题出来了!
解决办法
解决办法1:在给 v_address 赋值之前,先初始化 v_address
-- 解决办法:在给 v_address 赋值之前,先初始化 v_address
v_address = '';
if v_count >= 1 then
select st2.address
into v_address
from scott.source_table2 st2
where st2.sno = i.sno;
end if;
解决方法2(推荐):使用关联查询,避免 select into 的赋值形式
-- 先清空 "目标表",以免影响测试
truncate table scott.target_table;
-- 使用关联查询,如:for 循环中
declare
v_address scott.source_table2.address%type;
begin
for i in (select st.sno,
st.sname,
(select st2.address
from scott.source_table2 st2
where st2.sno = st.sno) address
from scott.source_table st) loop
-- 插入 "目标表"
insert into scott.target_table
(sno, sname, address)
values
(i.sno, i.sname, i.address);
end loop;
commit;
end;