oracle 存儲過程調用 執行


oracle存儲過程 
2011年02月11日 星期五 14:47 

SQL中調用存儲過程語句: 
call procedure_name(); 
調用時”()”是不可少的,無論是有參數還是無參數。 
定義對數據庫過程的調用時    無參數過程:{ call procedure_name}    僅有輸入參數的過程:{call procedure_name(?,?...)}     這里?表示輸入參數,創建存儲過程時用in表示輸入參數 
   僅有輸出參數的過程:{ Call procedure_name(?,?...)}     這里的?表示輸出參數,創建存儲過程時用out表示輸入參數 
   既有輸入參數又有輸出參數的過程            {call procedure_name(?,?...)}     這里的?有表示輸出參數的,也有表示輸入參數的 
下面將會對這4種情況分別舉出實例!!! 

參數過程實例 
無參數存儲過程: 
create or replace procedure stu_proc as 
pname varchar2(25); 
begin 
  select sname into pname from student where sno=1; 
  dbms_output.put_line(pname); 
end; 
或者 
create or replace procedure stu_proc as 
pname student.sname%type; 
begin 
  select sname into p_name from student where sno=1; 
  dbms_output.put_line(pname); 
end; 




參數過程實例 
僅有輸入參數的過程 
create or replace procedure stu_proc1(pno in student.sno%type) as 
pname varchar2(25); 
begin 
  select sname into pname from student where sno=pno; 
  dbms_output.put_line(pname); 
  end; 

參數過程實例 
僅有輸出參數的存儲過程 
create or replace procedure stu_proc2(pname out student.sname%type) as 
begin 
  select sname into pname from student where sno=1; 
  dbms_output.put_line(pname); 
  end; 
此種存儲過程不能直接用call來調用,這種情況的調用將在下面oracle函數調用中說明 

參數過程實例 
有輸入\輸出參數的存儲過程: 
create or replace procedure stu_proc3 
(pno in student.sno%type,pname out student.sname%type) as 
begin 
  select sname into pname from student where sno=pno; 
  dbms_output.put_line(pname); 
  end; 
此種存儲過程不能直接用call來調用,這種情況的調用將在下面oracle函數調用中說明 

Oracle函數調用存儲過程 
我們已經學習了oracle函數,下面就針對參數的4種情況分別舉出實例說明函數對存儲過程的調用 
函數調用存儲過程實例 
對無參數過程的調用: 
--函數 
create or replace function get_pname return varchar2 is 
  pname varchar2(20); 
  begin 
   stu_proc; 
   select sname into pname from student where sno=1; 
    return pname; 
    end; 
--調用 
declare 
begin 
   dbms_output.put_line('在PL/SQL中打印的結果:'||get_pname); 
end; 

函數調用存儲過程實例 
對有輸入參數過程的調用: 
create or replace function get_pname1(pno in number) return varchar2 is 
  pname varchar2(20); 
  begin 
  stu_proc1(pno in student.sno%type) 
  select sname into pname from student where  sno=pno; 
    return pname; 
    end; 
--調用 
declare 
begin 
   dbms_output.put_line('在PL/SQL中打印的結果:'||get_pname1(2)); 
end; 

函數調用存儲過程實例 
對有輸出參數過程的調用: 
create or replace function get_pname2(pname out varchar2) return varchar2 is 
  begin 
  stu_proc2(pname out student.sname%type); 
    return pname; 
    end; 
--調用 
declare 
pname student.sname%type; 
begin 
   dbms_output.put_line('在PL/SQL中打印的結果:'||get_pname2(pname)); 
end; 

函數調用存儲過程實例 
對有輸入\輸出參數過程的調用: 
create or replace function get_pname3(pno in number,pname out varchar2) return varchar2 is 
  begin 
stu_proc3(pno in student.sno%type,pname out student.sname%type); 
    return pname; 
    end; 
--調用 
declare 
pname student.sname%type; 
begin 
   dbms_output.put_line('在PL/SQL中打印的結果:'||get_pname3(2,pname)); 
end; 

JAVA調用數據庫存儲過程 
前面我們已經講述了有關oracle數據庫的存儲過程的幾種形式,以及oracle函數對存儲過程的調用,下面我將根據上面存儲過程的實例來舉出JAVA對oracle存儲過程的調用 
JAVA調用實例 
僅有返回值的過程: 
public static void main(String[] args) { 
Connection conn=BBConnection.getConnection(); 
String sql="{call stu_proc2(?)}"; 
try { 
CallableStatement statement=conn.prepareCall(sql); 
statement.registerOutParameter(1,Types.VARCHAR); 
statement.execute(); 
String pname=statement.getString(1); 
System.out.println(pname); 
} catch (SQLException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 




JAVA調用實例 
既有輸入參數又有輸出參數的過程 
public static void main(String[] args) { 
        Connection conn=BBConnection.getConnection(); 
        String sql="{call stu_proc3(?,?)}"; 
        try { 
                CallableStatement statement=conn.prepareCall(sql); 
                statement.setInt(1, 1); 
                statement.registerOutParameter(2,Types.VARCHAR); 
                statement.execute(); 
                String pname=statement.getString(2); 

                System.out.println(pname); 
         } catch (SQLException e) { 
               e.printStackTrace(); 
         } 

JAVA調用實例 
下面將舉出無out參數的調用實例 
這種參數不適於用在查詢語句上,因為查詢語句需要有返回值才能被JAVA調用 
返回到 OUT 參數中的值可能會是JDBC NULL。當出現這種情形時,將對 JDBC NULL 值進行轉換以使 getXXX 方法所返回的值為 null、0 或 false,這取決於getXXX 方法類型。對於 ResultSet 對象,要知道0或false是否源於JDBCNULL的唯一方法,是用方法wasNull進行檢測。如果 getXXX 方法讀取的最后一個值是 JDBC NULL,則該方法返回 true,否則返回 flase 

JAVA調用實例 
僅有參數的過程: 
public static void main(String[] args) { 
Connection conn=BBConnection.getConnection(); 
String sql="{call stu_proc1(?)}"; 
try { 
CallableStatement statement=conn.prepareCall(sql); 
statement.setInt(1, 1); 
statement.execute(); 
System.out.println(statement.execute()); 
} catch (SQLException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
}finally{ 
try { 
conn.close(); 
} catch (SQLException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 





JAVA調用實例 
無參數過程: 
public static void main(String[] args) { 
Connection conn=BBConnection.getConnection(); 
String sql="{call stu_proc()}"; 
try { 
CallableStatement statement=conn.prepareCall(sql); 
statement.execute(); 
System.out.println(statement.execute()); 
} catch (SQLException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
}finally{ 
try { 
conn.close(); 
} catch (SQLException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
}           


通過調用數據庫函數調用存儲過程 
下面將舉一個通過數據庫函數來調用存儲過程: 
public static void main(String[] args) { 
Connection conn=BBConnection.getConnection(); 
String sql="{?=call get_pname1(?)}"; 
try { 
CallableStatement statement=conn.prepareCall(sql); 
statement.registerOutParameter(1, Types.VARCHAR); 
statement.setInt(2, 1); 
statement.execute(); 
System.out.println(statement.getString(1)); 


} catch (SQLException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
}finally{ 
try { 
conn.close(); 
} catch (SQLException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 




?表示函數return的值, get_pname1是數據庫函數名 
存儲過程的out和in都是以參數傳進,這就是函數和存儲過程的區別之一 
存儲過程的異常處理 
為了提高存儲過程的健壯性,避免運行錯誤,當建立存儲過程時應包含異常處理部分。 
異常(EXCEPTION)是一種PL/SQL標識符,包括預定義異常、非預定義異常和自定義異常; 
預定義異常是指由PL/SQL提供的系統異常;非預定義異常用於處理與預定義異常無關的Oracle錯誤(如完整性約束等);自定義異常用於處理與Oracle錯誤的其他異常情況。 
RAISE_APPLICATION_ERROR用於自定義錯誤消息,並且消息號必須在-20000~-20999之間 
存儲過程的異常處理實例 
Oracle數據庫中提供了一些異常處理的方法,下面通過一個實例來說明 
create or replace procedure stu_proc6(pno in student.sno%type,pname out student.sname%type) 
       is 
       begin 
          select sname into pname from student where sno=pno; 
       EXCEPTION 
                 when NO_DATA_FOUND then 
                RAISE_APPLICATION_ERROR 
(-20011,'ERROR:不存在!'); 
end; 
Oracle提供的異常處理 
     命名的系統異常          產生原因 
ACCESS_INTO_NULL         未定義對象 
CASE_NOT_FOUND         CASE 中若未包含相應的 WHEN ,並且沒有設置 
COLLECTION_IS_NULL         集合元素未初始化 
CURSER_ALREADY_OPEN          游標已經打開 
DUP_VAL_ON_INDEX          唯一索引對應的列上有重復的值 
INVALID_CURSOR         在不合法的游標上進行操作 
INVALID_NUMBER        內嵌的 SQL 語句不能將字符轉換為數字 
NO_DATA_FOUND          使用 select into 未返回行,或應用索引表未初始化的 
TOO_MANY_ROWS         執行 select into 時,結果集超過一行 
ZERO_DIVIDE             除數為 0 
SUBSCRIPT_BEYOND_COUNT     元素下標超過嵌套表或 VARRAY 的最大值 
SUBSCRIPT_OUTSIDE_LIMIT     使用嵌套表或 VARRAY 時,將下標指定為負數 
VALUE_ERROR             賦值時,變量長度不足以容納實際數據 
LOGIN_DENIED               PL/SQL 應用程序連接到 oracle 數據庫時,提供了不正                    確的用戶名或密碼 
NOT_LOGGED_ON         PL/SQL 應用程序在沒有連接 oralce 數據庫的情況下訪                    問數據 
PROGRAM_ERROR          PL/SQL 內部問題,可能需要重裝數據字典& pl./SQL系                    統包 
ROWTYPE_MISMATCH         主游標變量與 PL/SQL 游標變量的返回類型不兼容 
SELF_IS_NULL             使用對象類型時,在 null 對象上調用對象方法 
STORAGE_ERROR         運行 PL/SQL 時,超出內存空間 
SYS_INVALID_ID              無效的 ROWID 字符串 
TIMEOUT_ON_RESOURCE         Oracle 在等待資源時超時 
存儲過程的異常處理實例 
自定義異常處理: 
create or replace procedure stu_proc7(pno in student.sno%type, 
       pon in student.sno%type 
       ) 
       is 
           v_raise exception; 
           v_name student.sname%type; 
       begin 
         if pno=101 then 
           raise v_raise; 
           end if; 
           select sname into v_name from student where sno=111111; 
       exception 
           when v_raise then 
             RAISE_APPLICATION_ERROR(-20010,'ERROR:not existed!'); 
           when no_data_found then 
             RAISE_APPLICATION_ERROR(-20011,'ERROR:不存在!'); 
end; 
存儲過程的事務處理 
事務用於確保數據的一致性,由一組相關的DML語句組成,該組DML語句所執行的操作要么全部確認,要么全部取消。 
當執行事務操作(DML)時,Oracle會在被作用的表上加鎖,以防止其他用戶改變表結構,同時也會在被作用的行上加行鎖,以防止其他事務在相應行上執行DML操作。 
當執行事務提交或事務回滾時,Oracle會確認事務變化或回滾事務、結束事務、刪除保存點、釋放鎖。 
存儲過程的事務處理 
提交事務(COMMIT)確認事務變化,結束當前事務、刪除保存點,釋放鎖,使得當前事務中所有未決的數據永久改變。 
保存點(SAVEPOINT)在當前事務中,標記事務的保存點。 
回滾事務(ROLLBACK)回滾整個事務,刪除該事務所定義的所有保存點,釋放鎖,丟棄所有未決的數據改變。 
回滾事務到指定的保存點(ROLLBACK TO SAVEPOINT)回滾當前事務到指定的保存點,丟棄該保存點創建后的任何改變,釋放鎖。 
存儲過程的事務處理 
當執行DDL、DCL語句,或退出SQL*PLUS時,會自動提交事務; 
事務期間應避免與使用者互動; 
查詢數據期間,盡量不要啟動事務; 
盡可能讓事務持續地越短越好; 
在事務中盡可能存取最少的數據量。 

事務處理實例 
存儲過程事務處理實例: 
create or replace procedure stu_proc8 
       is 
       begin 
         insert into student values(102,'sky','m',22,'gong'); 
         savepoint savepoint1; 
         insert into student values(102,'good','w',20,'wang'); 
         dbms_output.put_line('error'); 
         update student set sno=103 where sname='good'; 
         commit; 
         exception 
           when dup_val_on_index then 
             rollback to savepoint savepoint1; 
             RAISE_APPLICATION_ERROR(-20010,'ERROR:違反唯一索引約束!'); 
        end; 
數據庫函數和存儲過程的包 
創建包(package) 
函數: 
create or replace package 包名 as 函數 
注意:as后可加多個函數 
存儲過程: 
Create or replace package 包名 as 存儲過程 
注意:as后可加多個存儲過程 
包的調用 
函數的包調用: 
call 包名.函數名; 
存儲過程的包調用: 
call 包名.存儲過程名; 
THE  END


免責聲明!

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



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