plsql的存儲過程,存儲函數,觸發器

一存儲過程

1.什麼是存儲過程,爲什麼使用存儲過程

存儲過程是存儲在數據庫中供用戶調用的子程序,由於存儲過程是存儲在數據庫中已經編譯好的程序,在調用的時候,不必再次進行編譯,從而提高了程序的運行效率.

2.存儲過程的語法

創建存儲過程的語法

create [or replace] procedure procedure_name ([{in| out}]  data_type,parameter [{in| out}]  data_type..)

(is|as)

pl/sql子程序;

in:表示輸入參數                                     out:輸出參數

調用存儲過程有兩種方法:

第一種:execute(exec)  procedure_name(參數列表)

第二種:begin

procedure_name(參數列表)

end;

3.無參數的存儲過程

 

create or replace
PROCEDURE empename as
emp_ename emp.ename%type;
emp_sal emp.sal%type;
begin
select ename ,sal into emp_ename,emp_sal from emp where empno=7934;
dbms_output.put_line(emp_ename||'的工資是'|| emp_sal);
end;

注意:聲明變量不需要寫declare

調用存儲過程

set serveroutput on;
begin
empename;
end;

4.帶參數的存儲過程

create or replace
PROCEDURE empename(enum in number,emp_ename out emp.ename%type,emp_sal out emp.sal%type) 
as
begin
select ename ,sal into emp_ename,emp_sal from emp where empno=enum;
end;


調用存儲過程:

set serveroutput on;
declare
emp_ename emp.ename%type;
emp_sal emp.sal%type;
begin
empename(7369, emp_ename, emp_sal);
dbms_output.put_line(emp_ename||'的工資是'|| emp_sal);
end;


二存儲函數

函數爲一命名的存儲程序,可帶參數,並返回一計算值

 

1.存儲函數的語法

create oy replace function function_name([{in| out}]  data_type,parameter [{in| out}]  data_type..)

return 返回值的數據類型

begin

函數要做的操作

end;

in:表示輸入參數                                     out:輸出參數

 

create or replace
function emp_function(eno in number) RETURN NUMBER
as 
esal NUMBER;
ecommon NUMBER;
BEGIN
select sal ,comm into esal, ecommon from emp where empno=eno;
return esal+nvl(ecommon,0); 
end;


調用函數

set serveroutput on;
declare
sal_sum NUMBER;
begin
sal_sum:=emp_function(7369);
dbms_output.put_line('7369的年薪是'||sal_sum);
end;

 

 

三.使用jdbc怎麼調用存儲函數和存儲過程

jdbc調用存儲函數和存儲過程使用CallableStatement接口,sql語句如下;

{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}------------------------------------->存儲函數

{call <procedure-name>[(<arg1>,<arg2>, ...)]}----------------------------------->存儲過程

 

調用存儲過程

 

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import oracle.jdbc.OracleTypes;
import com.hotelmanagersystem.util.JdbcUtil;

public class maintest {
	public static void main(String[] args) {
     Connection conn=null;
     CallableStatement sts=null;
     ResultSet rs=null;
     try {
		conn=JdbcUtil.getConnection();
		sts=conn.prepareCall("call empename(?,?,?)");
		//設置輸入參數
		sts.setInt(1,7369);
		//註冊輸出參數
	    sts.registerOutParameter(2,OracleTypes.VARCHAR);
	    sts.registerOutParameter(3,OracleTypes.NUMBER);
		sts.execute();
		System.out.println(sts.getString(2)+"的工資是"+sts.getInt(3));
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally{
		JdbcUtil.closeAll(rs, sts, conn);
	}
     
	}

}


調用存儲函數;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import oracle.jdbc.OracleTypes;
import com.hotelmanagersystem.util.JdbcUtil;

public class maintest {
	public static void main(String[] args) {
     Connection conn=null;
     CallableStatement sts=null;
     ResultSet rs=null;
     try {
		conn=JdbcUtil.getConnection();
		sts=conn.prepareCall("{?=call emp_function(?)}");
		//設置輸入參數
		sts.setInt(2,7369);
		//註冊輸出參數
		sts.registerOutParameter(1,OracleTypes.NUMBER);
		sts.execute();
		System.out.println("年薪是"+sts.getInt(1));
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally{
		JdbcUtil.closeAll(rs, sts, conn);
	}
     
	}

}


注意:調用函數的大括號不能省略,調用存儲過程可以省略。

四.包和包體

1.包和包體

前面我們看到的都是返回一行數據,如果返回多行數據怎麼處理了,我們就可以使用遊標,但是在存儲過程和函數中使用遊標只能在包中,現在來看包是什麼

包就是一組相關的過程,函數,變量,常量和遊標等PL/SQL 程序設計元素的組合,包分爲包頭和包體,

包頭裏面定義了包裏面應該包含的 變量,過程,函數 等

在包頭裏面需要定義包裏面的函數,存儲過程等

包體裏面對包頭中定義的函數存儲過程等進行實現

包頭的定義語法:

CREATE    OR   REPLACE   PACKAGE package_name IS

//遊標,變量,過程,函數等

 TYPE mycursor IS REF CURSOR;
 PROCEDURE myproc(outcursor IN OUT mycursor);
END package_name;

包體:

CREATE   OR    REPLACE    PACKAGE BODY mypack IS
PROCEDURE myproc(
        outcursor IN OUT mycursor
    )
IS
BEGIN
OPEN outcursor FOR
SELECT*FROM Student WHERE ROWNUM<10;
RETURN;
END myproc;
END;

包頭代碼:

CREATE OR REPLACE
PACKAGE MYPACKAGE AS
type empcursor is ref cursor;
PROCEDURE queryempList(dno in NUMBER,empList out empcursor);
  /* TODO 在此輸入程序包聲明 (類型, 異常錯誤, 方法等) */

END MYPACKAGE;


包體代碼;

CREATE OR REPLACE
PACKAGE BODY MYPACKAGE AS

  PROCEDURE queryempList(dno in NUMBER,empList out empcursor) AS
  BEGIN
    open emplist for select *from emp where deptno= dno;
--注意結束過程的語句
END queryempList ;
End;


2.JDBC調用包和包體

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import oracle.jdbc.OracleTypes;
import oracle.jdbc.internal.OracleCallableStatement;

import com.hotelmanagersystem.util.JdbcUtil;

public class maintest {
	public static void main(String[] args) {
     Connection conn=null;
     CallableStatement sts=null;
     ResultSet rs=null;
     try {
		conn=JdbcUtil.getConnection();
               
                //注意sql語句的寫法
                 sts=conn.prepareCall("{call MYPACKAGE.queryempList(?,?)}");
		//設置輸入參數
		sts.setInt(1,10);
		//註冊輸出參數,參數是遊標型的
		sts.registerOutParameter(2,OracleTypes.CURSOR);
		sts.execute();
		//轉換成oracle的statement類型,就會有cursor方法
	    rs=((OracleCallableStatement)sts).getCursor(2);
	    while(rs.next()){
	    String name =rs.getString("ename");
	    int sal = rs.getInt("sal");
	    System.out.println(name+"的薪水是"+sal);
	    }
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally{
		JdbcUtil.closeAll(rs, sts, conn);
	}
     
	}
}


五:觸發器

pl/sql是一個與表相關的存儲的pl/sql程序,每當一個特定的數據庫操作語句(update,insert,delete)在指定的表上發出時,oracle自動的執行觸發器中定義的語句序列。

創建觸發器的語法格式:

create   [or replace]  trigger 觸發器名

{before|after}

{delate | insert | updsate [of]列名 }

on 表名

[for each row [where( 條件)]]

pl/sql塊

觸發語句與僞列記錄變量的值

觸發語句

:old

:new

Insert

所有字段都是空(null)

將要插入的數據

Update

更新以前該行的值

更新後的值

delete

刪除以前該行的值

所有字段都是空(null)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章