1. 程式人生 > >PL/SQL儲存函式,儲存過程

PL/SQL儲存函式,儲存過程

一.儲存過程和儲存函式

1.1什麼是儲存過程和儲存函式:

指儲存在資料庫中供所有的使用者程式呼叫的 子程式叫儲存過程、儲存函式。
儲存過程和儲存函式的相同點:完成特定功能的程式
儲存過程和儲存函式的區別:是否用return 語句返回值,儲存過程不能使用return 返回一個函式的值,儲存函式可以,對於其他的
可以認為他們是相同的。

二、建立和使用儲存過程


使用create procedure命令建立儲存過程和儲存函式

語法:

	--建立或替換一個儲存過程              引數列表需要指明輸入或者輸出引數
	create [or replace] procedure 過程名(Name in | out type, Name in | out type, ...)
	as | is --相當於PL/SQL塊的declare,這裡不可省略
	PLSQL子程式體;

1.2.1不帶引數的儲存過程

--第一個儲存過程列印helloworld --注意不帶引數的儲存過程過程名不能有()

create [or replace] procedure sayhelloWorld
	as 
	--相當於PL/SQL中declare說明部分,不過這裡即使沒有說明部分也需要寫
	begin
		dbms_output.put_line('helloWorld');
	end sayhelloWorld;

如果使用PL/SQL Developer 工具,如果執行成功可以在左邊的procedure區域看到我們執行後編譯後的儲存過程(成功一般顯示為綠色,如果不對會有一個小紅x)

1.2.2呼叫儲存過程

方式一:在 Command Windows(命令視窗中執行) exec sayhelloWorld();


方式二:可以在SQL Windows或 Command Windowsz中執行PL/SQL呼叫

1.2.3帶引數的儲存過程

--建立一個帶引數的儲存過程,給指定的員工漲100員工資,並列印漲前和漲後的薪水

--in表示是一個輸入引數,如果帶引數,需要指明是輸入引數還是輸出引數

	create or repalce procedure raisesalary(eno in number) 
		as
			--定義一個變數儲存漲前的薪水
			psal emp.sal%type;
		begin
			--得到員工的漲前的薪水
			select sal into psal emp where empno=eno;
			--給員工漲100
			update emp set sal = sal+100 where empno = eno;
			--這裡進行了update,不過我們一般不在儲存過程和儲存函式中進行提交事務,一般由呼叫者進行提交

			--列印漲前和漲後的薪水
			dbms_output.put_line('漲前:'||psal||'漲後'||(psal+100));
		end;

1.2.4 帶引數的儲存過程的呼叫

			begin
				raisesalary(7839); --給員工號為7839漲工資
				raisesalary(7566); --給員工號為7566漲工資
			end;

1.3儲存過程的debug除錯

有時候有一些儲存過程比較大,需要進行debug除錯,看是否符合我們的邏輯需求,使用PL/SQL Developer可以對儲存過程進行除錯

1.3.1選中需要除錯的儲存過程--》test進入debug除錯模式

1.3.2設定斷點,可以單步執行

三、儲存函式


函式(Function) 為一命名的儲存程式,可帶引數,並返回一計算值
函式和過程結構類似,但必需要有一個return子句,用於返回函式數值。
 

3.1建立儲存函式的語法

--帶引數的儲存函式必需指明引數列表是輸入引數還是輸出引數

--假如不帶引數,不能帶()

	create [or replace] function 函式名(Name in | out type, Name in | out type, ...)
	return 函式值型別
	as | is
	PL/SQL子程式體;


案例:

--儲存函式:查詢某個員工的年收入

		create or replace function queryempincomme(eno in number)
		return number
		as
			--定義變數儲存員工的薪水和獎金
			psal emp.sal%type;
			pcomm emp.comm%type;
		begin
			--得到員工的月薪和獎金
			select sal,comm into psal,pcomm from emp where empno=eno;
			--直接返回年收入
			return psal*12+nvl(pcomm,0);
		end;

3.1.1儲存函式的呼叫

		declare
			ypsal number;
		begin
			--得到員工7891的年收入
			ypsal:=queryempincomme(7891);
			dbms_output.put_line(ypsal);
		end;

四、in和out 引數

前邊我們介紹了儲存過程和儲存函式
a.一般來講,儲存過程和儲存函式的區別在於儲存函式可以有一個返回值;而儲存過程沒有返回值
b.如果儲存過程或儲存函式帶引數的話我們需要指明是輸入引數還是輸出引數
c.儲存過程和儲存函式都可以通過out引數指定一個或多個輸出引數,我們可以利用out引數,在過程或函式中實現返回一個或多個值
 (即儲存過程本來不能有返回值,但利用out引數,我們就可以實現儲存過程返回值)
d.一般如果需要返回多個值,我們優先使用儲存過程,如果只要返回一個值我們優先使用儲存函式

案例:
--利用out引數查詢員工的姓名,月薪和職位

	create or replace procedure queryempinfo(eno in number,pename out varchar2,psal out nubmer,pjob out varchar2)
	as
	begin
		--得到員工的姓名,月薪,職位
		select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
	end;


呼叫:

	declare 
		eno number;
		pename varchar2(30);
		psal number;
		pjob varchar2(200);
	begin
		eno := 7839;
		--呼叫儲存過程,我們可以得到out引數的返回值
		queryempinfo(eno,pename,psal,pjob);
		dbms_output.put_line(pename);
		dbms_output.put_line(psal);
		dbms_output.put_line(pjob);
	end;



問題:上邊的案例只利用out引數返回了員工的部分資訊
1.假如需要查詢員工的所有資訊,out引數有很多,難道要寫很多個out引數?
2.查詢某個部門中所有員工的所有資訊---》out中返回一個集合

五、程式包

程式包在一般情況下使用的還是比較少的,這裡粗略的說一下,如果需要使用,請見其他資料如《精通Oracle10g SQL和PL/SQL》

oracle中的程式包分為包頭和包體,包頭負責宣告,包體負責實現(者很像java中的介面與實現類的關係)

包頭語法:

	create [or replace] package package_name
	is | as
	--定義公用常量、變數、遊標、型別
	--定義公用的過程和函式
	end package_name;


包體語法

	create [or replace] package body package_name
	is | as
	--定義私有常量、變數、型別、遊標、過程和函式
	--實現公用的過程和函式
	end package_name

案例:查詢某個部門中所有員工的所有資訊,這裡使用如下方案,實現第4條留下的幾個問題out引數很多顯然不可取,我們是使用cursor游標實現

建立包頭

	create or replace package mypackage as 
		--定義公用的型別 自定義型別empcursor 為 cursor型別
		type empcursor is ref cursor;
		--定義公用的過程和函式 --之後需要在包體中實現
		procedure queryEmpList(dno in number,empList out empcursor);
		end mypackage;

建立包體

		create or replace package body mypackage
		as
			procedure queryEmpList(dno in number,empList out empcursor)
			as
			begin
				--開啟游標
				open empcursor from select * from emp where deptno=dno;
			end queryEmpList;
		end mypackage;


呼叫程式包:
呼叫公用變數
exec 程式包名.公用變數名 := 賦值;
呼叫公共過程
exec 程式包名.公用過程名(引數);

下邊兩個圖是我擷取《精通Oracle10g SQL和PL/SQL》的片段

相關推薦

PL/SQL儲存函式儲存過程

一.儲存過程和儲存函式 1.1什麼是儲存過程和儲存函式: 指儲存在資料庫中供所有的使用者程式呼叫的 子程式叫儲存過程、儲存函式。 儲存過程和儲存函式的相同點:完成特定功能的程式 儲存過程和儲存函式的區別:是否用return 語句返回值,儲存過程不能使用return 返

mybatis的SQL,儲存函式儲存過程

package cn.et.mybatis.lesson02.func; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import org

在java應用程式下呼叫儲存函式儲存過程

建立connection連結,釋放關閉連結 package demo.untils; import java.sql.Connection; import java.sql.DriverManage

SQL儲存過程呼叫標量值函式儲存過程呼叫儲存過程

一、存 儲過程呼叫標量值函式 先建一個標量值函式,如 CREATE FUNCTION [dbo].[F_Num] ( @a nvarchar(50) ) RETURNS nvarchar(50) AS BEGIN declare @m nvarchar(50) selec

使用PL/SQL developer ORACLE 建立儲存過程、DBMS_JOB定時任務

由於需要對資料庫的一個表進行定時更新,之前想在後臺寫定時任務,後來發現數據庫的dems_job比較方便,之前並沒有接觸過PL/SQL和Oracle的定時任務Job,為了實現這一需求,於是在網上找了各種資料。 建立定時任務job之前首先需要有我們要操作的資料庫表,然後我們應該

pl/sql建立並使用儲存過程

實現功能——從其他表中統計資料後,插入到另一張表by_train_count中: 參考連結:http://wzhiju.iteye.com/blog/1123157 create or replace procedure up_insert_by_train_count i

[Oracle]高效的PL/SQL程式設計(五)--呼叫儲存過程返回結果集

            Oracle.DataAccess.Client.OracleConnection oracleConnection1=new OracleConnection("data source=precolm2;user id=colmtest;password=colmtest");   

關於SQL函式儲存過程的區別

本質上沒區別。只是函式有如:只能返回一個變數的限制。而儲存過程可以返回多個。而函式是可以嵌入在sql中使用的,可以在select中呼叫,而儲存過程不行。執行的本質都一樣。      函式限制比較多,比如不能用臨時表,只能用表變數.還有一些函式都不可用等等.而儲存過程的限制相

JDBC-MYSQL-儲存函式儲存過程的呼叫

最近要學習資料庫,在用JDBC呼叫儲存過程和儲存函式是出現了小麻煩。在MYSQL中,用JDBC呼叫儲存過程和儲存函式還是有一些不同的。  一,用JDBC呼叫儲存過程一般過程如下: String sql = "call proc(?,?)"; CallableSt

PL/SQL單行函式和組函式詳解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

pl/sql使用心得學習總結

設定 常用設定及快捷鍵 https://blog.csdn.net/wildboy2001/article/details/6887792 輸入中文跳出建表框的問題 檢查發現時快捷鍵配置中建表的快捷鍵為空導致的,給建表設定一個快捷鍵就好了 怎麼將介面中文化 https

Oracle基礎(五)pl/sql進階(分頁過程)

   編寫分頁過程         通過pl/sql實現分頁過程,再該過程中由簡單到難一步步深入,目的在於通過該案例熟悉pl/sql的各種儲存過程,包,遊標,如何在java中呼叫等內容的學習。    1、無返回值的儲存過程      例如 1、可以向book表新增書,  

【Oracle】——pl/sql中文亂碼顯示“?”

前提      最近的專案都是Oracle,雖然小編對oracle資料庫一直是一竅不懂,但是要去學習啊!也是剛剛開始學習使用,問題就不斷啊。就說這個最有可能遇到的亂碼的問題,第一反應,編碼格式的問題

掌握PL/SQL小技巧提高工作效率

用分號隔開不同的SQL語句 在同一視窗輸入,可以在一次執行,PL/SQL將自動新建SQL視窗,分別執行不同的SQL語句(PL/SQL 7.1版本有次功能,低版本的可能會提示出錯) 用&符號引入變數 如select * from emp where ename='

PL/SQL查詢表內容中文亂碼解決辦法

1)在plsql中新建一個sql視窗,在這個視窗中執行: select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';   //注意:單引號裡邊的字串一定要是大寫的,否則查詢不到資料

ORACLE PL/SQL語法應用:遊標儲存過程觸發器函式

--遊標 --do while迴圈 declare    cursor c is select * from t_t_student order by id;   v_record c%rowtype

oracle中pl/sql程式設計---儲存過程函式觸發器

1.pl/sql程式設計 pl/sql 指procedure language 過程化/sql. pl/sql 是oracle在標準的sql語句基礎上擴充套件的一種對oracle資料庫進行程式設計的的語言。 可以定義變數和常量,而且可以使用條件語句和迴圈語句。 2.為什麼要有pl/sql程式設計? 平時是通過

SQL語句優化索引檢視觸發器儲存過程函式等。

    一,SQL優化        主要解決海量資料操作時的全表搜尋,所以減少不必要的全表搜尋是SQL優化的主要目的,下面總結一下常用的優化有哪些:        1,避免在where條件中使用!=或者<>,這樣會是的查詢放棄索引而進行全域性掃描       

開發PL/SQl的子程式和包 儲存過程函式

簡化指令碼 標準指令碼 工作環境 SQLPLUS Command Window SQLPLUS Test Window 語法要求 無 declare begain exception end 定義變數 var 名 資料型別 名 資料型別 使用變數 :名 名 賦值語句 ex

[PL/SQL] 請教大家一個問題儲存過程中需要幾個commit?

如果中間有語句發生錯誤就不一樣了,寫了一個測試的例子,看看對你有幫助沒有 drop table aatest; create table aatest (nid number,nname varchar2(16)) insert into aatest(nid,nname)values(1,'00