Oracle存儲過程中EXECUTE IMMEDIATE 執行結果是空時怎么繼續執行


無查詢結果

  1. 創建測試表和模擬數據
create table test1(
  name varchar2(10)
);
insert into test1 values ('aaa');
insert into test1 values ('bbb');
insert into test1 values ('ccc');

create table test2(
  name varchar2(10),
  n number
);
insert into test2 values ('aaa',111);
insert into test2 values ('ddd',444);
insert into test2 values ('ccc',333);

create table test3(
  name varchar2(10),
  value varchar2(10)
)
  1. 創建存儲過程

需求:對test1表結果進行遍歷,將遍歷到的name值,在test2中搜索,如果匹配到數據則將結果存放到test3

create or replace procedure test_p() is 
declare 
  cursor datas is select name from test1;

v_sql varchar2(100);
value  varchar2(50);

begin
	v_sql:= 'delete from test3';
	execute immediate v_sql;
	for data_item in datas LOOP
		v_sql:= 'select n from test2 where name='''||data_item.name||'''';
		execute immediate v_sql into value;
		v_sql:= 'insert into test3 values('''||data_item.name||''','''||value||''')';
		execute immediate v_sql;
	end loop;
end;

上面執行存儲過程,test3表收集到的數據只有一條。

這是因為在執行execute immediate v_sql into xxx的時候存儲過程出現異常了,導致后面的循環終止了。

我們可以采用異常處理來解決。

需求將沒有匹配到的值,打個標識來標記。

create or replace procedure test_p() is 
declare 
  cursor datas is select name from test1;

v_sql varchar2(100);
value  varchar2(50);

begin
  v_sql:= 'delete from test3';
  execute immediate v_sql;
  for data_item in datas LOOP
    begin
      v_sql:= 'select n from test2 where name='''||data_item.name||'''';
      execute immediate v_sql into value;
      v_sql:= 'insert into test3 values('''||data_item.name||''','''||value||''')';
      execute immediate v_sql;
      Exception when others then 
        value:= '沒有匹配到值';        -- 打個標識
        v_sql:= 'insert into test3 values('''||data_item.name||''','''||value||''')';
        execute immediate v_sql;
    end;
  end loop;
end;

上面表示當value變量賦值不成功時會自動跳到異常處理代碼塊執行。

但是上面我們只是為某個變量重新賦值,然后又需要復制N多行重復的代碼,這樣不易於維護,我們可以修改指針的指向。

create or replace procedure test_p() is 
declare 
  cursor datas is select name from test1;

v_sql varchar2(100);
value  varchar2(50);

begin
  v_sql:= 'delete from test3';
  execute immediate v_sql;
  for data_item in datas LOOP
    begin
      v_sql:= 'select n from test2 where name='''||data_item.name||'''';
      execute immediate v_sql into value;
      <<next1>>
      v_sql:= 'insert into test3 values('''||data_item.name||''','''||value||''')';
      execute immediate v_sql;
      Exception when others then 
        value:= '沒有匹配到值';
        goto next1;
    end;
  end loop;
end;

通過goto 標記來指定跳轉的位置,這樣就不需要寫重復的代碼啦


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM