总结:Oracle快速入门
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%。
2)、二重條件分支 if–then–else
問(wèn)題:編寫一個(gè)過(guò)程,可以輸入一個(gè)雇員名,如果該雇員的補(bǔ)助不是0就在原來(lái)的基礎(chǔ)上增加100;如果補(bǔ)助為0就把補(bǔ)助設(shè)為200;
3)、多重條件分支 if–then–ELSIF–then
問(wèn)題:編寫一個(gè)過(guò)程,可以輸入一個(gè)雇員編號(hào),如果該雇員的職位是PRESIDENT就給他的工資增加1000,如果該雇員的職位是MANAGER 就給他的工資增加500,其它職位的雇員工資增加200。
循環(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),返回該雇員的姓名。
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)。
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é)果集。
1)、開發(fā)一個(gè)包
建立一個(gè)包,在該包中定義類型為test_cursor的游標(biāo)。
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)題。
- 上一篇: Shell脚本编程----变量的使用
- 下一篇: (四)maven之查找jar包坐标,选择