無查詢結果
- 創建測試表和模擬數據
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)
)
- 創建存儲過程
需求:對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 標記
來指定跳轉的位置,這樣就不需要寫重復的代碼啦