日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

总结:Oracle快速入门

發(fā)布時(shí)間:2024/4/17 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 总结:Oracle快速入门 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

一:數(shù)據(jù)庫(kù)分類

小:access/foxbase等

中:mysql/sql server/informix等

大:oracle/sybase/db2

二:sqlpus常用命令

oracle自帶用戶:sys(超級(jí)用戶,具有sysdba角色,可以創(chuàng)建數(shù)據(jù)庫(kù))、system(具有sysoper角色),區(qū)別在于是否能創(chuàng)建數(shù)據(jù)庫(kù)。

1:連接命令:【conn 用戶名/密碼@網(wǎng)絡(luò)服務(wù)名 [as sysdba/sysoper]】

2:顯示當(dāng)前用戶:【show user】

3:斷開連接:【disc/disconn/disconnect】

4:修改當(dāng)前用戶的密碼:【passw/password】,修改其他用戶密碼(權(quán)限):【alter user 用戶名 identity by 新密碼】

5:退出sqlplus:【exit】

6:清空屏幕:【clear screen】

7:運(yùn)行sql腳本:【start/@ url.sql】

8:編輯sql腳本:【edit url.sql】

9:將屏幕內(nèi)容輸入到指定文件:【spool url.sql】【spool off】

10:交互式命令&:【&value】需要用戶輸入值

11:顯示和設(shè)置環(huán)境變量:【show/set linesize/pagesize】

12:創(chuàng)建用戶(dba權(quán)限):create user 用戶名 identified by 密碼;

13:刪除用戶:【drop user 用戶名 [cascade]】

14:授予權(quán)限(系統(tǒng)和對(duì)象權(quán)限):【grant 權(quán)限 to 用戶 [with grant option]/[with admin opyion]】

15:收回權(quán)限:【revoke 權(quán)限 on 對(duì)象 from 用戶】(系統(tǒng)權(quán)限不級(jí)聯(lián),對(duì)象權(quán)限級(jí)聯(lián)收回)

16:賬號(hào)鎖定(創(chuàng)建profile口令限制的集合):【create profile lock_account limit failed_login_attempts 3 password_lock_time 2;】【alter user scott profile lock_account;】

17:賬戶解鎖:【alter user scott account unlock;】

18:終止口令(使用戶定期修改密碼):【create profile myprofile limit password_life_time 10 password_grace_time 2;】【alter user test profile myprofile;】

19:口令歷史:【create profile password_history limit password_life_time 10 password_grace_time 2 password_reuse_time 10】【alter user test profile password_history;】

20:刪除profile:【drop profile password_history [casade]】

三:常用SQL命令

1:數(shù)據(jù)類型:char/varchar2(n)/varchar/number(n,m)/date/timestamp/blob

2:創(chuàng)建表:create table demo( filed1 varchar2(20),...);

3:修改表:alter table demo add/modify ( filed1 varchar2(20))/drop column field1;

4:修改表名字:rename demo to test;

5:刪除表:drop table demo;

6:添加數(shù)據(jù):insert into table demo values(...);

7:修改數(shù)據(jù):update demo set ... where ...

8:刪除數(shù)據(jù):delete from demo where ...;

9:刪除表結(jié)構(gòu)和數(shù)據(jù):drop table demo;

10:刪除所有表記錄,無(wú)日志寫入無(wú)法找回刪除的記錄:truncate table demo;

11:查看表結(jié)構(gòu):desc demo;

12:查詢所有列:select * from demo;

13:底部顯示操作時(shí)間:set timing on/off;

14:表復(fù)制語(yǔ)句:insert into t2(filed1,...) select v1,v2,...from t1;

15:查詢統(tǒng)計(jì):select count(*) from demo;

16:查詢語(yǔ)句:select [distinct] field1 [as alias],... from ... where ...

17:nvl函數(shù):nvl(str1,replace_str2)

18:連接字符串:||

19:模糊查詢:like '%demo_';

20:范圍查詢:in (A,B,C);

21:判空查詢:is null/null

22:升降序排列:order by [asc/desc]

23:聚合函數(shù)(如果列里面有一個(gè)分組函數(shù),其它都必須是分組函數(shù)):max/min/avg/sum/count

24:分組統(tǒng)計(jì):group by ... having ...??? (order by ...)

25: 當(dāng)在from 子句中使用子查詢時(shí),必須給子查詢指定別名 , 給表取別名的時(shí)候,不能加as;但是給列取別名,是可以加as的。

26:根據(jù)查詢結(jié)果創(chuàng)建新表: CREATE TABLE mytable (id, name, sal, job, deptno) as SELECT empno, ename, sal, job, deptno FROM emp;

27:合并查詢:union(去掉重復(fù)行)/union all/intersect/minus

四:oracel分頁(yè)方式

1:rowid分頁(yè)

SELECT *
FROM EMP
WHERE ROWID IN
?????? (SELECT RID
????????? FROM (SELECT ROWNUM RN, RID
????????????????? FROM (SELECT ROWID RID, EMPNO FROM EMP ORDER BY EMPNO DESC)
???????????????? WHERE ROWNUM <= ( (currentPage-1) * pageSize + pageSize )) --每頁(yè)顯示幾條
???????? WHERE RN > ((currentPage-1) * pageSize) ) --當(dāng)前頁(yè)數(shù)
?ORDER BY EMPNO DESC;

2:rownum分頁(yè)

SELECT *
? FROM (SELECT T.*, ROWNUM RN
????????? FROM (SELECT * FROM EMP ORDER BY EMPNO DESC) T
???????? WHERE ROWNUM <= ( (currentPage-1) * pageSize + pageSize )) --每頁(yè)顯示幾條
? WHERE RN > ( (currentPage-1) * pageSize ); --當(dāng)前頁(yè)數(shù)

3:分析函數(shù)分頁(yè)

SELECT *
FROM (SELECT T.*, ROW_NUMBER() OVER(ORDER BY empno DESC) RK FROM emp T)
WHERE RK <= ( (currentPage-1) * pageSize + pageSize ) --每頁(yè)顯示幾條
AND RK > ( (currentPage-1) * pageSize ); --當(dāng)前頁(yè)數(shù)

解析步驟:

1:SELECT * FROM emp;
2:顯示rownum,由oracle分配的
SELECT e.*, ROWNUM rn FROM (SELECT * FROM emp) e; --rn相當(dāng)于Oracle分配的行的ID號(hào)
3:先查出1-10條記錄
正確的: SELECT e.*, ROWNUM rn FROM (SELECT * FROM emp) e WHERE ROWNUM<=10;
錯(cuò)誤的:SELECT e.*, ROWNUM rn FROM (SELECT * FROM emp) e WHERE rn<=10;
4:然后查出6-10條記錄
SELECT * FROM (SELECT e.*, ROWNUM rn FROM (SELECT * FROM emp) e WHERE ROWNUM<=10) WHERE rn>=6;

五:事務(wù)操作

1:設(shè)置保存點(diǎn):savepoint a;

2:回滾到保存點(diǎn):rollback to a;

3:回滾全部事務(wù)操作:rollback;

4:提交事務(wù):commit;

5:java中使用事務(wù):conn.setAutoCommit(false);關(guān)閉自動(dòng)提交事務(wù),然后事務(wù)機(jī)制操作

6:只讀事務(wù): set transaction read only;

六:常用函數(shù)

1:字符函數(shù): lower(char) /upper(char)/length(char)/substr(char, m, n)/replace(char1, search_string, replace_string) /instr(C1,C2,I,J)

2:數(shù)字函數(shù): cos,cosh,exp,ln, log,sin,sinh,sqrt,tan,tanh,acos,asin,atan,round 等

3:日期函數(shù): sysdate (返回系統(tǒng)時(shí)間 )、 add_months(time,moths)函數(shù) ( 得到某一時(shí)間之前或之后n個(gè)月的時(shí)間 )、 last_day(d)(返回指定日期所在月份的最后一天 )

4:轉(zhuǎn)換函數(shù): to_char(date,formatStr)函數(shù)(

yy:兩位數(shù)字的年份 2004-->04
yyyy:四位數(shù)字的年份 2004年
mm:兩位數(shù)字的月份 8 月-->08
dd:兩位數(shù)字的天 30 號(hào)-->30
hh24: 8點(diǎn)-->20
hh12:8點(diǎn)-->08
mi、ss-->顯示分鐘\秒
9:顯示數(shù)字,并忽略前面0
0:顯示數(shù)字,如位數(shù)不足,則用0補(bǔ)齊
.:在指定位置顯示小數(shù)點(diǎn)
,:在指定位置顯示逗號(hào)
$:在數(shù)字前加美元
L:在數(shù)字前面加本地貨幣符號(hào)
C:在數(shù)字前面加國(guó)際貨幣符號(hào)
G:在指定位置顯示組分隔符、
D:在指定位置顯示小數(shù)點(diǎn)符號(hào)(.)

)

to_date()函數(shù) ('dateStr',formatStr)

5:sys_context(‘USERENV’,param)系統(tǒng)函數(shù):(param=teminal/language/db_name/nls_date_format/session_user/currentt_schema/host)

6:管理員區(qū)別: sysdba>sysoper>dba

7:顯示初始化參數(shù):show parameter

8:修改參數(shù): oracle\admin\myoral\pfile\init.ora 文件中去修改。

七:備份與恢復(fù)

一:備份(導(dǎo)出):導(dǎo)出表、導(dǎo)出方案、導(dǎo)出數(shù)據(jù)庫(kù)

參數(shù):

userid:用于指定執(zhí)行導(dǎo)出操作的用戶名,口令,連接字符串
tables:用于指定執(zhí)行導(dǎo)出操作的表
owner:用于指定執(zhí)行導(dǎo)出操作的方案
full=y:用于指定執(zhí)行導(dǎo)出操作的數(shù)據(jù)庫(kù)
inctype:用于指定執(zhí)行導(dǎo)出操作的增量類型
rows:用于指定執(zhí)行導(dǎo)出操作是否要導(dǎo)出表中的數(shù)據(jù)
file:用于指定導(dǎo)出文件名

1:導(dǎo)出表:

exp userid=scott/oracle@orcl tables=(emp) file=d:\emp.dmp --導(dǎo)出單個(gè)表
exp userid=scott/oracle@orcl tables=(emp,dept) file=d:\emp.dmp --導(dǎo)出多個(gè)表

導(dǎo)出其他方案的表:

exp userid=system/oracle@orcl tables=(scott.emp) file=d:\emp.emp

exp userid=system/oracle@orcl tables=(scott.emp,scott.dept) file=d:\emp.emp

導(dǎo)出表結(jié)構(gòu):

exp userid=scott/oracle@orcl tables=(emp) file=d:\emp.dmp rows=n

直接導(dǎo)出方式 :

exp userid=scott/oracle@orcl tables=(emp) file=d:\emp.dmp direct=y

2:導(dǎo)出方案:

導(dǎo)出方案:

exp userid=scott/oracle@orcl owner=scott file=d:\scott.dmp

導(dǎo)出其它方案:

exp userid=system/oracle@orcl owner=(system,scott) file=d:\system.dmp

3:導(dǎo)出數(shù)據(jù)庫(kù)

exp userid=system/oracle@orcl full=y inctype=complete file=d:\all.dmp

二:恢復(fù)(導(dǎo)入)

參數(shù):

userid:用于指定執(zhí)行導(dǎo)入操作的用戶名,口令,連接字符串
tables:用于指定執(zhí)行導(dǎo)入操作的表
formuser:用于指定源用戶
touser:用于指定目標(biāo)用戶
file 用于指定導(dǎo)入文件名
full=y:用于指定執(zhí)行導(dǎo)入整個(gè)文件
inctype:用于指定執(zhí)行導(dǎo)入操作的增量類型
rows:指定是否要導(dǎo)入表行(數(shù)據(jù))
ignore:如果表存在,則只導(dǎo)入數(shù)據(jù)

1:導(dǎo)入表

導(dǎo)入表:
imp userid=scott/oracle@orcl tables=(emp) file=d:\xx.dmp
導(dǎo)入表到其它用戶:
imp userid=system/oracle@orcl tables=(emp) file=d:\xx.dmp touser=scott
導(dǎo)入表結(jié)構(gòu):
imp userid=scott/oracle@orcl tables=(emp) file=d:\xx.dmp rows=n
導(dǎo)入數(shù)據(jù):
imp userid=scott/oracle@orcl tables=(emp) file=d:\xx.dmp ignore=y?

2:導(dǎo)入方案
導(dǎo)入自身的方案:
imp userid=scott/oracle@orcl file=d:\xxx.dmp
導(dǎo)入其它方案:
imp userid=system/oracle@orcl file=d:\xxx.dmp fromuser=system touser=scott

3:導(dǎo)入數(shù)據(jù)庫(kù)(相當(dāng)于數(shù)據(jù)庫(kù)遷移)
imp userid=system/oracle@orcl full=y file=d:\xxx.dmp

八:視圖操作

1:數(shù)據(jù)字典視圖: user_xxx,all_xxx,dba_xxx

user_tables: 用于顯示當(dāng)前用戶所擁有的所有表,它只返回用戶所對(duì)應(yīng)方案的所有表 。

all_tables: 用于顯示當(dāng)前用戶可以訪問(wèn)的所有表,它不僅會(huì)返回當(dāng)前用戶方案的所有表,還會(huì)返回當(dāng)前用戶可以訪問(wèn)的其它方案的表 。

dba_tables: 它會(huì)顯示所有方案擁有的數(shù)據(jù)庫(kù)表。但是查詢這種數(shù)據(jù)庫(kù)字典視圖,要求用戶必須是dba角色或是有select any table 系統(tǒng)權(quán)限。

2:用戶名和權(quán)限和角色

dba_users可以顯示所有數(shù)據(jù)庫(kù)用戶的詳細(xì)信息;
dba_sys_privs可以顯示用戶所具有的系統(tǒng)權(quán)限;
dba_tab_privs可以顯示用戶具有的對(duì)象權(quán)限;
dba_col_privs 可以顯示用戶具有的列權(quán)限;
dba_role_privs 可以顯示用戶所具有的角色。

九:表空間和數(shù)據(jù)文件

表空間:數(shù)據(jù)庫(kù)的邏輯組成部分, 物理上講,數(shù)據(jù)庫(kù)數(shù)據(jù)存放在數(shù)據(jù)文件中。邏輯上講,數(shù)據(jù)庫(kù)數(shù)據(jù)則是存放在表空間中,表空間由一個(gè)或多個(gè)數(shù)據(jù)文件組成( 數(shù)據(jù)庫(kù)由表空間構(gòu)成,而表空間又是由段構(gòu)成,而段又是由區(qū)構(gòu)成,而區(qū)又是由oracle塊構(gòu)成 )。

1:建立表空間: create tablespace data01 datafile 'D:\dev\oracle\product\10.2.0\dada01.dbf' size 20m uniform size 128k;

2:使用表空間:

create table mypart(
?? deptno number(4),
?? dname varchar2(14),
?? loc varchar2(13)
) tablespace data01;

3:改變表空間狀態(tài):

表空間脫機(jī): alter tablespace 表空間名 offline;

表空間聯(lián)機(jī): alter tablespace 表空間名 online;

只讀表空間: alter tablespace 表空間名 read only;

4:刪除表空間: drop tablespace ‘表空間’ including contents and datafiles;

5:擴(kuò)展表空間:

增加數(shù)據(jù)文件 : alter tablespace sp01 add datafile 'D:\dev\oracle\product\10.2.0\dada02.dbf' size 1m;

修改數(shù)據(jù)文件的大小 : alter tablespace sp01 'D:\dev\oracle\product\10.2.0\dada01.dbf' resize 4m;

設(shè)置文件的自動(dòng)增長(zhǎng) : alter tablespace sp01 'D:\dev\oracle\product\10.2.0\dada01.dbf' autoextend on next 10m maxsize 500m;

6:移動(dòng)數(shù)據(jù)文件: 確定數(shù)據(jù)文件所在的表空間 》 使表空間脫機(jī) 》 使用命令移動(dòng)數(shù)據(jù)文件到指定的目標(biāo)位置 》 執(zhí)行alter tablespace 命令 》 使得表空間聯(lián)機(jī)

select tablespace_name from dba_data_files where file_name=upper('D:\dev\oracle\product\10.2.0\dada01.dbf');

alter tablespace sp01 offline;

host move D:\dev\oracle\product\10.2.0\dada01.dbf c:\dada01.dbf;

alter tablespace sp01 rename datafile 'D:\dev\oracle\product\10.2.0\dada01.dbf' to 'c:\sp01.dbf';

alter tablespace sp01 online;

7:顯示表空間信息: select tablespace_name from dba_tablespaces;

8: 除了最常用的數(shù)據(jù)表空間外,還有其它類型表空間:索引表空間、 undo表空間、 臨時(shí)表空間、 非標(biāo)準(zhǔn)塊的表空間。

十:約束

1:約束包括:not null、 unique, primary key, foreign key和check 五種。

1)、not null(非空)
如果在列上定義了not null,那么當(dāng)插入數(shù)據(jù)時(shí),必須為列提供數(shù)據(jù)。
2)、unique(唯一)
當(dāng)定義了唯一約束后,該列值是不能重復(fù)的,但是可以為null。
3)、primary key(主鍵)
用于唯一的標(biāo)示表行的數(shù)據(jù),當(dāng)定義主鍵約束后,該列不但不能重復(fù)而且不能為null。
需要說(shuō)明的是:一張表最多只能有一個(gè)主鍵,但是可以有多個(gè)unqiue約束。
4)、foreign key(外鍵)
用于定義主表和從表之間的關(guān)系。外鍵約束要定義在從表上,主表則必須具有主鍵約束或是unique 約束,當(dāng)定義外鍵約束后,要求外鍵列數(shù)據(jù)必須在主表的主鍵列存在或是為null。
5)、check
用于強(qiáng)制行數(shù)據(jù)必須滿足的條件,假定在sal列上定義了check約束,并要求sal列值在1000-2000之間如果不在1000-2000之間就會(huì)提示出錯(cuò)。

2:刪除約束

alter table 表名 drop constraint 約束名稱 ;

3:顯示約束信息

select constraint_name, constraint_type, status, validated from user_constraints where table_name = '表名';

select column_name, position from user_cons_columns where constraint_name = '約束名';

直接用pl/sql developer查看 .

十一:索引

1:創(chuàng)建索引

單列索引:單列索引是基于單個(gè)列所建立的索引
語(yǔ)法:create index 索引名 on 表名(列名);

復(fù)合索引:復(fù)合索引是基于兩列或是多列的索引。在同一張表上可以有多個(gè)索引,但是要求列的組合必須不同,比如:create index emp_idx1 on emp(ename, job); create index emp_idx1 on emp(job, ename); 這兩個(gè)索引是兩個(gè)不同的索引。

2:使用原則

1)、在大表上建立索引才有意義
2)、在where子句或是連接條件上經(jīng)常引用的列上建立索引
3)、索引的層次不要超過(guò)4層

3:索引缺點(diǎn)

1)、建立索引,系統(tǒng)要占用大約為表1.2倍的硬盤和內(nèi)存空間來(lái)保存索引。
2)、更新數(shù)據(jù)的時(shí)候,系統(tǒng)必須要有額外的時(shí)間來(lái)同時(shí)對(duì)索引進(jìn)行更新,以維持?jǐn)?shù)據(jù)和索引的一致性。

比如在如下字段建立索引應(yīng)該是不恰當(dāng)?shù)?#xff1a;
1. 很少或從不引用的字段;
2. 邏輯型的字段,如男或女(是或否)等。

4:索引分類

按照數(shù)據(jù)存儲(chǔ)方式,可以分為B*樹、反向索引、位圖索引;
按照索引列的個(gè)數(shù)分類,可以分為單列索引、復(fù)合索引;
按照索引列值的唯一性,可以分為唯一索引和非唯一索引。
此外還有函數(shù)索引,全局索引,分區(qū)索引...

5:顯示索引信息

1):在同一張表上可以有多個(gè)索引,通過(guò)查詢數(shù)據(jù)字典視圖dba_indexs和user_indexs,可以顯示索引信息。其中dba_indexs用于顯示數(shù)據(jù)庫(kù)所有的索引信息,而user_indexs用于顯示當(dāng)前用戶的索引信息:select index_name, index_type from user_indexes where table_name = '表名';
2):顯示索引列:通過(guò)查詢數(shù)據(jù)字典視圖user_ind_columns,可以顯示索引對(duì)應(yīng)的列的信息
select table_name, column_name from user_ind_columns where index_name ='IND_ENAME';
3):你也可以通過(guò)pl/sql developer工具查看索引信息 。

十二:權(quán)限

一:系統(tǒng)權(quán)限

常用:

create session 連接數(shù)據(jù)庫(kù)
create table 建表
create view 建視圖
create public synonym 建同義詞
create procedure 建過(guò)程、函數(shù)、包
create trigger 建觸發(fā)器
create cluster 建簇

1:顯示系統(tǒng)權(quán)限: select * from system_privilege_map order by name;

2:授予系統(tǒng)權(quán)限: grant create session, create table to ken with admin option;

3:回收系統(tǒng)權(quán)限(不級(jí)聯(lián)): revoke create session from ken;

二:對(duì)象權(quán)限

常用:

insert 添加
delete 刪除
alter 修改
select 查詢
index 索引
references 引用
execute 執(zhí)行

1:顯示對(duì)象權(quán)限: select distinct privilege from dba_tab_privs;

2:授予對(duì)象權(quán)限: grant select on emp to blake with grant option;

3:授予列權(quán)限: grant select on emp(ename,sal) to monkey ;

4:回收對(duì)象權(quán)限(級(jí)聯(lián)): revoke select on emp from blake ;

十三:角色

一:預(yù)定義角色: connect、resource、dba

1:connect角色
connect角色具有一般應(yīng)用開發(fā)人員需要的大部分權(quán)限。
create cluster
create database link
create session
alter session
create table
create view
create sequence

2:resource角色
resource角色具有應(yīng)用開發(fā)人員所需要的其它權(quán)限。
resource角色包含以下系統(tǒng)權(quán)限:
create cluster
create indextype
create table
create sequence
create type
create procedure
create trigger?

3:dba角色:具有所有的系統(tǒng)權(quán)限,及with admin option選項(xiàng),默認(rèn)的dba用戶為sys和system,它們可以將任何系統(tǒng)權(quán)限授予其他用戶。但是要注意的是dba角色不具備sysdba和sysoper的特權(quán)(啟動(dòng)和關(guān)閉數(shù)據(jù)庫(kù))。

二:自定義角色

1:建立角色: create role 角色名 not identified; create role 角色名 identified by 密碼;

2:角色授權(quán): grant insert, update, delete on scott.emp to 角色名;

3:分配角色給用戶: grant 角色名 to 用戶 with admin option;

4:刪除角色: drop role 角色名;

5:顯示角色信息:

1)、顯示所有角色: select * from dba_roles;
2)、顯示角色具有的系統(tǒng)權(quán)限:select privilege, admin_option from role_sys_privs where role='角色名';
3)、顯示角色具有的對(duì)象權(quán)限:通過(guò)查詢數(shù)據(jù)字典視圖dba_tab_privs可以查看角色具有的對(duì)象權(quán)限或是列的權(quán)限。
4)、顯示用戶具有的角色,及默認(rèn)角色:當(dāng)以用戶的身份連接到數(shù)據(jù)庫(kù)時(shí),oracle 會(huì)自動(dòng)的激活默認(rèn)的角色,通過(guò)查詢數(shù)據(jù)字典視圖dba_role_privs 可以顯示某個(gè)用戶具有的所有角色及當(dāng)前默認(rèn)的角色。
select granted_role, default_role from dba_role_privs where grantee = ‘用戶名’;

十四:PL/SQL

1:編碼規(guī)范

2: pl/sql塊: 三個(gè)部分構(gòu)成:定義部分,執(zhí)行部分,例外處理部分。

declare
/*定義部分——定義常量、變量、游標(biāo)、例外、復(fù)雜數(shù)據(jù)類型*/
begin
/*執(zhí)行部分——要執(zhí)行的pl/sql 語(yǔ)句和sql 語(yǔ)句*/
exception
/*例外處理部分——處理運(yùn)行的各種錯(cuò)誤*/
end;

eg:

set serveroutput on; DECLARE--定義字符串變量v_ename varchar2(10); v_sal NUMBER(7,2); BEGIN--執(zhí)行部分select ename, sal into v_ename, v_sal from emp where empno=&empno; dbms_output.put_line('雇員名:'||v_ename||',薪水:'||v_sal); EXCEPTION--異常處理 WHEN no_data_found THEN dbms_output.put_line('朋友,您的編號(hào)輸入有誤!'); end; /

3:存儲(chǔ)過(guò)程: 用于執(zhí)行特定的操作,當(dāng)建立存儲(chǔ)過(guò)程時(shí),既可以指定輸入?yún)?shù)(in),也可以指定輸出參數(shù)(out),通過(guò)在過(guò)程中使用輸入?yún)?shù),可以將數(shù)據(jù)傳遞到執(zhí)行部分;通過(guò)使用輸出參數(shù),可以將執(zhí)行部分的數(shù)據(jù)傳遞到應(yīng)用環(huán)境。在sqlplus中可以使用create procedure命令來(lái)建立過(guò)程。

編寫存儲(chǔ)過(guò)程:

CREATE PROCEDURE sp_update(uname VARCHAR2, newsal NUMBER) IS BEGINupdate emp set sal=newsal where ename=uname; END; /

調(diào)用存儲(chǔ)過(guò)程:

SQL> exec sp_update('zhangsan', 888); SQL> commit;

java中調(diào)用存儲(chǔ)過(guò)程:

package junit.test;import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager;/** * 演示java程序調(diào)用oracle的存儲(chǔ)過(guò)程案例* * @author jiqinlin**/ public class ProcedureTest {public static void main(String[] args) {try {// 1.加載驅(qū)動(dòng)Class.forName("oracle.jdbc.driver.OracleDriver");// 2.得到連接Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "oracle");// 3.創(chuàng)建CallableStatementCallableStatement cs = ct.prepareCall("{call sp_update(?,?)}");// 4.給?賦值cs.setString(1, "SMITH");cs.setInt(2, 4444);// 5.執(zhí)行cs.execute();// 關(guān)閉cs.close();ct.close();} catch (Exception e) {e.printStackTrace();}} }

4:函數(shù): 用于返回特定的數(shù)據(jù),當(dāng)建立函數(shù)時(shí),在函數(shù)頭部必須包含return子句。而在函數(shù)體內(nèi)必須包含return語(yǔ)句返回的數(shù)據(jù)。我們可以使用create function來(lái)建立函數(shù)。

編寫函數(shù):

CREATE FUNCTION annual_incomec(uname VARCHAR2) RETURN NUMBER IS annual_salazy NUMBER(7,2); BEGIN SELECT a.sal*13 INTO annual_salazy FROM emp a WHERE a.ename=uname;RETURN annual_salazy; END; /

調(diào)用函數(shù):

SQL> var income NUMBER; SQL> call annual_incomec('SCOTT') into:income; SQL> print income;

java中調(diào)用存儲(chǔ)過(guò)程:

package junit.test;import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet;/** * 演示java程序調(diào)用oracle的函數(shù)案例* * @author jiqinlin**/ public class ProcedureTest {public static void main(String[] args) {try {// 1.加載驅(qū)動(dòng)Class.forName("oracle.jdbc.driver.OracleDriver");// 2.得到連接Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "oracle");// 3.創(chuàng)建PreparedStatementPreparedStatement ps = ct.prepareStatement("select annual_incomec('SCOTT') annual from dual");// 4.執(zhí)行ResultSet rs=ps.executeQuery();if(rs.next()){Float annual=rs.getFloat("annual");System.out.println(annual);}//5、關(guān)閉rs.close();ps.close();ct.close();} catch (Exception e) {e.printStackTrace();}} }

5:包: 用于在邏輯上組合過(guò)程和函數(shù),它由包規(guī)范和包體兩部分組成, 使用create package命令來(lái)創(chuàng)建包 。

1:聲明包:

create package sp_package isprocedure update_sal(name varchar2, newsal number);function annual_income(name varchar2) return number; end;

2:創(chuàng)建包體:

CREATE OR REPLACE PACKAGE BODY SP_PACKAGE IS--存儲(chǔ)過(guò)程PROCEDURE UPDATE_SAL(NAME VARCHAR2, NEWSAL NUMBER) ISBEGINUPDATE EMP SET SAL = NEWSAL WHERE ENAME = NAME;COMMIT;END;--函數(shù)FUNCTION ANNUAL_INCOME(NAME VARCHAR2) RETURN NUMBER ISANNUAL_SALARY NUMBER;BEGINSELECT SAL * 12 + NVL(COMM, 0) INTO ANNUAL_SALARY FROM EMP WHERE ENAME = NAME;RETURN ANNUAL_SALARY;END; END; /

調(diào)用:

exec sp_package.update_sal('SCOTT', 8888); --調(diào)用函數(shù) var income NUMBER; CALL sp_package.ANNUAL_INCOME('SCOTT') INTO:income; print income;

6:變量:

1)、標(biāo)量類型(scalar)

pl/sql中定義變量和常量的語(yǔ)法如下:
identifier [constant] datatype [not null] [:=| default expr]
identifier: 名稱
constant:指定常量。需要指定它的初始值,且其值是不能改變的
datatype:數(shù)據(jù)類型
not null:指定變量值不能為null
:= 給變量或是常量指定初始值
default 用于指定初始值
expr :指定初始值的pl/sql表達(dá)式,可以是文本值、其它變量、函數(shù)等。

使用%type類型可以避免數(shù)字或值錯(cuò)誤( 超過(guò)了5個(gè)字符的話,就會(huì)有“ORA-06502: PL/SQL: 數(shù)字或值錯(cuò)誤 :? 字符串緩沖區(qū)太小”錯(cuò)誤 ) : 標(biāo)識(shí)符名 表名.列名%type;
2)、復(fù)合類型(composite):

pl/sql記錄類似結(jié)構(gòu)體:

set serveroutput on; --打開輸出選項(xiàng)
DECLARE
? --定義一個(gè)pl/sql記錄類型emp_record_type,
? --類型包含3個(gè)數(shù)據(jù)NAME, SALARY, TITLE。說(shuō)白了,就是一個(gè)類型可以存放3個(gè)數(shù)據(jù),主要是為了方便管理
? TYPE EMP_RECORD_TYPE IS RECORD(
??? NAME?? EMP.ENAME%TYPE,
??? SALARY EMP.SAL%TYPE,
??? TITLE? EMP.JOB%TYPE);
? --定義了一個(gè)sp_record變量,這個(gè)變量的類型是emp_record_type
? SP_RECORD EMP_RECORD_TYPE;
BEGIN
? SELECT ENAME, SAL, JOB INTO SP_RECORD FROM EMP WHERE EMPNO = 7788;
? DBMS_OUTPUT.PUT_LINE('員工名:' || SP_RECORD.NAME || '工資:' || SP_RECORD.SALARY);
END;
/

pl/sql表:類似數(shù)組

方法一(推薦):
set serveroutput on; --打開輸出選項(xiàng)
DECLARE
? --定義了一個(gè)pl/sql表類型sp_table_type,該類型是用于存放EMP.ENAME%TYPE
? --INDEX BY VARCHAR2(20)表示下標(biāo)是字符串
? TYPE SP_TABLE_TYPE IS TABLE OF EMP.ENAME%TYPE INDEX BY VARCHAR2(20);
? --定義了一個(gè)sp_table變量,這個(gè)變量的類型是sp_table_type
? SP_TABLE SP_TABLE_TYPE;
BEGIN
? SELECT ENAME, sal INTO SP_TABLE('ename'), SP_TABLE('sal') FROM EMP WHERE EMPNO = 7788;
? DBMS_OUTPUT.PUT_LINE('員工名:' || SP_TABLE('ename')||'工資:'||SP_TABLE('sal'));
END;
/

方法二:
set serveroutput on; --打開輸出選項(xiàng)
DECLARE
? --定義了一個(gè)pl/sql 表類型sp_table_type,該類型是用于存放EMP.ENAME%TYPE
? --index by binary_integer表示下標(biāo)是整數(shù)
? TYPE SP_TABLE_TYPE IS TABLE OF EMP.ENAME%TYPE INDEX BY BINARY_INTEGER; --注意binary_integer如果換為integer就會(huì)報(bào)錯(cuò),知道的朋友歡迎告訴我下
? --定義了一個(gè)sp_table變量,這個(gè)變量的類型是sp_table_type
? SP_TABLE SP_TABLE_TYPE;
BEGIN
? SELECT ENAME,sal INTO SP_TABLE(-1),SP_TABLE(-2) FROM EMP WHERE EMPNO = 7788;
? DBMS_OUTPUT.PUT_LINE('員工名:' || SP_TABLE(-1)||'工資:'||SP_TABLE(-2));
END;
/

3)、參照類型(reference)

參照變量——ref cursor游標(biāo)變量:

SET serveroutput ON;
DECLARE
? --定義游標(biāo)
? TYPE sp_emp_cursor IS REF CURSOR;
? --定義一個(gè)游標(biāo)變量
? sp sp_emp_cursor;
? --定義變量
? v_ename emp.ename%TYPE;
? v_sal emp.sal%TYPE;
BEGIN
? OPEN sp FOR SELECT e.ename, e.sal FROM emp e WHERE e.deptno=10;
? --方法一 loop循環(huán)
? /*
? LOOP
? FETCH sp INTO v_ename, v_sal;
? EXIT WHEN sp%NOTFOUND;
? DBMS_OUTPUT.PUT_LINE('名字:' || V_ENAME || ' 工資:' || V_SAL);
? END LOOP;*/
? --方法二 while循環(huán)
? /*
? WHILE 1=1 LOOP
??? FETCH sp INTO v_ename, v_sal;
??? EXIT WHEN sp%NOTFOUND;
??? DBMS_OUTPUT.PUT_LINE('名字:' || V_ENAME || ' 工資:' || V_SAL);
? END LOOP;*/
? --方法三 for循環(huán)
? FOR cur IN (SELECT e.ename, e.sal FROM emp e WHERE e.deptno=10) LOOP
??? DBMS_OUTPUT.PUT_LINE('名字:' || cur.ename || ' 工資:' || cur.sal);
? END LOOP;
END;
/
4)、lob(large object)

7:pl/sql控制結(jié)構(gòu)

條件分支語(yǔ)句: if—then,if–then–else,if–then–else if–then

1)、簡(jiǎn)單的條件判斷if–then
問(wèn)題:編寫一個(gè)過(guò)程,可以輸入一個(gè)雇員名,如果該雇員的工資低于2000,就給該員工工資增加10%。

SET serveroutput ON; CREATE OR REPLACE PROCEDURE SP_PRO6(SPNAME VARCHAR2) IS--定義V_SAL EMP.SAL%TYPE; BEGIN--執(zhí)行SELECT SAL INTO V_SAL FROM EMP WHERE ENAME = SPNAME;--判斷IF V_SAL < 2000 THENUPDATE EMP SET SAL = SAL + SAL * 0.1 WHERE ENAME = SPNAME;COMMIT;END IF; END; /--調(diào)用存儲(chǔ)過(guò)程 exec SP_PRO6('ALLEN');

2)、二重條件分支 if–then–else
問(wèn)題:編寫一個(gè)過(guò)程,可以輸入一個(gè)雇員名,如果該雇員的補(bǔ)助不是0就在原來(lái)的基礎(chǔ)上增加100;如果補(bǔ)助為0就把補(bǔ)助設(shè)為200;

CREATE OR REPLACE PROCEDURE SP_PRO6(SPNAME VARCHAR2) IS--定義V_COMM EMP.COMM%TYPE; BEGIN--執(zhí)行SELECT COMM INTO V_COMM FROM EMP WHERE ENAME = SPNAME;--判斷IF V_COMM <> 0 THENUPDATE EMP SET COMM = COMM + 100 WHERE ENAME = SPNAME;ELSEUPDATE EMP SET COMM = COMM + 200 WHERE ENAME = SPNAME;END IF;COMMIT; END; /--調(diào)用存儲(chǔ)過(guò)程 exec SP_PRO6('ALLEN');

3)、多重條件分支 if–then–ELSIF–then
問(wèn)題:編寫一個(gè)過(guò)程,可以輸入一個(gè)雇員編號(hào),如果該雇員的職位是PRESIDENT就給他的工資增加1000,如果該雇員的職位是MANAGER 就給他的工資增加500,其它職位的雇員工資增加200。

CREATE OR REPLACE PROCEDURE SP_PRO6(SPNO NUMBER) IS--定義V_JOB EMP.JOB%TYPE; BEGIN--執(zhí)行SELECT JOB INTO V_JOB FROM EMP WHERE EMPNO = SPNO;IF V_JOB = 'PRESIDENT' THENUPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = SPNO;ELSIF V_JOB = 'MANAGER' THENUPDATE EMP SET SAL = SAL + 500 WHERE EMPNO = SPNO;ELSEUPDATE EMP SET SAL = SAL + 200 WHERE EMPNO = SPNO;END IF;COMMIT; END; / --調(diào)用存儲(chǔ)過(guò)程 exec SP_PRO6(7499);

循環(huán)語(yǔ)句-loop:

CREATE OR REPLACE PROCEDURE SP_PRO6(SPNAME VARCHAR2) IS--定義 :=表示賦值V_NUM NUMBER := 1; BEGINLOOPINSERT INTO USERS VALUES (V_NUM, SPNAME);--判斷是否要退出循環(huán)EXIT WHEN V_NUM = 10;--自增V_NUM := V_NUM + 1;END LOOP;COMMIT; END; /--調(diào)用存儲(chǔ)過(guò)程 EXEC SP_PRO6('ALLEN');

循環(huán)語(yǔ)句-while循環(huán):

CREATE OR REPLACE PROCEDURE SP_PRO6(SPNAME VARCHAR2) IS--定義 :=表示賦值V_NUM NUMBER := 11; BEGINWHILE V_NUM <= 20 LOOP--執(zhí)行INSERT INTO USERS VALUES (V_NUM, SPNAME);V_NUM := V_NUM + 1;END LOOP;COMMIT; END; /--調(diào)用存儲(chǔ)過(guò)程 EXEC SP_PRO6('ALLEN');

--調(diào)用存儲(chǔ)過(guò)程
EXEC SP_PRO6('ALLEN');

循環(huán)語(yǔ)句-for循環(huán):

CREATE OR REPLACE PROCEDURE SP_PRO6 IS--注意如果無(wú)參記得不要加() BEGINFOR I IN REVERSE 1 .. 10 LOOP --REVERSE反轉(zhuǎn)函數(shù),表示I從10到1遞減,去掉REVERSE表示I從1到10遞增INSERT INTO USERS VALUES (I, 'shunping');END LOOP; END; /--調(diào)用存儲(chǔ)過(guò)程 EXEC SP_PRO6;

順序控制語(yǔ)句-goto、null:

set serveroutput on; DECLAREI INT := 1; BEGINLOOPDBMS_OUTPUT.PUT_LINE('輸出i=' || I);IF I = 1 THENGOTO END_LOOP;END IF;I := I + 1;END LOOP;<<END_LOOP>>DBMS_OUTPUT.PUT_LINE('循環(huán)結(jié)束'); END; / SET serveroutput ON; DECLAREV_SAL EMP.SAL%TYPE;V_ENAME EMP.ENAME%TYPE; BEGINSELECT ENAME, SAL INTO V_ENAME, V_SAL FROM EMP WHERE EMPNO = &NO;IF V_SAL < 3000 THENUPDATE EMP SET COMM = SAL * 0.1 WHERE ENAME = V_ENAME;dbms_output.put_line('1111');ELSENULL;dbms_output.put_line('2222');--不會(huì)被執(zhí)行END IF; END; /

8:pl/sql分頁(yè)

一、無(wú)返回值的存儲(chǔ)過(guò)程

古人云:欲速則不達(dá),為了讓大家伙比較容易接受分頁(yè)過(guò)程編寫,我還是從簡(jiǎn)單到復(fù)雜,循序漸進(jìn)的給大家講解。首先是掌握最簡(jiǎn)單的存儲(chǔ)過(guò)程,無(wú)返回值的存儲(chǔ)過(guò)程。 案例:現(xiàn)有一張表book,表結(jié)構(gòu)如下:書號(hào)、書名、出版社。

CREATE TABLE book(ID NUMBER(4),book_name VARCHAR2(30),publishing VARCHAR2(30) );

請(qǐng)寫一個(gè)過(guò)程,可以向book表添加書,要求通過(guò)java程序調(diào)用該過(guò)程。

--注意:in->表示這是一個(gè)輸入?yún)?shù),默認(rèn)為in --out->表示一個(gè)輸出參數(shù) CREATE OR REPLACE PROCEDURE ADD_BOOK(ID IN NUMBER,NAME IN VARCHAR2,PUBLISHING IN VARCHAR2) IS BEGININSERT INTO BOOK VALUES (ID, NAME, PUBLISHING);COMMIT; END; /??

java程序調(diào)用該存儲(chǔ)過(guò)程的代碼

package junit.test;import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager;/** * 調(diào)用一個(gè)無(wú)返回值的存儲(chǔ)過(guò)程* * @author jiqinlin**/ public class ProcedureTest {public static void main(String[] args) {try {// 1.加載驅(qū)動(dòng)Class.forName("oracle.jdbc.driver.OracleDriver");// 2.得到連接Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "oracle");// 3.創(chuàng)建CallableStatementCallableStatement cs = ct.prepareCall("call ADD_BOOK(?,?,?)");//給?賦值cs.setInt(1, 1);cs.setString(2, "java");cs.setString(3, "java出版社");// 4.執(zhí)行cs.execute();//5、關(guān)閉cs.close();ct.close();} catch (Exception e) {e.printStackTrace();}} }?????

二、有返回值的存儲(chǔ)過(guò)程(非列表)
案例:編寫一個(gè)存儲(chǔ)過(guò)程,可以輸入雇員的編號(hào),返回該雇員的姓名。

--輸入和輸出的存儲(chǔ)過(guò)程 CREATE OR REPLACE PROCEDURE SP_PROC(SPNO IN NUMBER, SPNAME OUT VARCHAR2) IS BEGINSELECT ENAME INTO SPNAME FROM EMP WHERE EMPNO = SPNO; END; /

java程序調(diào)用該存儲(chǔ)過(guò)程的代碼

package junit.test;import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager;/** * 調(diào)用一個(gè)無(wú)返回值的存儲(chǔ)過(guò)程* * @author jiqinlin**/ public class ProcedureTest {public static void main(String[] args) {try {// 1.加載驅(qū)動(dòng)Class.forName("oracle.jdbc.driver.OracleDriver");// 2.得到連接Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "oracle");// 3.創(chuàng)建CallableStatementCallableStatement cs = ct.prepareCall("{call sp_proc(?,?)}");//給第一個(gè)?賦值cs.setInt(1,7788);//給第二個(gè)?賦值cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);//4、執(zhí)行cs.execute();//取出返回值,要注意?的順序String name=cs.getString(2);System.out.println("編號(hào)7788的名字:"+name);//5、關(guān)閉cs.close();ct.close();} catch (Exception e) {e.printStackTrace();}} }??

案例擴(kuò)張:編寫一個(gè)過(guò)程,可以輸入雇員的編號(hào),返回該雇員的姓名、工資和崗位。

--輸入和輸出的存儲(chǔ)過(guò)程 CREATE OR REPLACE PROCEDURE SP_PROC(SPNO IN NUMBER,SPNAME OUT VARCHAR2,SPSAL OUT NUMBER,SPJOB OUT VARCHAR2) IS BEGINSELECT ENAME, SAL, JOB INTO SPNAME, SPSAL, SPJOB FROM EMP WHERE EMPNO = SPNO; END; /

java程序調(diào)用該存儲(chǔ)過(guò)程的代碼

package junit.test;import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager;/** * 調(diào)用一個(gè)無(wú)返回值的存儲(chǔ)過(guò)程* * @author jiqinlin**/ public class ProcedureTest {public static void main(String[] args) {try {// 1.加載驅(qū)動(dòng)Class.forName("oracle.jdbc.driver.OracleDriver");// 2.得到連接Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "oracle");// 3.創(chuàng)建CallableStatementCallableStatement cs = ct.prepareCall("{call sp_proc(?,?,?,?)}");//給第一個(gè)?賦值cs.setInt(1,7788);//給第二個(gè)?賦值cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);//給第三個(gè)?賦值cs.registerOutParameter(3,oracle.jdbc.OracleTypes.DOUBLE);//給第四個(gè)?賦值cs.registerOutParameter(4,oracle.jdbc.OracleTypes.VARCHAR);//4、執(zhí)行cs.execute();//取出返回值,要注意?的順序String name=cs.getString(2);double sal=cs.getDouble(3);String job=cs.getString(4);System.out.println("編號(hào)7788的名字:"+name+",職位:"+job+",薪水:"+sal+"");//5、關(guān)閉cs.close();ct.close();} catch (Exception e) {e.printStackTrace();}} }

三、有返回值的存儲(chǔ)過(guò)程(列表[結(jié)果集])
案例:編寫一個(gè)存儲(chǔ)過(guò)程,輸入部門號(hào),返回該部門所有雇員信息。
該題分析如下:由于oracle存儲(chǔ)過(guò)程沒(méi)有返回值,它的所有返回值都是通過(guò)out參數(shù)來(lái)替代的,列表同樣也不例外,但由于是集合,所以不能用一般的參數(shù),必須要用pagkage了。所以要分兩部分:
1)、建立一個(gè)包,在該包中我們定義類型test_cursor,它是個(gè)游標(biāo)。

CREATE OR REPLACE PACKAGE TESTPACKAGE ASTYPE TEST_CURSOR IS REF CURSOR; END TESTPACKAGE; /

2)、建立存儲(chǔ)過(guò)程。

CREATE OR REPLACE PROCEDURE SP_PROC(SPNO IN NUMBER,P_CURSOR OUT TESTPACKAGE.TEST_CURSOR) IS BEGINOPEN P_CURSOR FORSELECT * FROM EMP WHERE DEPTNO = SPNO; END SP_PROC; /??

3)、如何在java 程序中調(diào)用該過(guò)程

package junit.test;import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet;/** * 調(diào)用一個(gè)無(wú)返回值的存儲(chǔ)過(guò)程* * @author jiqinlin**/ public class ProcedureTest {public static void main(String[] args) {try {// 1.加載驅(qū)動(dòng)Class.forName("oracle.jdbc.driver.OracleDriver");// 2.得到連接Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "oracle");// 3.創(chuàng)建CallableStatementCallableStatement cs = ct.prepareCall("{call sp_proc(?,?)}");//給第一個(gè)?賦值cs.setInt(1,10);//給第二個(gè)?賦值cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);//4、執(zhí)行cs.execute();//得到結(jié)果集ResultSet rs = (ResultSet) cs.getObject(2);while (rs.next()) {System.out.println(rs.getInt(1) + " " + rs.getString(2));}//5、關(guān)閉rs.close();cs.close();ct.close();} catch (Exception e) {e.printStackTrace();}} }

四、編寫分頁(yè)過(guò)程
有了上面的基礎(chǔ),相信大家可以完成分頁(yè)存儲(chǔ)過(guò)程了。
要求,請(qǐng)大家編寫一個(gè)存儲(chǔ)過(guò)程,要求可以輸入表名、每頁(yè)顯示記錄數(shù)、當(dāng)前頁(yè)。返回總記錄數(shù),總頁(yè)數(shù),和返回的結(jié)果集。

--ROWNUM用法 SELECT o.*, ROWNUM RN FROM (SELECT * FROM EMP) o WHERE ROWNUM <= 10; ----oracle分頁(yè)sql語(yǔ)句;在分頁(yè)時(shí),大家可以把下面的sql語(yǔ)句當(dāng)做一個(gè)模板使用 SELECT * FROM (SELECT o.*, ROWNUM RN FROM (SELECT * FROM EMP) o WHERE ROWNUM <= 10) WHERE RN >= 6;

1)、開發(fā)一個(gè)包
建立一個(gè)包,在該包中定義類型為test_cursor的游標(biāo)。

--建立一個(gè)包 CREATE OR REPLACE PACKAGE TESTPACKAGE ASTYPE TEST_CURSOR IS REF CURSOR; END TESTPACKAGE; /--開始編寫分頁(yè)的過(guò)程 CREATE OR REPLACE PROCEDURE FENYE(TABLENAME IN VARCHAR2, PAGESIZE IN NUMBER, --每頁(yè)顯示記錄數(shù)PAGENOW IN NUMBER, --頁(yè)數(shù)MYROWS OUT NUMBER, --總記錄數(shù)MYPAGECOUNT OUT NUMBER, --總頁(yè)數(shù)P_CURSOR OUT TESTPACKAGE.TEST_CURSOR) IS --返回的記錄集--定義部分 --定義sql語(yǔ)句字符串 V_SQL VARCHAR2(1000); --定義兩個(gè)整數(shù) V_BEGIN NUMBER := (PAGENOW - 1) * PAGESIZE + 1; V_END NUMBER := PAGENOW * PAGESIZE; BEGIN --執(zhí)行部分 V_SQL := 'select * from (select t1.*, rownum rn from (select * from ' || TABLENAME || ') t1 where rownum<=' || V_END || ') where rn>=' || V_BEGIN; --把游標(biāo)和sql關(guān)聯(lián) OPEN P_CURSOR FOR V_SQL; --計(jì)算myrows和myPageCount --組織一個(gè)sql語(yǔ)句 V_SQL := 'select count(*) from ' || TABLENAME; --執(zhí)行sql,并把返回的值,賦給myrows; EXECUTE ImMEDIATE V_SQL INTO MYROWS; --它解析并馬上執(zhí)行動(dòng)態(tài)的SQL語(yǔ)句或非運(yùn)行時(shí)創(chuàng)建的PL/SQL塊.動(dòng)態(tài)創(chuàng)建和執(zhí)行SQL語(yǔ)句性能超前,--EXECUTE IMMEDIATE的目標(biāo)在于減小企業(yè)費(fèi)用并獲得較高的性能,較之以前它相當(dāng)容易編碼.--盡管DBMS_SQL仍然可用,但是推薦使用EXECUTE IMMEDIATE,因?yàn)樗@的收益在包之上。 --計(jì)算myPageCount --if myrows%Pagesize=0 then 這樣寫是錯(cuò)的 IF MOD(MYROWS, PAGESIZE) = 0 THEN MYPAGECOUNT := MYROWS/PAGESIZE; ELSE MYPAGECOUNT := MYROWS/PAGESIZE + 1; END IF; --關(guān)閉游標(biāo) --CLOSE P_CURSOR; --不要關(guān)閉,否則java調(diào)用該存儲(chǔ)過(guò)程會(huì)報(bào)錯(cuò) END; /?

java調(diào)用分頁(yè)代碼

package junit.test;import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet;/** * 調(diào)用一個(gè)無(wú)返回值的存儲(chǔ)過(guò)程* * @author jiqinlin* */ public class ProcedureTest {public static void main(String[] args) {try {// 1.加載驅(qū)動(dòng)Class.forName("oracle.jdbc.driver.OracleDriver");// 2.得到連接Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "oracle");// 3.創(chuàng)建CallableStatementCallableStatement cs = ct.prepareCall("{call fenye(?,?,?,?,?,?)}");cs.setString(1, "emp"); //表名cs.setInt(2, 5); //每頁(yè)顯示記錄數(shù)cs.setInt(3, 1);//頁(yè)數(shù)// 注冊(cè)總記錄數(shù)cs.registerOutParameter(4, oracle.jdbc.OracleTypes.INTEGER); //總記錄數(shù)// 注冊(cè)總頁(yè)數(shù)cs.registerOutParameter(5, oracle.jdbc.OracleTypes.INTEGER); //總頁(yè)數(shù)// 注冊(cè)返回的結(jié)果集cs.registerOutParameter(6, oracle.jdbc.OracleTypes.CURSOR); //返回的記錄集// 4、執(zhí)行cs.execute();// 得到結(jié)果集// 取出總記錄數(shù) /這里要注意,getInt(4)中4,是由該參數(shù)的位置決定的int rowNum = cs.getInt(4);int pageCount = cs.getInt(5);ResultSet rs = (ResultSet) cs.getObject(6);// 顯示一下,看看對(duì)不對(duì)System.out.println("rowNum=" + rowNum);System.out.println("總頁(yè)數(shù)=" + pageCount);while (rs.next()) {System.out.println("編號(hào):" + rs.getInt(1) + " 名字:" + rs.getString(2) + " 工資:" + rs.getFloat(6));}// 5、關(guān)閉//rs.close();cs.close();ct.close();} catch (Exception e) {e.printStackTrace();}} }

十五:oracle例外

1)、預(yù)定義例外用于處理常見的oracle錯(cuò)誤。
2)、非預(yù)定義例外用于處理預(yù)定義例外不能處理的例外。
3)、自定義例外用于處理與oracle錯(cuò)誤無(wú)關(guān)的其它情況。

1:處理預(yù)定義例外

case_not_found預(yù)定義例外 :

SET SERVEROUTPUT ON; CREATE OR REPLACE PROCEDURE SP_PRO6(SPNO NUMBER) ISV_SAL EMP.SAL%TYPE; BEGINSELECT SAL INTO V_SAL FROM EMP WHERE EMPNO = SPNO;CASEWHEN V_SAL < 1000 THENUPDATE EMP SET SAL = SAL + 100 WHERE EMPNO = SPNO;WHEN V_SAL < 2000 THENUPDATE EMP SET SAL = SAL + 200 WHERE EMPNO = SPNO;END CASE; EXCEPTIONWHEN CASE_NOT_FOUND THENDBMS_OUTPUT.PUT_LINE('case語(yǔ)句沒(méi)有與' || V_SAL || '相匹配的條件'); END; /--調(diào)用存儲(chǔ)過(guò)程 SQL> EXEC SP_PRO6(7369); case語(yǔ)句沒(méi)有與4444相匹配的條件

cursor_already_open預(yù)定義例外 :

DECLARECURSOR EMP_CURSOR ISSELECT ENAME, SAL FROM EMP; BEGINOPEN EMP_CURSOR; --聲明時(shí)游標(biāo)已打開,所以沒(méi)必要再次打開FOR EMP_RECORD1 IN EMP_CURSOR LOOPDBMS_OUTPUT.PUT_LINE(EMP_RECORD1.ENAME);END LOOP; EXCEPTIONWHEN CURSOR_ALREADY_OPEN THENDBMS_OUTPUT.PUT_LINE('游標(biāo)已經(jīng)打開'); END; /

dup_val_on_index預(yù)定義例外 :

BEGININSERT INTO DEPT VALUES (10, '公關(guān)部', '北京'); EXCEPTIONWHEN DUP_VAL_ON_INDEX THENDBMS_OUTPUT.PUT_LINE('在deptno列上不能出現(xiàn)重復(fù)值'); END; /

invalid_cursorn預(yù)定義例外 :

DECLARECURSOR EMP_CURSOR ISSELECT ENAME, SAL FROM EMP;EMP_RECORD EMP_CURSOR%ROWTYPE; BEGIN--open emp_cursor; --打開游標(biāo)FETCH EMP_CURSOR INTO EMP_RECORD;DBMS_OUTPUT.PUT_LINE(EMP_RECORD.ENAME);CLOSE EMP_CURSOR; EXCEPTIONWHEN INVALID_CURSOR THENDBMS_OUTPUT.PUT_LINE('請(qǐng)檢測(cè)游標(biāo)是否打開'); END; /

invalid_number預(yù)定義例外 :

SET SERVEROUTPUT ON; BEGINUPDATE EMP SET SAL = SAL + 'AAA'; EXCEPTIONWHEN INVALID_NUMBER THENDBMS_OUTPUT.PUT_LINE('輸入的數(shù)字不正確'); END; /

no_data_found預(yù)定義例外 :

SET serveroutput ON; DECLAREV_SAL EMP.SAL%TYPE; BEGINSELECT SAL INTO V_SAL FROM EMP WHERE ENAME = 'ljq'; EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('不存在該員工'); END; /

too_many_rows預(yù)定義例外 :

DECLAREV_ENAME EMP.ENAME%TYPE; BEGINSELECT ENAME INTO V_ENAME FROM EMP; EXCEPTIONWHEN TOO_MANY_ROWS THENDBMS_OUTPUT.PUT_LINE('返回了多行'); END; /

zero_divide預(yù)定義例外 : 當(dāng)執(zhí)行2/0語(yǔ)句時(shí),則會(huì)觸發(fā)該例外

value_error預(yù)定義例外 : 當(dāng)在執(zhí)行賦值操作時(shí),如果變量的長(zhǎng)度不足以容納實(shí)際數(shù)據(jù),則會(huì)觸發(fā)該例外value_error

login_denied : 當(dāng)用戶非法登錄時(shí),會(huì)觸發(fā)該例外

not_logged_on:如果用戶沒(méi)有登錄就執(zhí)行dml操作,就會(huì)觸發(fā)該例外
storage_error:如果超過(guò)了內(nèi)存空間或是內(nèi)存被損壞,就觸發(fā)該例外
timeout_on_resource:如果oracle在等待資源時(shí),出現(xiàn)了超時(shí)就觸發(fā)該例外

2:非預(yù)定義例外:非預(yù)定義例外用于處理與預(yù)定義例外無(wú)關(guān)的oracle錯(cuò)誤。使用預(yù)定義例外只能處理21個(gè)oracle 錯(cuò)誤,而當(dāng)使用pl/sql開發(fā)應(yīng)用程序時(shí),可能會(huì)遇到其它的一些oracle錯(cuò)誤。比如在pl/sql塊中執(zhí)行dml語(yǔ)句時(shí),違反了約束規(guī)定等等。

3:處理預(yù)定義例外: 預(yù)定義例外和自定義例外都是與oracle錯(cuò)誤相關(guān)的,并且出現(xiàn)的oracle 錯(cuò)誤會(huì)隱含的觸發(fā)相應(yīng)的例外;而自定義例外與oracle 錯(cuò)誤沒(méi)有任何關(guān)聯(lián),它是由開發(fā)人員為特定情況所定義的例外.

CREATE OR REPLACE PROCEDURE EX_TEST(SPNO NUMBER) IS BEGINUPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = SPNO; END; /--調(diào)用存儲(chǔ)過(guò)程, EXEC EX_TEST(56); CREATE OR REPLACE PROCEDURE EX_TEST(SPNO NUMBER) IS --定義一個(gè)例外 MYEX EXCEPTION; BEGIN --更新用戶sal UPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = SPNO; --sql%notfound 這是表示沒(méi)有update --raise myex;觸發(fā)myex IF SQL%NOTFOUND THEN RAISE MYEX; END IF; EXCEPTION WHEN MYEX THEN DBMS_OUTPUT.PUT_LINE('沒(méi)有更新任何用戶'); END; /

轉(zhuǎn)載于:https://my.oschina.net/zhuqingbo0501/blog/1815912

總結(jié)

以上是生活随笔為你收集整理的总结:Oracle快速入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。