函數(shù)--==================函數(shù)通常用于返回特定的數(shù)據(jù)。其實(shí)質(zhì)是一個(gè)有名字的PL/SQL塊,作為一個(gè)schema對(duì)象存儲(chǔ)于數(shù)據(jù)庫(kù),可以被反復(fù)執(zhí)行。函數(shù)通常被作為一個(gè)表達(dá)式來(lái)調(diào)用或存儲(chǔ)過(guò)程的一個(gè)參數(shù),具有返回值。一、建立函數(shù)的語(yǔ)法CREATE[ORREPLACE]FUNCTIONfunction_name(argument1[mode1]datatype1,argument2[mo" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

PL/SQL --> 函數(shù)

系統(tǒng) 1820 0

--==================

-- PL/SQL --> 函數(shù)

--==================

?

??? 函數(shù)通常用于返回特定的數(shù)據(jù)。其實(shí)質(zhì)是一個(gè)有名字的 PL / SQL 塊,作為一個(gè) schema 對(duì)象存儲(chǔ)于數(shù)據(jù)庫(kù),可以被反復(fù)執(zhí)行。函數(shù)通常被作為

一個(gè)表達(dá)式來(lái)調(diào)用或存儲(chǔ)過(guò)程的一個(gè)參數(shù),具有返回值。

?

一、建立函數(shù)的語(yǔ)法

??? CREATE [ OR REPLACE ] FUNCTION function_name

??????? ( argument1 [mode1] datatype1 ,

??????? ? argument2 [mode2] datetype2 ,

??????? ? ...)

??? RETURN datatype

??? IS | AS

??????? [local_variable_declarations;...]

??? BEGIN

??????? --actions;

??????? RETURN expression ;

??? END [function_name] ;

???

??? 建立函數(shù)的幾點(diǎn)注意事項(xiàng)

??????? 1. 指定參數(shù)數(shù)據(jù)類(lèi)型時(shí) (argument) ,不能指定其長(zhǎng)度

??????? 2. 函數(shù)頭部必須指定 return 子句,函數(shù)體內(nèi)至少要包含一條 return 語(yǔ)句

??????? 3. 可以指定 in 參數(shù),也可以指定 out 參數(shù),以及 in out 參數(shù)

??????? 4. 可以為參數(shù)指定缺省值。指定缺省值時(shí)使用 default 關(guān)鍵字。如 arg1 varchar2 default 'SCOTT'

?

二、使用函數(shù)的優(yōu)點(diǎn)

??? 1. 增加了代碼的靈活性,可以完成一些較為復(fù)雜的任務(wù),以及僅僅通過(guò) SQL 無(wú)法完成的任務(wù)

??? 2. 可以直接將函數(shù)使用到 where 子句中來(lái)過(guò)濾數(shù)據(jù)

??? 3. 可以作為存儲(chǔ)過(guò)程的參數(shù)使用,是存儲(chǔ)過(guò)程的一種補(bǔ)充

???

三、建立函數(shù)

??? 1. 建立不帶參數(shù)的函數(shù)

??????? scott@ORCL > create or replace function get_user

??????? ? 2 ? return varchar2

??????? ? 3 ? is

??????? ? 4 ??? v_user varchar2 ( 20 );

??????? ? 5 ? begin

??????? ? 6 ??? select username into v_user from user_users ;

??????? ? 7 ??? return v_user ;

??????? ? 8 ? end ;

??????? ? 9 ? /

?

??????? Function created .

?

??????? -- 使用全局變量接收函數(shù)的返回值

??????????? scott@ORCL > var v1 varchar2 ( 20 ) ?

??????????? scott@ORCL > exec : v1 := get_user

?

??????????? PL / SQL procedure successfully completed .

?

??????????? scott@ORCL > print v1 ;

?

??????????? V1

??????????? --------------------------------

??????????? SCOTT

???????

??????? -- 使用本地變量接收函數(shù)的返回值

??????????? scott@ORCL > set serveroutput on ;

??????????? scott@ORCL > declare user_name varchar2 ( 20 );

??????????? ? 2 ? begin

??????????? ? 3 ? user_name := get_user ();

??????????? ? 4 ? dbms_output . put_line ( 'Current user: ' || user_name );

??????????? ? 5 ? end ;

??????????? ? 6 ? /

??????????? Current user : SCOTT

?

??????????? PL / SQL procedure successfully completed . ???

???????????

??????? -- SQL 語(yǔ)句中直接調(diào)用函數(shù) ??

??????????? scott@ORCL > select get_user from dual ;

?

??????????? GET_USER

??????????? ---------------------

??????????? SCOTT ??

?

??????? -- 使用 dbms_output 調(diào)用函數(shù) ( 此調(diào)用作為存儲(chǔ)過(guò)程的一個(gè)參數(shù)來(lái)進(jìn)行調(diào)用 ) ??

??????????? scott@ORCL > set serveroutput on ;

??????????? scott@ORCL > exec dbms_output . put_line ( 'Current user: ' || get_user );

??????????? Current user : SCOTT ????

???????????

??? 2. 建立帶有 in 參數(shù)的函數(shù)

??????? scott@ORCL > create or replace function raise_sal ( name in varchar2 ) ??? -- 注意此處定義時(shí)參數(shù)并為指定類(lèi)型的長(zhǎng)度

??????? ? 2 ? return number

??????? ? 3 ? as

??????? ? 4 ??? v_sal emp . sal % type ;

??????? ? 5 ? begin

??????? ? 6 ??? select sal * 1.2 into v_sal from emp

??????? ? 7 ??? where upper ( ename )= upper ( name );

??????? ? 8 ??? return v_sal ;

??????? ? 9 ? exception

??????? ? 10 ??? when no_data_found then

??????? ? 11 ??? raise_application_error (- 20000 , 'Current Employee is not exists' );

??????? ? 12 ? end ;

??????? ? 13 ? /

?

??????? Function created . ??

?

??????? scott@ORCL > select sal , raise_sal ( 'SCOTT' ) from emp where ename = 'SCOTT' ;

?

??????????? ?? SAL RAISE_SAL ( 'SCOTT' )

??????? ---------- ------------------

??????????? ? 3100 ?????????????? 3720 ??

?

??????? scott@ORCL > select raise_sal ( 'Robinson' ) from dual ;

??????? select raise_sal ( 'Robinson' ) from dual

??????????? ?? *

??????? ERROR at line 1 :

??????? ORA - 20000 : Current Employee is not exists

??????? ORA - 06512 : at "SCOTT.GET_SAL" , line 11 ?????

?

??? 3. 建立帶有 out 參數(shù)的函數(shù)

??????? scott@ORCL > create or replace function get_info

??????? ? 2 ? ( name varchar2 , title out varchar2 )

??????? ? 3 ? return varchar2

??????? ? 4 ? as

??????? ? 5 ??? deptname dept . dname % type ;

??????? ? 6 ? begin

??????? ? 7 ??? select e . job , d . dname into title , deptname

??????? ? 8 ??? from emp e inner join dept d

??????? ? 9 ????? on e . deptno = d . deptno

??????? ? 10 ??? where upper ( e . ename )= upper ( name );

??????? ? 11 ??? return deptname ;

??????? ? 12 ? exception

??????? ? 13 ??? when no_data_found then

??????? ? 14 ????? raise_application_error (- 20000 , 'Current Employee is not exists' );

??????? ? 15 ? end ;

??????? ? 16 ? /

?

??????? Function created .

?

??????? 注意對(duì)于使用 out 參數(shù)的函數(shù),不能使用 SQL 語(yǔ)句來(lái)調(diào)用。而必須定義變量接收 out 參數(shù)和函數(shù)的返回值。

??????? 調(diào)用如下

??????? scott@ORCL > var job varchar2 ( 20 );

??????? scott@ORCL > var dname varchar2 ( 20 );

??????? scott@ORCL > exec : dname := get_info ( 'scott' ,: job );

?

??????? PL / SQL procedure successfully completed .

?

??????? scott@ORCL > print dname job ;

?

??????? DNAME

??????? --------------------------------

??????? RESEARCH

?

?

??????? JOB

??????? --------------------------------

??????? ANALYST

?

??? 3. 建立帶有 in out 參數(shù)的函數(shù)

??????? scott@ORCL > create or replace function comp

??????? ? 2 ? ( num1 number , num2 in out number )

??????? ? 3 ? return number

??????? ? 4 ? as

??????? ? 5 ??? v_result number ( 6 );

??????? ? 6 ??? v_remainder number ;

??????? ? 7 ? begin

??????? ? 8 ??? v_result := num1 * num2 ;

??????? ? 9 ??? v_remainder := mod ( num1 , num2 );

??????? ? 10 ??? num2 := v_remainder ;

??????? ? 11 ??? return v_result ;

??????? ? 12 ? exception

??????? ? 13 ??? when zero_divide then

??????? ? 14 ????? raise_application_error (- 20000 , 'Divison by zero' );

??????? ? 15 ? end ;

??????? ? 16 ? /

?

??????? Function created .

?

??????? scott@ORCL > var result1 number ;

??????? scott@ORCL > var result2 number ;

??????? scott@ORCL > exec :result2 := 10

?

??????? PL / SQL procedure successfully completed .

?

??????? scott@ORCL > exec :result1 := comp ( 16 , :result2 );

?

??????? PL / SQL procedure successfully completed .

?

??????? scott@ORCL > print result1 result2 ;

?

??????? ?? RESULT1

??????? ----------

??????????? ?? 160

?

?

??????? ?? RESULT2

??????? ----------

??????????????? ? 6

?

四、函數(shù)的調(diào)用及限制

??? 1. 函數(shù)的調(diào)用 ( 其具體調(diào)用方法參照上面的演示 )

??????? a . 使用全局變量接收函數(shù)的返回值

??????? b . 使用本地變量接受函數(shù)的返回值

??????? c . SQL 語(yǔ)句中直接調(diào)用函數(shù)

??????? d . 使用 dbms_output 調(diào)用函數(shù)

??????? 注:函數(shù)在調(diào)用的時(shí)候需要按位置指定參數(shù),沒(méi)有存儲(chǔ)過(guò)程參數(shù)傳遞靈活

??????????? 必須具有 execute 函數(shù)的權(quán)限

???

??? 2. 函數(shù)在 SQL 中調(diào)用的主要場(chǎng)合

??????? 由于函數(shù)必須要返回?cái)?shù)據(jù),因此只能作為表達(dá)式的一部分調(diào)用。此外函數(shù)可以在 SQL 語(yǔ)句的以下部分調(diào)用

??????? a. select 命令的選擇列表或子查詢(xún)中

??????? b. 條件表達(dá)式 where, having 子句中

??????? c. connect by , start with ,order by 以及 group by 子句中

??????? d. insert 命令的 values 子句中

??????? f. update 命令的 set 子句中

???????

??? 3. 函數(shù)在 SQL 中調(diào)用的限制

??????? a . SQL 語(yǔ)句中只能調(diào)用存儲(chǔ)在服務(wù)器端的函數(shù),而不能調(diào)用存儲(chǔ)于客戶(hù)端的函數(shù)

??????? b. SQL 語(yǔ)句中調(diào)用的函數(shù)只能帶有輸入?yún)?shù) IN ,而不能帶有輸出參數(shù) OUT 以及輸入輸出參數(shù) IN OUT

??????? c. SQL 語(yǔ)句中調(diào)用的函數(shù)只能使用 SQL 支持的標(biāo)準(zhǔn)數(shù)據(jù)類(lèi)型,不能使用 PL/SQL 特有的類(lèi)型,如 boolean,table,record

??????? d. SQL 語(yǔ)句中調(diào)用的函數(shù)不能包含 insert ,update delete 語(yǔ)句

???????

??????? 下面演示 SQL 調(diào)用時(shí)不能完整 DML 操作示例

?

??????? -- 創(chuàng)建一張表 tb_emp

??????????? scott@ORCL > create table tb_emp as select * from emp ;

?

??????? -- 創(chuàng)建一個(gè)函數(shù),用于刪除 tb_emp 表中指定的 empno 號(hào)的雇員信息,并返回其薪資

??????????? scott@ORCL > create or replace function delete_oper ( no number )

??????????? ? 2 ? return number

??????????? ? 3 ? as

??????????? ? 4 ??? v_sal emp . sal % type ;

??????????? ? 5 ??? begin

??????????? ? 6 ??? select sal into v_sal from tb_emp where empno = no ;

??????????? ? 7 ??? delete from tb_emp where empno = no ;

??????????? ? 8 ??? return v_sal ;

??????????? ? 9 ??? end ;

??????????? ? 10 ? /

?

??????????? Function created .

???????

??????? -- 使用 SQL 語(yǔ)句調(diào)用時(shí),收到了錯(cuò)誤信息,在內(nèi)部查詢(xún)內(nèi)不能完成 DML 操作

??????????? scott@ORCL > select delete_oper ( 7788 ) from dual ;

??????????? select delete_oper ( 7788 ) from dual

??????????????? ?? *

??????????? ERROR at line 1 :

??????????? ORA - 14551 : cannot perform a DML operation inside a query

??????????? ORA - 06512 : at "SCOTT.DELETE_OPER" , line 7 ??????

???????

??????? -- 使用 exec 執(zhí)行時(shí)函數(shù)被成功執(zhí)行

??????? ??? scott@ORCL > var v_no number ;

??????????? scott@ORCL > exec : v_no := delete_oper ( 7788 );

?

??????????? PL / SQL procedure successfully completed .

?

??????????? scott@ORCL > print v_no ;

?

??????????????? ? V_NO

??????????? ----------

??????????????? ? 3100

?

??????????? scott@ORCL > select * from tb_emp where empno = 7788 ;

?

??????????? no rows selected ???

???????????

??????? -- 下面的演示表明,不能使用 DML 語(yǔ)句來(lái)調(diào)用函數(shù)

??????????? scott@ORCL > update emp set sal = raise_sal ( 'SCOTT' ) where ename = 'SCOTT' ;

??????????? update emp set sal = raise_sal ( 'SCOTT' ) where ename = 'SCOTT'

??????????????????????????? ?? *

??????????? ERROR at line 1 :

??????????? ORA - 04091 : table SCOTT . EMP is mutating , trigger / function may not see it

??????????? ORA - 06512 : at "SCOTT.RAISE_SAL" , line 6 ????

???????????

五、函數(shù)的管理 ?

??? 函數(shù)使用了與存儲(chǔ)過(guò)程相關(guān)的視圖,可以從系統(tǒng)視圖中獲得函數(shù)的相關(guān)信息

??????? DBA_OBJECTS

??????? DBA_SOURCE

??????? USER_OBJECTS

??????? USER_SOURCE

?

??? -- 查看函數(shù)的源碼

??????? scott@ORCL > select text from user_source where name = 'DELETE_OPER' order by line ;

?

??????? TEXT

??????? ------------------------------------------------------------

??????? function delete_oper ( no number )

??????? ? return number

??????? ? as

??????? ? v_sal emp . sal % type ;

??????? ? begin

??????? ? select sal into v_sal from tb_emp where empno = no ;

??????? ? delete from tb_emp where empno = no ;

??????? ? commit ;

??????? ?? return v_sal ;

??????? ? end ;

?

??? -- 查看函數(shù)的參數(shù)信息

??????? scott@ORCL > desc delete_oper ;

??????? FUNCTION delete_oper RETURNS NUMBER

??????? ? Argument Name ????????????????? Type ??????????????????? In/ Out Default ?

??????? ? ------------------------------ ----------------------- ------ --------

??????? ? NO ???????????????????????????? NUMBER ????????????????? IN ?

?

???????

六、函數(shù)與存儲(chǔ)過(guò)程的差異

??? 存儲(chǔ)過(guò)程 ??? ????????????????????????? ? ???????????? 函數(shù)

??? ---------------------------------- ?????????????? ? -------------------------------

??? 不能被作為表達(dá)式調(diào)用 ??? ??????????????????????????? 只能作為表達(dá)式被調(diào)用

??? 聲明頭部關(guān)鍵字為 procedure ??????????????????????? 聲明頭部關(guān)鍵字為 function

??? 聲明頭部不包含 return 關(guān)鍵字來(lái)描述返回類(lèi)型 ???????? 頭部必須包含 return 關(guān)鍵字 , PL/SQL 塊中至少包含一個(gè)有效的 return 語(yǔ)句

??? 可以通過(guò) out,in out 返回零個(gè)或多個(gè)值 ?????????????? 通過(guò) return 語(yǔ)句返回一個(gè)與頭部聲明中類(lèi)型一致的值 , 也可使用 in,in out 返回值

??? SQL 語(yǔ)句中不可調(diào)用存儲(chǔ)過(guò)程 ?????????????????????? ? SQL 語(yǔ)句可以調(diào)用函數(shù)

??? 多用于數(shù)據(jù)庫(kù)中完成特定的操作 , 如刪除 , 更新 , 插入等 DML 操作 ???? 多用于特定的數(shù)據(jù)如選擇等

???

七、更多參考

? ??? ?

有關(guān) SQL 請(qǐng)參考

??????? SQL 基礎(chǔ)--> 子查詢(xún)

??????? SQL 基礎(chǔ)--> 多表查詢(xún)

SQL 基礎(chǔ)--> 分組與分組函數(shù)

SQL 基礎(chǔ)--> 常用函數(shù)

SQL 基礎(chǔ)--> ROLLUP 與CUBE 運(yùn)算符實(shí)現(xiàn)數(shù)據(jù)匯總

SQL 基礎(chǔ)--> 層次化查詢(xún)(START BY ... CONNECT BY PRIOR)

?

??? 有關(guān) PL/SQL 請(qǐng)參考

??????? PL/SQL --> 語(yǔ)言基礎(chǔ)

PL/SQL --> 流程控制

PL/SQL --> 存儲(chǔ)過(guò)程

PL/SQL --> 函數(shù)

PL/SQL --> 游標(biāo)

PL/SQL --> 隱式游標(biāo)(SQL%FOUND)

PL/SQL --> 異常處理(Exception)

PL/SQL --> PL/SQL 記錄

PL/SQL --> 包的創(chuàng)建與管理

PL/SQL --> 包重載、初始化

PL/SQL --> DBMS_DDL 包的使用

PL/SQL --> DML 觸發(fā)器

PL/SQL --> INSTEAD OF 觸發(fā)器

?

???

PL/SQL --> 函數(shù)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 毛片爱爱 | 国内视频一区 | 狠狠做深爱婷婷久久一区 | 玖玖视频精品 | 亚洲综合激情五月色播 | 欧美影院一区 | 久久国产热视频 | 久久午夜宅男免费网站 | 国产在线不卡视频 | 99久久久精品 | 日本一区二区三区精品 | 全部毛片免费看 | 最新国产中文字幕 | 国产欧美成人免费观看视频 | 亚洲国产成人久久综合野外 | 精品国精品国产自在久国产应用 | 色综合欧美亚洲另类久久 | 国产欧美精品一区二区三区-老狼 | 色噜噜狠狠一区二区三区 | 九九99香蕉在线视频美国毛片 | 欧美国产综合日韩一区二区 | 欧美日韩中文字幕在线视频 | 国产探花视频在线观看 | 豆国产97在线 | 亚洲 | 日本一片免费观看高清完整 | 成人影院欧美大片免费看 | 久久精品亚洲99一区二区 | 亚洲不卡一区二区三区在线 | 久久久久久九九 | 亚州精品一区二区三区 | 狠狠狠综合色 | 欧美一级毛片欧美一级无片 | 国产欧美精品午夜在线播放 | 国产www在线观看 | 免费看片aⅴ免费大片 | 波多野结衣中文字幕一区二区三区 | 久久夜色精品国产尤物 | 亚洲欧美日韩国产专区一区 | 国产成人综合日韩精品婷婷九月 | 亚洲国产婷婷综合在线精品 | 国产精品第九页 |