我想请教一下,,怎么在存储过程里面判断多个DB_LINK的有效性?是这样的,我需要在系统里面抽取多个省份的数据, 必须为每个省份的建立一个DB_LINK,,,但是现在发现如果某个省份的DB_LINK出了问题, 程序就死掉了, 不会再往下走了. 以致影响了其他省份的抽取,所以我想在程序运行之前先写个程序验证配置表里面的DB_LINK的有效性, 有效的设为Y, 无效的设为N, 抽取程序只读取配置为Y的省份进行抽取.程序这样: -- 先将所有的都失效
update bicode.h_etl_pro_config h set h.v_valid='N';
<<check1>>
-- 找出省公司对应的 用户名 DBLINK
for pro_item in v_pro_cur loop
v_check := 0;
v_sql :='select 1 from dual@'|| pro_item.etl_db_link;
execute immediate v_sql into v_check; if v_check = 1 then
update bicode.h_etl_pro_config h set h.v_valid='Y'
where h.pro_unit_code = pro_item.pro_unit_code;
commit;
end if; end loop check1;
--exception when others then goto check1;但是问题仍然是一样, 只要中间有某个无效的DBLINK出现, 整个程序就跳出来了, 接下来的那些就不检查了.exception 更加烦人. 不能不处理, 也不能加在FOR里面, 也不能用GOTO.
不能像JAVA的TRY CATCH那样,捕捉到了不处理,直接进行下一次的循环..
update bicode.h_etl_pro_config h set h.v_valid='N';
<<check1>>
-- 找出省公司对应的 用户名 DBLINK
for pro_item in v_pro_cur loop
v_check := 0;
v_sql :='select 1 from dual@'|| pro_item.etl_db_link;
execute immediate v_sql into v_check; if v_check = 1 then
update bicode.h_etl_pro_config h set h.v_valid='Y'
where h.pro_unit_code = pro_item.pro_unit_code;
commit;
end if; end loop check1;
--exception when others then goto check1;但是问题仍然是一样, 只要中间有某个无效的DBLINK出现, 整个程序就跳出来了, 接下来的那些就不检查了.exception 更加烦人. 不能不处理, 也不能加在FOR里面, 也不能用GOTO.
不能像JAVA的TRY CATCH那样,捕捉到了不处理,直接进行下一次的循环..
when others then
null;
对每条数据(即每个DBLINK)进行异常判断。若出现异常,不作为。继续检查。
begin case declare
end exit for goto if loop mod null pragma raise return select
update while with <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe
行:176
文本:exception when others then null;
for pro_item in v_pro_cur loop
v_check := 0;
v_sql :='select 1 from dual@'|| pro_item.etl_db_link;
execute immediate v_sql into v_check; if v_check = 1 then
update bicode.h_etl_pro_config h set h.v_valid='Y'
where h.pro_unit_code = pro_item.pro_unit_code;
commit;
end if;
exception when others then null;
end loop check1;
LOOP里必须写在begin ... end块里。SQL> create or replace procedure test
2 IS
3 v_areaid area.areaid%TYPE;
4
5 begin
6 FOR i IN 1..10 LOOP
7 BEGIN
8 SELECT areaid INTO v_areaid FROM area;
9 EXCEPTION
10 WHEN no_data_found THEN
11 NULL;
12 END;
13 NULL;
14 END LOOP;
15 end ;
16 /过程已创建。SQL> show error
没有错误。
SQL>
检查配置表里面的 DB_LINK 的有效性, 避免因为某个省的连接失败影响到其他省的抽取
*/
procedure P_CHECK_DBLINK
is
-- 省公司的信息配置表
cursor v_pro_cur is
select * from bicode.h_etl_pro_config p
order by p.date_base_name;
v_sql varchar2(500);
v_check number :=0;
begin
-- 先将所有的都失效
update bicode.h_etl_pro_config h set h.v_valid='N';
-- 找出省公司对应的 用户名 DBLINK
for pro_item in v_pro_cur loop
begin
v_check := 0;
v_sql :='select 1 from dual@'|| pro_item.etl_db_link;
execute immediate v_sql into v_check; if v_check = 1 then
update bicode.h_etl_pro_config h set h.v_valid='Y'
where h.pro_unit_code = pro_item.pro_unit_code;
commit;
end if;
end;
exception when others then null;
end loop;
end P_CHECK_DBLINK;
晕,,,,为什么我的还是报错的?
多谢suiziguo!!!!!!!!!!!!!!!!分全给你了
上面这句可能触发异常,所以你要它发生异常时,程序继续运行,必须单独对其异常进行捕捉和处理。
也就是说,要想做到子程序遇到异常继续,必须针对每一可能发生异常的单独的语句进行处理,而不是整个块。
PL/SQL里就是这么麻烦,但这样也保持了事务完整性,从而保持数据一致性。
增加begin ... exception...end就行了-- 先将所有的都失效
UPDATE bicode.h_etl_pro_config h SET h.v_valid = 'N';
< < check1 >>
-- 找出省公司对应的 用户名 DBLINK
FOR pro_item IN v_pro_cur LOOP
v_sql := 'select 1 from dual@' || pro_item.etl_db_link;
BEGIN
EXECUTE IMMEDIATE v_sql
INTO v_check;
UPDATE bicode.h_etl_pro_config h
SET h.v_valid = 'Y'
WHERE h.pro_unit_code = pro_item.pro_unit_code;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END LOOP check1;