近日,因為工作需要,時間投入到寫儲存過程的中。下面貼上儲存過程。進行分析,以便自己記憶,和朋友分享儲存過程的寫法。
曾幾何時,認為儲存過程很難,現在看來也並非如此。
此儲存過程乃是我們用到遞迴刪除。
--宣告乙個帶引數的儲存過程,引數都是varchar型,如果帶有輸出引數的話,引數後面跟的型別必須有個out 例: num out integer;
create or replace procedure recursion_delete(v_tablename varchar2,v_fieldvalue varchar2) is
--kobe.lee 編輯於2009-09-17
--遞迴刪除
--宣告儲存過程中用到的引數
--v_tablename varchar2(100); -- 表名
--v_fieldvalue varchar2(100); --字段值
v_fieldvalue2 varchar2(100);
v_count integer; --總數
v_count2 integer;
v_reltable varchar2(100); --關係表
v_relfield varchar2(100); --關係表字段
v_relfieldvalue varchar2(100); --關係表字段值
v_sql_str varchar2(100); --動態sql
v_sql_str2 varchar2(100);
v_sql_str3 varchar2(100);
v_primarykey_field varchar2(100); --主鍵字段
--宣告游標
cursor mycur is select str.reltable,str.relfield from systablerel str where str.maintable=v_tablename and str.associatedelete=1;
--此游標為動態游標 必須宣告為引用游標
type cur_type is ref cursor;
mycur1 cur_type;
begin
--取出來所有和此表有關係的表名字。並統計數量,如果大於0 進行迴圈。
select count(*) into v_count from systablerel str where str.maintable=v_tablename and str.associatedelete=1;
--如果大於0證明還有引用,對引用進行迴圈
if (v_count>0) then
--開啟游標
open mycur;
--進入迴圈
loop
--從游標中取出引數進行賦值
fetch mycur into v_reltable,v_relfield;
if mycur%notfound then exit; --如果不存在 退出
elsif mycur%found then --如果存在繼續執行
--先通過v_reltable查字段
select distinct str2.mainfield into v_primarykey_field from systablerel str2 where str2.maintable=v_reltable;
--動態sql(動態拼接sql的方法)
v_sql_str := 'select '||v_primarykey_field||' from '||v_reltable||' where '||v_relfield||'='''||v_fieldvalue||'''';
--先查詢是否有資料,如果有資料進入迴圈
v_sql_str2 := 'select count(*) from '||v_reltable||' where '||v_relfield||'='''||v_fieldvalue||'''';
--執行動態sql,把執行出來的值給v_count2
execute immediate v_sql_str2 into v_count2;
if (v_count2>0) then
--給動態游標賦值
open mycur1 for v_sql_str;
--對動態游標進行迴圈判斷
loop
fetch mycur1 into v_fieldvalue2;
if mycur1%notfound then exit; --如果不存在 退出
elsif mycur1%found then --如果存在繼續執行
--繼續呼叫儲存過程(儲存過程呼叫儲存過程,呼叫自己,如果帶引數,可以用類似動態sql的方式宣告後動態執行)
recursion_delete(v_reltable,v_fieldvalue2);
end if;
end loop;
end if;
end if;
end loop;
--迴圈結束,證明此資料雖然有關係表,但是沒有引用,刪除資料。
--查詢此表的主見字段
select distinct str3.mainfield into v_primarykey_field from systablerel str3 where str3.maintable=v_tablename;
v_sql_str3 := 'delete from '||v_tablename||' where '||v_primarykey_field||'='''||v_fieldvalue||'''';
execute immediate v_sql_str3;
--證明此為最後一層,開始刪除
elsif (v_count=0) then
select distinct str3.mainfield into v_primarykey_field from systablerel str3 where str3.maintable=v_tablename;
v_sql_str3 := 'delete from '||v_tablename||' where '||v_primarykey_field||'='''||v_fieldvalue||'''';
execute immediate v_sql_str3;
end if;
end;
在sql_plus中呼叫帶引數的儲存過程的方法:
declare
v_flag integer;
begin
--儲存過程名以及引數,v_flag輸出到哪個變數上
deleteproc('plan','4028e48523bb4be80123bbb8ee8a000d',1,v_flag);
dbms_output.put_line(v_flag);
end;
在高階點的儲存過程,可能會用到臨時表,以及group by 進行分組......
oracle的儲存過程
以前一直對oracle的儲存過程概念很模糊,今天來複習一下 第一步 開啟輸出 set serveroutput on 第二步 建立表空間 create tablespace test data logging datafile d test.dbf size 50m autoextend on ne...
Oracle儲存過程呼叫儲存過程
oracle儲存過程呼叫有返回結果集的儲存過程一般用光標的方式,宣告乙個游標,把結果集放到游標裡面,然後迴圈游標 declare newcs sys refcursor cs1 number cs2 number cstype table rowtype table列的個數和newcs返回的個數一樣...
ORACLE儲存過程
自定義函式開始 create or replace function fn wftemplateidget templatecategoryid number,organid number,templatemode number return number istemplateid number i...