《Oracle经典教程》
轉(zhuǎn)自?https://blog.csdn.net/self_realian/article/details/72724307
走進(jìn)Oracle.?2
1.????Oracle簡(jiǎn)介...?3
2.????Oracle安裝...?4
3.????Oracle客戶端工具...?9
4.????Oracle服務(wù)...?16
5.????Oracle啟動(dòng)和關(guān)閉...?17
6.????Oracle用戶和權(quán)限...?18
7.????本章總結(jié)...?21
8.????本章練習(xí)...?22
SQL數(shù)據(jù)操作和查詢...?25
1.????SQL簡(jiǎn)介...?26
2.????Oracle數(shù)據(jù)類型...?26
3.????創(chuàng)建表和約束...?27
4.????數(shù)據(jù)操縱語(yǔ)言(DML)...?30
5.????操作符...?35
6.????高級(jí)查詢...?36
7.????本章總結(jié)...?44
8.????本章練習(xí)...?45
子查詢和常用函數(shù)...?48
1.????子查詢...?49
2.????Oracle中的偽列...?51
3.????Oracle函數(shù)...?54
4.????本章總結(jié)...?62
5.????本章練習(xí)...?63
表空間、數(shù)據(jù)庫(kù)對(duì)象...?66
1.????Oracle數(shù)據(jù)庫(kù)對(duì)象...?67
2.????同義詞...?67
3.????序列...?70
4.????視圖...?72
5.????索引...?74
6.????表空間...?75
7.????本章總結(jié)...?79
8.????本章練習(xí)...?80
PL/SQL程序設(shè)計(jì)...?83
1.????PL/SQL簡(jiǎn)介...?84
2.????PL/SQL塊...?85
3.????PL/SQL數(shù)據(jù)類型...?89
4.????PL/SQL條件控制和循環(huán)控制...?91
5.????PL/SQL中動(dòng)態(tài)執(zhí)行SQL語(yǔ)句...?101
6.????PL/SQL的異常處理...?102
7.????本章總結(jié)...?108
8.????本章練習(xí)...?109
Oracle應(yīng)用于.Net平臺(tái)...?111
1.????回顧ADO.NET.?112
2.????使用ADO.Net連接Oracle.?113
3.????抽象工廠中加入Oracle.?117
4.????本章總結(jié)...?121
5.????本章練習(xí)...?122
數(shù)據(jù)庫(kù)導(dǎo)入導(dǎo)出...?124
1.????Oracle導(dǎo)入導(dǎo)出...?125
2.????EXP導(dǎo)出數(shù)據(jù)...?125
3.????IMP導(dǎo)入...?128
4.????常見(jiàn)問(wèn)題...?128
?
?
?
?
?
?
?
?
?
第1章
?
?
走進(jìn)Oracle
?
?
?
?
?
???????????????????????????????????????????
?
?
| ? | 主要內(nèi)容 |
| ? | ü? Oracle安裝 ü? Oracle創(chuàng)建用戶和角色 ü? 客戶端鏈接Oracle服務(wù)器 ? |
?
?
?
?
1.???Oracle簡(jiǎn)介
在第一學(xué)期我們已經(jīng)接觸過(guò)關(guān)系型數(shù)據(jù)庫(kù)SQL Server,對(duì)數(shù)據(jù)庫(kù)、表、記錄、表的增刪改查操作等這些基本的概念已經(jīng)了解。Oracle是基于對(duì)象的關(guān)系型數(shù)據(jù)庫(kù),Oracle也是用表的形式對(duì)數(shù)據(jù)存儲(chǔ)和管理,并且在Oracle的操作中添加了一些面向?qū)ο蟮乃枷搿?/p>
?
Oracle數(shù)據(jù)庫(kù)是Oracle(中文名稱叫甲骨文)公司的核心產(chǎn)品,Oracle數(shù)據(jù)庫(kù)是一個(gè)適合于大中型企業(yè)的數(shù)據(jù)庫(kù)管理系統(tǒng)。在所有的數(shù)據(jù)庫(kù)管理系統(tǒng)中(比如:微軟的SQL Server,IBM的DB2等),Oracle的主要用戶涉及面非常廣,包括:銀行、電信、移動(dòng)通信、航空、保險(xiǎn)、金融、電子商務(wù)和跨國(guó)公司等。Oracle產(chǎn)品是免費(fèi)的,可以在Oracle官方網(wǎng)站上下載到安裝包,另一方面Oracle服務(wù)是收費(fèi)的。
?
Oracle公司成立以來(lái),從最初的數(shù)據(jù)庫(kù)版本到Oracle7、Oracle8i、Oracle9i,Oracle10g到Oracle11g,雖然每一個(gè)版本之間的操作都存在一定的差別,但是Oracle對(duì)數(shù)據(jù)的操作基本上都遵循SQL標(biāo)準(zhǔn)。因此對(duì)Oracle開(kāi)發(fā)來(lái)說(shuō)版本之間的差別不大。
?
很多人沒(méi)有學(xué)習(xí)Oracle就開(kāi)始發(fā)怵,因?yàn)槿藗冊(cè)谡`解Oracle,認(rèn)為Oracle太難學(xué)了,認(rèn)為Oracle不是一般人用的數(shù)據(jù)庫(kù),其實(shí)任何數(shù)據(jù)庫(kù)對(duì)應(yīng)用程序研發(fā)人員來(lái)說(shuō),都是大同小異,因?yàn)槟壳岸鄶?shù)數(shù)據(jù)庫(kù)都支持標(biāo)準(zhǔn)的SQL。在Oracle這本書中,我們能學(xué)習(xí)到:
???Oracle的安裝
???Oracle數(shù)據(jù)管理
???常用子查詢及常用函數(shù)
???PL/SQL編程
???Oracle基本管理
?
由于在第一學(xué)期已經(jīng)接觸了SQL Server,Oracle數(shù)據(jù)庫(kù)的概念不是很難,主要是實(shí)踐,因此在本書的學(xué)習(xí)中,認(rèn)真的完成上機(jī)練習(xí)是學(xué)習(xí)好本書的關(guān)鍵。
?
接下來(lái)我們先從Oracle安裝開(kāi)始,接觸一些Oracle中基本的概念。
?
2.???Oracle安裝
Oracle數(shù)據(jù)庫(kù)產(chǎn)品是免費(fèi)的,我們可以從Oracle的官方網(wǎng)站(http://www.oracle.com)下載到程序安裝包,Oracle在Windows下的安裝非常方便,安裝開(kāi)始后,一直點(diǎn)擊安裝程序的“下一步”即可。
?
1.???????下載Oracle10g后,解壓到一個(gè)文件夾下,單擊“setup.exe”文件即可啟動(dòng)安裝界面。如下圖:
?
?
圖1??Oracle安裝啟動(dòng)界面
?
Oracle主目錄位置就是Oracle準(zhǔn)備安裝的位置,稱為“Oracle_Home”,一般Oracle根據(jù)當(dāng)前計(jì)算機(jī)的硬盤大小默認(rèn)給出一個(gè)合適的位置。Oracle安裝時(shí)可以只安裝Oracle軟件,然后單獨(dú)創(chuàng)建數(shù)據(jù)庫(kù),也可以在上圖中選中“創(chuàng)建啟動(dòng)數(shù)據(jù)庫(kù)”復(fù)選框,在安裝Oracle產(chǎn)品時(shí),同時(shí)創(chuàng)建一個(gè)數(shù)據(jù)庫(kù),對(duì)初學(xué)者來(lái)說(shuō),推薦這樣安裝。填寫全局?jǐn)?shù)據(jù)庫(kù)名,以及管理員的密碼。全局?jǐn)?shù)據(jù)庫(kù)名是數(shù)據(jù)庫(kù)在服務(wù)器網(wǎng)絡(luò)中的唯一標(biāo)識(shí)。
?
2.???????點(diǎn)擊“下一步”,就會(huì)出現(xiàn)如下圖內(nèi)容,開(kāi)始對(duì)Oracle服務(wù)器進(jìn)行環(huán)境檢查,主要查看服務(wù)器是否符合Oracle安裝的條件,比如操作系統(tǒng)是否支持、系統(tǒng)內(nèi)存是否符合Oracle安裝的最低要求等。
?
?
圖2??Oracle安裝前環(huán)境檢查
?
3.???????Oracle檢查通過(guò)后,單擊“下一步”,就會(huì)列出所有安裝Oracle過(guò)程中的默認(rèn)選項(xiàng)。
?
?
圖3??Oracle默認(rèn)安裝設(shè)置
?
4.???????單擊“安裝”按鈕,進(jìn)入安裝界面,這一過(guò)程經(jīng)歷時(shí)間比較長(zhǎng),根據(jù)計(jì)算機(jī)的性能不同有很大差別。
?
?
圖4??Oracle安裝
?
5.???????上圖完成后,進(jìn)入了各種Oracle工具的安裝階段,包括網(wǎng)絡(luò)配置向?qū)?#xff0c;iSQL*plus等(后面課程中講解)。如下圖所示:
?
?
圖5??Oracle各種工具的安裝
?
6.???????接下來(lái)自動(dòng)啟動(dòng)DBCA(Database Configuration Assistant)進(jìn)入創(chuàng)建默認(rèn)數(shù)據(jù)庫(kù)階段。
?
?
圖6? DBCA下安裝數(shù)據(jù)庫(kù)
?
???????? Oracle中的數(shù)據(jù)庫(kù)主要是指存放數(shù)據(jù)的文件,這些文件在Oracle安裝完成后,在計(jì)算機(jī)硬盤上都能找到,包括數(shù)據(jù)文件、控制文件和數(shù)據(jù)庫(kù)日志文件。
?
數(shù)據(jù)庫(kù)創(chuàng)建后會(huì)有一系列為該數(shù)據(jù)庫(kù)提供服務(wù)的內(nèi)存空間和后臺(tái)進(jìn)程,稱為該數(shù)據(jù)庫(kù)的實(shí)例。每一個(gè)數(shù)據(jù)庫(kù)至少會(huì)有一個(gè)實(shí)例為其服務(wù)。實(shí)例中的內(nèi)存結(jié)構(gòu)稱為系統(tǒng)全局區(qū)(SGA),系統(tǒng)會(huì)根據(jù)當(dāng)前計(jì)算機(jī)系統(tǒng)的性能給SGA分配非常可觀的內(nèi)存空間。
?
Oracle創(chuàng)建數(shù)據(jù)庫(kù)不能像SQL Server那樣用一個(gè)簡(jiǎn)單的CREATE DATABASE命令就能完成,在創(chuàng)建數(shù)據(jù)庫(kù)的過(guò)程中還需要配置各種參數(shù)。雖然有DBCA工具向?qū)?#xff0c;但是仍然需要進(jìn)行比較麻煩的配置。
????????
| ? | 雖然一個(gè)Oracle數(shù)據(jù)庫(kù)服務(wù)器中可以安裝多個(gè)數(shù)據(jù)庫(kù),但是一個(gè)數(shù)據(jù)庫(kù)需要占用非常大的內(nèi)存空間,因此一般一個(gè)服務(wù)器只安裝一個(gè)數(shù)據(jù)庫(kù)。每一個(gè)數(shù)據(jù)庫(kù)可以有很多用戶,不同的用戶擁有自己的數(shù)據(jù)庫(kù)對(duì)象(比如:數(shù)據(jù)庫(kù)表),一個(gè)用戶如果訪問(wèn)其他用戶的數(shù)據(jù)庫(kù)對(duì)象,必須由對(duì)方用戶授予一定的權(quán)限。不同的用戶創(chuàng)建的表,只能被當(dāng)前用戶訪問(wèn)。因此在Oracle開(kāi)發(fā)中,不同的應(yīng)用程序只需使用不同的用戶訪問(wèn)即可。 |
?
7.???????數(shù)據(jù)庫(kù)創(chuàng)建完畢后,需要設(shè)置數(shù)據(jù)庫(kù)的默認(rèn)用戶。Oracle中為管理員預(yù)置了兩個(gè)用戶分別是SYS和SYSTEM。同時(shí)Oracle為程序測(cè)試提供了一個(gè)普通用戶scott,口令管理中,可以對(duì)數(shù)據(jù)庫(kù)用戶設(shè)置密碼,設(shè)置是否鎖定。?Oracle客戶端使用用戶名和密碼登錄Oracle系統(tǒng)后才能對(duì)數(shù)據(jù)庫(kù)操作。
?
?
圖7??DBCA下的口令管理
?
圖8? 為system,sys,scott用戶設(shè)置密碼
?
?????????默認(rèn)的用戶中,SYS和SYSTEM用戶是沒(méi)有鎖定的,安裝成功后可以直接使用,SCOTT用戶默認(rèn)為鎖定狀態(tài),因此不能直接使用,需要把SCOTT用戶設(shè)定為非鎖定狀態(tài)才能正常使用。
?
?????????這一步完成后,Oracle系統(tǒng)安裝成功。
?
| ? | Oracle數(shù)據(jù)庫(kù)中,默認(rèn)情況下,所有系統(tǒng)的數(shù)據(jù),SQL關(guān)鍵字等都是大寫的,在操作過(guò)程中,Oracle會(huì)自動(dòng)把這些內(nèi)容轉(zhuǎn)換為大寫,因此用戶操作時(shí)不需考慮大小寫問(wèn)題,一般情況下,為了良好的程序風(fēng)格,程序中建議關(guān)鍵字用大寫,非關(guān)鍵字可以使用小寫。 |
?
3.???Oracle客戶端工具
Oracle服務(wù)器安裝成功后,就可以通過(guò)客戶端工具連接Oracle服務(wù)器了,可以到Oracle官方下載Oracle專用的客戶端軟件,大多客戶端工具都是基于Oracle客戶端軟件的。接下來(lái)介紹幾種常用的Oracle客戶端工具。
?
2??SQL*Plus工具
?
該工具是Oracle系統(tǒng)默認(rèn)安裝下,自帶的一個(gè)客戶端工具。在Windows命令行中輸入“sqlplusw”命令,就能夠啟動(dòng)該工具了。
?
?
圖9? SQL*Plus工具
?
輸入用戶名和密碼后,如果SQL*Plus與數(shù)據(jù)庫(kù)服務(wù)器在同一臺(tái)計(jì)算機(jī)上,并且當(dāng)前服務(wù)器下只有一個(gè)數(shù)據(jù)庫(kù)實(shí)例,那么“主機(jī)字符串”可以不用填寫。
?
| ? | SQL*Plus工具雖然是Oracle自帶的工具,但是在現(xiàn)實(shí)開(kāi)發(fā)中,基于該環(huán)境對(duì)開(kāi)發(fā)不方便,因此很少使用。 |
?
SQL*Plus連接成功后就如圖所示:
?
?
圖10??SQL*Plus工具登錄后
?
2??SQL*Plus命令行工具
?
該命令行工具,提供了與數(shù)據(jù)庫(kù)交互的能力和維護(hù)數(shù)據(jù)庫(kù)的能力,包括了Oracle自帶的SQL*Plus工具的全部功能,在Oracle管理中經(jīng)常使用。在命令行中輸入:“sqlplus /nolog”即可啟動(dòng)該工具。如下圖:
?
?
圖11? 啟動(dòng)SQL*Plus命令行工具
?
?????????輸入“sqlplus /nolog”命令后,只是啟動(dòng)了一個(gè)客戶端進(jìn)程,并沒(méi)有與服務(wù)器連接,連接到Oracle服務(wù)器的命令是:
?
conn?用戶名/密碼?as?連接身份@服務(wù)器連接字符串
?
說(shuō)明:
1.???????連接身份:表示該用戶連接后擁有的權(quán)限。
???sysdba:即數(shù)據(jù)庫(kù)管理員,權(quán)限包括:打開(kāi)數(shù)據(jù)庫(kù)服務(wù)器、關(guān)閉數(shù)據(jù)庫(kù)服務(wù)器、備份數(shù)據(jù)庫(kù)、恢復(fù)數(shù)據(jù)庫(kù)、日志歸檔、會(huì)話限制、管理功能、創(chuàng)建數(shù)據(jù)庫(kù)。sys用戶必須用sysdba身份才能登錄,system用戶可以用普通身份登錄。
???sysyoper:即數(shù)據(jù)庫(kù)操作員,權(quán)限包括:打開(kāi)數(shù)據(jù)庫(kù)服務(wù)器、關(guān)閉數(shù)據(jù)庫(kù)服務(wù)器、備份數(shù)據(jù)庫(kù)、恢復(fù)數(shù)據(jù)庫(kù)、日志歸檔、會(huì)話限制。
???normal:即普通用戶,權(quán)限只有查詢某些數(shù)據(jù)表的數(shù)據(jù)。默認(rèn)的身份是normal用戶。
?
2.???????客戶端工具可以根據(jù)“服務(wù)器連接字符串”對(duì)服務(wù)器進(jìn)行連接,有了連接字符串后客戶端就可以像操作本機(jī)一樣操作遠(yuǎn)程數(shù)據(jù)庫(kù),因此“服務(wù)器連接字符串”的配置也叫本地網(wǎng)絡(luò)服務(wù)配置,如果SQL*Plus工具啟動(dòng)在服務(wù)器上,并且服務(wù)器上只有一個(gè)數(shù)據(jù)庫(kù)實(shí)例的情況下,連接字符串可以缺省,在連接字符串中包括連接服務(wù)器的協(xié)議,服務(wù)器的地址,服務(wù)器的端口等設(shè)置,Oracle服務(wù)名等,該配置文件在Oracle安裝目錄下的:?network/ADMIN/ tnsnames.ora。該文件是一個(gè)文本文件,用記事本打開(kāi)后如下所示:
?
?
圖12? 服務(wù)器連接字符串配置
?
2??配置本地網(wǎng)絡(luò)服務(wù)名
?
?????????本地網(wǎng)絡(luò)服務(wù)名,即客戶端與服務(wù)器的連接字符串,本地網(wǎng)絡(luò)服務(wù)名是客戶端的配置,Oracle客戶端安裝后,可以使用客戶端自帶的網(wǎng)絡(luò)配置向?qū)?#xff08;Net Configuration Assistant)進(jìn)行配置:
?
1.???????啟動(dòng)Net Configuration Assistant。選擇“本地Net服務(wù)名配置”選項(xiàng)。如下圖所示:
?
?
圖13? 啟動(dòng)Net Configuration Assistant
?
2.???????選擇“下一步”,本步驟可以對(duì)本地網(wǎng)絡(luò)服務(wù)名進(jìn)行添加,刪除,測(cè)試是否正常連接等操作,選擇“添加”選項(xiàng)。
?
?
圖14??Net Configuration Assistant
?
3.???????點(diǎn)擊“下一步”,填寫服務(wù)名,該服務(wù)名就是Oracle安裝時(shí)(圖1),為數(shù)據(jù)庫(kù)取的全局?jǐn)?shù)據(jù)庫(kù)名。
?
?
圖15? 服務(wù)名配置
?
4.???????點(diǎn)擊“下一步”,選擇服務(wù)需要的協(xié)議,默認(rèn)是TCP協(xié)議。推薦使用默認(rèn)的TCP協(xié)議。
?
?
圖16? 選擇協(xié)議
?
5.???????點(diǎn)擊“下一步”,輸入主機(jī)名,主機(jī)名可以是計(jì)算機(jī)名稱,也可以是一個(gè)IP地址,主機(jī)如果是本機(jī),可以使用本機(jī)計(jì)算機(jī)名稱、“l(fā)ocalhost”、“127.0.0.1”、或者本機(jī)的IP地址。
?
?
圖17? 輸入主機(jī)名和端口
?
6.???????單擊“下一步”,選擇“是,進(jìn)行測(cè)試”選項(xiàng)。進(jìn)入下圖界面。
?
?
圖18? 測(cè)試成功
?
在測(cè)試時(shí),默認(rèn)采用的用戶名和密碼是system/manager進(jìn)行測(cè)試,如果用戶system的密碼不是“manager”,有可能測(cè)試通不過(guò),更改登錄后,輸入正確的用戶名和密碼后再進(jìn)行測(cè)試即可。
7.???????測(cè)試成功后,單擊“下一步”,出現(xiàn)如下界面,這一步是為本地網(wǎng)絡(luò)服務(wù)命名,即圖12中的服務(wù)器連接字符串名。
?
?
圖19? 為網(wǎng)絡(luò)服務(wù)名命名
?
?????????點(diǎn)擊“下一步”,配置就完成了,進(jìn)入tnsnames.ora文件中查看,就出現(xiàn)了如圖12中的內(nèi)容。
?
2??PL/SQL Developer工具
?
在實(shí)際Oracle開(kāi)發(fā)中,經(jīng)常使用一個(gè)功能強(qiáng)大的第三方工具:“PL/SQL Developer”工具。PL/SQL Developer基本上可以實(shí)現(xiàn)Oracle開(kāi)發(fā)中的任何操作。它運(yùn)行在客戶端時(shí)必須先安裝Oracle客戶端,并且通過(guò)網(wǎng)絡(luò)配置向?qū)渲镁W(wǎng)絡(luò)服務(wù)名后才能正常與服務(wù)器連接。
?
?
圖20 PL/SQL Developer
?
4.???Oracle服務(wù)
Oracle在windows中安裝完成后,會(huì)安裝很多服務(wù),下面介紹幾個(gè)主要的服務(wù)。
?
?
圖21?Oracle服務(wù)
?
???OracleService+服務(wù)名,該服務(wù)是數(shù)據(jù)庫(kù)啟動(dòng)的基礎(chǔ),只有該服務(wù)啟動(dòng)了,Oracle數(shù)據(jù)庫(kù)才能正常啟動(dòng)。這是必須啟動(dòng)的服務(wù)。
???OracleOraDb10g_home1TNSListener,該服務(wù)是服務(wù)器端為客戶端提供的監(jiān)聽(tīng)服務(wù),只有該服務(wù)在服務(wù)器上正常啟動(dòng),客戶端才能連接到服務(wù)器。該監(jiān)聽(tīng)服務(wù)接收客戶端發(fā)出的請(qǐng)求,然后將請(qǐng)求傳遞給數(shù)據(jù)庫(kù)服務(wù)器。一旦建立了連接,客戶端和數(shù)據(jù)庫(kù)服務(wù)器就能直接通信了。
???OracleOraDb10g_home1iSQL*Plus,該服務(wù)提供了用瀏覽器對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)操作的方式。該服務(wù)啟動(dòng)后,就可以使用瀏覽器進(jìn)行遠(yuǎn)程登錄并進(jìn)行數(shù)據(jù)庫(kù)操作了。如下圖所示:
?
?
圖22 iSQL*Plus
?
???OracleDBConsole+服務(wù)名,Oracle10g中的一個(gè)新服務(wù)。在Oracle9i之前,Oracle官方提供了一個(gè)基于圖形界面的企業(yè)管理器(EM),從Oracle10g開(kāi)始,Oracle提供了一個(gè)基于B/S的企業(yè)管理器,在操作系統(tǒng)的命令行中輸入命令:emctl start dbconsole,就可以啟動(dòng)OracleDbConsole服務(wù),如下圖所示:
?
?
圖23?EM服務(wù)的啟動(dòng)
?
?????????服務(wù)啟動(dòng)之后,就可以在瀏覽器中輸入上圖中進(jìn)入EM的地址,使用B/S方式管理Oracle服務(wù)器。
?
5.???Oracle啟動(dòng)和關(guān)閉
OracleService啟動(dòng)動(dòng)后,就可以對(duì)數(shù)據(jù)庫(kù)進(jìn)行管理了,Oracle的啟動(dòng)和關(guān)閉是最基本的命令,在SQL*Plus中,啟動(dòng)Oracle必須是sys用戶,命令格式是:
?
startup open
?
?
圖24?Oracle服務(wù)啟動(dòng)
?
???????? Oracle服務(wù)關(guān)閉用命令:shutdown immediate
?
?
圖25?Oracle服務(wù)關(guān)閉
?
6.???Oracle用戶和權(quán)限
Oracle中,一般不會(huì)輕易在一個(gè)服務(wù)器上創(chuàng)建多個(gè)數(shù)據(jù)庫(kù),在一個(gè)數(shù)據(jù)庫(kù)中,不同的項(xiàng)目由不同的用戶訪問(wèn),每一個(gè)用戶擁有自身創(chuàng)建的數(shù)據(jù)庫(kù)對(duì)象,因此用戶的概念在Oracle中非常重要。Oracle的用戶可以用CREATE USER命令來(lái)創(chuàng)建。其語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):創(chuàng)建用戶
| CREATE USER 用戶名 IDENTIFIED BY 口令 [ACCOUNT LOCK|UNLOCK] |
語(yǔ)法解析:
???????? LOCK|UNLOCK創(chuàng)建用戶時(shí)是否鎖定,默認(rèn)為鎖定狀態(tài)。鎖定的用戶無(wú)法正常的登錄進(jìn)行數(shù)據(jù)庫(kù)操作。
?
代碼演示:創(chuàng)建用戶
| SQL> CREATE USER jerry 2? IDENTIFIED BY tom 3? ACCOUNT UNLOCK; |
????????
| ? | Oracle在SQL*Plus中的命令以分號(hào)(;)結(jié)尾,代表命令完畢并執(zhí)行,系統(tǒng)同時(shí)會(huì)把該命令保存在緩存中,緩存中只保存最近執(zhí)行過(guò)的命令,如果重新執(zhí)行緩存中的命令,直接使用左斜杠符號(hào)(/)。如果命令不以分號(hào)結(jié)尾,該命令只是寫入緩存保存起來(lái),但并不執(zhí)行。 |
?
?????????盡管用戶成功創(chuàng)建,但是還不能正常的登錄Oracle數(shù)據(jù)庫(kù)系統(tǒng),因?yàn)樵撚脩暨€沒(méi)有任何權(quán)限。如果用戶能夠正常登錄,至少需要CREATE SESSION系統(tǒng)權(quán)限。
?
???????? Oracle用戶對(duì)數(shù)據(jù)庫(kù)管理或?qū)ο蟛僮鞯臋?quán)利,分為系統(tǒng)權(quán)限和數(shù)據(jù)庫(kù)對(duì)象權(quán)限。系統(tǒng)權(quán)限比如:CREATE SESSION,CREATE TABLE等,擁有系統(tǒng)權(quán)限的用戶,允許擁有相應(yīng)的系統(tǒng)操作。數(shù)據(jù)庫(kù)對(duì)象權(quán)限,比如對(duì)表中的數(shù)據(jù)進(jìn)行增刪改操作等,擁有數(shù)據(jù)庫(kù)對(duì)象權(quán)限的用戶可以對(duì)所擁有的對(duì)象進(jìn)行對(duì)應(yīng)的操作。
?
?????????還有一個(gè)概念就是數(shù)據(jù)庫(kù)角色(role),數(shù)據(jù)庫(kù)角色就是若干個(gè)系統(tǒng)權(quán)限的集合。下面介紹幾個(gè)常用角色:
???CONNECT角色,主要應(yīng)用在臨時(shí)用戶,特別是那些不需要建表的用戶,通常只賦予他們CONNECT role。CONNECT是使用Oracle的簡(jiǎn)單權(quán)限,擁有CONNECT角色的用戶,可以與服務(wù)器建立連接會(huì)話(session,客戶端對(duì)服務(wù)器連接,稱為會(huì)話)。
???RESOURCE角色,更可靠和正式的數(shù)據(jù)庫(kù)用戶可以授予RESOURCE role。RESOURCE提供給用戶另外的權(quán)限以創(chuàng)建他們自己的表、序列、過(guò)程(procedure)、觸發(fā)器(trigger)、索引(index)等。
???DBA角色,DBA role擁有所有的系統(tǒng)權(quán)限----包括無(wú)限制的空間限額和給其他用戶授予各種權(quán)限的能力。用戶SYSTEM擁有DBA角色。
?
一般情況下,一個(gè)普通的用戶(如SCOTT),擁有CONNECT和RESOURCE兩個(gè)角色即可進(jìn)行常規(guī)的數(shù)據(jù)庫(kù)開(kāi)發(fā)工作。
?
?????????可以把某個(gè)權(quán)限授予某個(gè)角色,可以把權(quán)限、角色授予某個(gè)用戶。系統(tǒng)權(quán)限只能由DBA用戶授權(quán),對(duì)象權(quán)限由擁有該對(duì)象的用戶授權(quán),授權(quán)語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):授權(quán)
| GRANT角色|權(quán)限 TO 用戶(角色) |
?
代碼演示:授權(quán)
| SQL> GRANT CONNECT TO jerry; 授權(quán)成功。 SQL> GRANT RESOURCE TO jerry; 授權(quán)成功。 SQL> |
????????
語(yǔ)法結(jié)構(gòu):其他操作
| //回收權(quán)限 REVOKE 角色|權(quán)限 FROM 用戶(角色) //修改用戶的密碼 ALTER USER?用戶名?IDENTIFIED BY?新密碼 //修改用戶處于鎖定(非鎖定)狀態(tài) ALTER USER 用戶名 ACCOUNT LOCK|UNLOCK |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
7.???本章總結(jié)
???Oracle是基于對(duì)象的關(guān)系型數(shù)據(jù)庫(kù),Oracle產(chǎn)品免費(fèi),服務(wù)收費(fèi)。
???Oracle安裝后默認(rèn)會(huì)有兩個(gè)管理員用戶(system,sys)和一個(gè)普通用戶Scott。
???Sql*plus是Oracle管理和數(shù)據(jù)操作的客戶端工具。
???客戶端鏈接服務(wù)器前,服務(wù)器要啟動(dòng)監(jiān)聽(tīng)服務(wù),并且客戶端工具要安裝Oracle客戶端,并且在客戶端要建立本地網(wǎng)絡(luò)服務(wù)名。
???Oracle服務(wù)和監(jiān)聽(tīng)啟動(dòng)后才能對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。
???用startup命令啟動(dòng)數(shù)據(jù)庫(kù),用shutdown命令關(guān)閉數(shù)據(jù)庫(kù)。
???Oracle的角色包括了一系列系統(tǒng)權(quán)限和普通對(duì)象權(quán)限,可以把權(quán)限授權(quán)給角色,把權(quán)限或者角色授權(quán)給用戶。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
8.???本章練習(xí)
1.???????描述Oracle安裝過(guò)程中的關(guān)鍵點(diǎn)。
2.???????描述創(chuàng)建本地網(wǎng)絡(luò)服務(wù)名的步驟。
3.???????描述Oracle主要服務(wù)的作用。
4.???????Oracle使用什么命令才能啟動(dòng)和關(guān)閉。
5.???????什么是Oracle權(quán)限和角色?他們的關(guān)系是什么?
6.???????創(chuàng)建一個(gè)用戶,并授權(quán)CONNECT和RESOURCE。
?
章節(jié)知識(shí)結(jié)構(gòu)圖
?
?
?
?
?
?
第2章
?
?
SQL數(shù)據(jù)操作和查詢
?
?
?
???????????????????????????????????????????
?
?
| ? | 主要內(nèi)容 |
| ? | ü? Oracle數(shù)據(jù)類型 ü? SQL建表和約束 ü? SQL對(duì)數(shù)據(jù)增刪改 ü? SQL查詢 ü? Oracle偽列 ? |
?
?
1.???SQL簡(jiǎn)介
在第一學(xué)期的SQL Server學(xué)習(xí)中,已經(jīng)知道,SQL是結(jié)構(gòu)化查詢語(yǔ)言(Structured Query Language[D1]?),專門用于數(shù)據(jù)存取、數(shù)據(jù)更新及數(shù)據(jù)庫(kù)管理等操作。并且已經(jīng)學(xué)習(xí)了用SQL語(yǔ)句對(duì)數(shù)據(jù)庫(kù)的表進(jìn)行增刪改查的操作。
?
在Oracle開(kāi)發(fā)中,客戶端把SQL語(yǔ)句發(fā)送給服務(wù)器,服務(wù)器對(duì)SQL語(yǔ)句進(jìn)行編譯、執(zhí)行,把執(zhí)行的結(jié)果返回給客戶端。Oracle SQL語(yǔ)句由如下命令組成:
???數(shù)據(jù)定義語(yǔ)言Data?Definition?Language(DDL)[D2]?,包括CREATE(創(chuàng)建)命令、ALTER(修改)命令、DROP(刪除)命令等。
???數(shù)據(jù)操縱語(yǔ)言Data?Manipulation?Language(DML)[D3]?,包括INSERT(插入)命令、UPDATE(更新)命令、DELETE(刪除)命令、SELECT … FOR UPDATE(查詢)等。
???數(shù)據(jù)查詢語(yǔ)言Data Query Language(DQL),包括基本查詢語(yǔ)句、Order By子句、Group By子句等。
???事務(wù)控制語(yǔ)言(TCL),包括COMMIT(提交)命令、SAVEPOINT(保存點(diǎn))命令、ROLLBACK(回滾)命令。
???數(shù)據(jù)控制語(yǔ)言(DCL),GRANT(授權(quán))命令、REVOKE(撤銷)命令。
?
目前主流的數(shù)據(jù)庫(kù)產(chǎn)品(比如:SQL Server、Oracle)都支持標(biāo)準(zhǔn)的SQL語(yǔ)句。數(shù)據(jù)定義語(yǔ)言,表的增刪改操作,數(shù)據(jù)的簡(jiǎn)單查詢,事務(wù)的提交和回滾,權(quán)限的授權(quán)和撤銷等,Oracle與SQL Server在操作上基本一致。
?
2.???Oracle數(shù)據(jù)類型
Oracle數(shù)據(jù)庫(kù)的核心是表,表中的列使用到的常見(jiàn)數(shù)據(jù)類型如下:
?
| 類型 | 含義 |
| CHAR(length) | 存儲(chǔ)固定長(zhǎng)度的字符串。參數(shù)length指定了長(zhǎng)度,如果存儲(chǔ)的字符串長(zhǎng)度小于length,用空格填充。默認(rèn)長(zhǎng)度是1,最長(zhǎng)不超過(guò)2000字節(jié)。 |
| VARCHAR2(length) | 存儲(chǔ)可變長(zhǎng)度的字符串。length指定了該字符串的最大長(zhǎng)度。默認(rèn)長(zhǎng)度是1,最長(zhǎng)不超過(guò)4000字符。 |
| NUMBER(p,s) | 既可以存儲(chǔ)浮點(diǎn)數(shù),也可以存儲(chǔ)整數(shù),p表示數(shù)字的最大位數(shù)(如果是小數(shù)包括整數(shù)部分和小數(shù)部分和小數(shù)點(diǎn),p默認(rèn)是38為),s是指小數(shù)位數(shù)。 |
| DATE | 存儲(chǔ)日期和時(shí)間,存儲(chǔ)紀(jì)元、4位年、月、日、時(shí)、分、秒,存儲(chǔ)時(shí)間從公元前4712年1月1日到公元后4712年12月31日。 |
| TIMESTAMP | 不但存儲(chǔ)日期的年月日,時(shí)分秒,以及秒后6位,同時(shí)包含時(shí)區(qū)。 |
| CLOB | 存儲(chǔ)大的文本,比如存儲(chǔ)非結(jié)構(gòu)化的XML文檔 |
| BLOB | 存儲(chǔ)二進(jìn)制對(duì)象,如圖形、視頻、聲音等。 |
表1??Oracle的部分?jǐn)?shù)據(jù)類型
?
?????????對(duì)應(yīng)NUMBER類型的示例:
?
| 格式 | 輸入的數(shù)字 | 實(shí)際的存儲(chǔ) |
| NUMBER | 1234.567 | 1234.567 |
| NUMBER(6,2) | 123.4567 | 123.46 |
| NUMBER(4,2) | 12345.67 | 輸入的數(shù)字超過(guò)了所指定的精度,數(shù)據(jù)庫(kù)不能存儲(chǔ) |
表2??Number示例
?
?????????對(duì)于日期類型,可以使用sysdate內(nèi)置函數(shù)可以獲取當(dāng)前的系統(tǒng)日期和時(shí)間,返回DATE類型,用systimestamp函數(shù)可以返回當(dāng)前日期、時(shí)間和時(shí)區(qū)。
?
?
圖1??sysdate和sysTimestamp
?
???????? Oracle的查詢中,必須使用“select?列… from?表”的完整語(yǔ)法,當(dāng)查詢單行函數(shù)的時(shí)候,from后面使用DUAL表,dual表在系統(tǒng)中只有一行一列,該表在輸出單行函數(shù)時(shí)為了select…from的語(yǔ)法完整性而使用。
?
3.???創(chuàng)建表和約束
Oracle創(chuàng)建表同SQL Server一樣,使用CREATE TABLE命令來(lái)完成。創(chuàng)建約束則使用如下命令:
語(yǔ)法格式:ALTERTABLE命令
| ???ALTER TABLE?表名?ADDCONSTRAINT[D4]?約束名約束內(nèi)容。 |
?
不論創(chuàng)建表還是約束,與SQL Server基本相同,注意:在Oracle中default是一個(gè)值,而SQL Server中default是一個(gè)約束[D5]?,因此Oracle的default設(shè)置可以在建表的時(shí)候創(chuàng)建。
?
案例1:創(chuàng)建一個(gè)學(xué)生信息(INFOS)表和約束
?
代碼演示:Oracle創(chuàng)建表和約束
| CREATE TABLE INFOS ( ??STUID VARCHAR2(7) NOT NULL,????--學(xué)號(hào) 學(xué)號(hào)=‘S’+班號(hào)+2位序號(hào) ??STUNAME VARCHAR2(10) NOT NULL,? --姓名 ??GENDER VARCHAR2(2) NOT NULL,??? --性別? ??AGE NUMBER(2) NOT NULL,??????? --年齡 ??SEAT NUMBER(2) NOT NULL,??????? --座號(hào) ??ENROLLDATE DATE,????? --入學(xué)時(shí)間 ??STUADDRESS VARCHAR2(50)?DEFAULT?'地址不詳',??????--住址 ??CLASSNO VARCHAR2(4) NOT NULL??? --班號(hào)班號(hào)=學(xué)期序號(hào)+班級(jí)序號(hào)? ) /? ① ALTER TABLE INFOS ADD?CONSTRAINT PK_INFOS PRIMARY KEY(STUID)?②[D6]? / ALTER TABLE INFOS ADD CONSTRAINT CK_INFOS_GENDER? CHECK(GENDER = '男' OR GENDER = '女')??③[D7]? / ALTER TABLE INFOS ADD CONSTRAINT CK_INFOS_SEAT CHECK(SEAT >=0 AND SEAT <=50)??④ / ALTER TABLE INFOS ADD CONSTRAINT CK_INFOS_AGE? CHECK(AGE >=0 AND AGE<=100)??⑤ / ALTER TABLE INFOS ADD CONSTRAINT CK_INFOS_CLASSNO? CHECK((CLASSNO >='1001' AND CLASSNO<='1999') OR (CLASSNO >='2001' AND CLASSNO<='2999'))??⑥ / ALTER TABLE INFOS ADD CONSTRAINTS UN_STUNAME UNIQUE(STUNAME)??⑦[D8]? / |
代碼解析:
①??在Oracle代碼中,“/”執(zhí)行緩存區(qū)中的語(yǔ)句,由于緩沖區(qū)中只存儲(chǔ)一條剛剛保存過(guò)語(yǔ)句,由于每條語(yǔ)句沒(méi)有用分號(hào)結(jié)尾,只是保存在緩沖區(qū),因此每條語(yǔ)句后面都有單獨(dú)一行“/”。
②??創(chuàng)建一個(gè)主鍵約束[D9]?。
③??與 ④ ⑤ ⑥ ⑦一起創(chuàng)建各種check約束。其中⑦是唯一約束,表示該列值是唯一的,列中的值不能重復(fù)。
?
Oracle中創(chuàng)建外鍵約束與SQL Server相同。比如:現(xiàn)有成績(jī)表定義如下:
?
案例2:創(chuàng)建一個(gè)成績(jī)表(SCORES)表和約束
?
代碼演示:Oracle創(chuàng)建表和約束
| CREATE TABLE SCORES ( ????ID NUMBER ,??????? ????????????????????????--ID??① ????TERM VARCHAR2(2),????????????????????????????? ???? --學(xué)期 S1或S2 ??? ? STUID VARCHAR2(7) NOT NULL,?????????????????? --學(xué)號(hào) ??? ? EXAMNO VARCHAR2(7) NOT NULL,?????????????? --考號(hào) E+班號(hào)+序號(hào)????? ??? ? WRITTENSCORE NUMBER(4,1) NOT NULL,??? --筆試成績(jī) ??? ? LABSCORE NUMBER(4,1) NOT NULL???????????? --機(jī)試成績(jī) ) ALTER TABLE SCORES ??? ADD CONSTRAINT CK_SCORES_TERM CHECK(TERM = 'S1' OR TERM ='S2') / ALTER TABLE SCORES ??? ADD CONSTRAINT FK_SCORES_INFOS_STUID FOREIGN KEY(STUID) REFERENCES INFOS(STUID)??② / |
代碼解析:
①??SQL Server中可以使用identify創(chuàng)建自動(dòng)增長(zhǎng)列,但是Oracle中的自動(dòng)增長(zhǎng)需要借助序列(Sequence)完成,在后面章節(jié)中講解。
②??Oracle中的外鍵約束定義。
?
4.???數(shù)據(jù)操縱語(yǔ)言(DML)
數(shù)據(jù)操縱語(yǔ)言(DML)用于對(duì)數(shù)據(jù)庫(kù)的表中數(shù)據(jù)進(jìn)行添加、修改、刪除和SELECT…For UPDATE(后面專門學(xué)習(xí)該查詢)操作。對(duì)比一期學(xué)習(xí)過(guò)的SQL Server操作,接下來(lái)一一介紹在Oracle中的操作。
?
2??簡(jiǎn)單查詢
?
數(shù)據(jù)查詢是用SELECT命令從數(shù)據(jù)庫(kù)的表中提取信息。SELECT語(yǔ)句的語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):簡(jiǎn)單查詢
| SELECT *|列名|表達(dá)式?FROM?表名?WHERE?條件?ORDER BY?列名 |
語(yǔ)法解析:
1.???????*表示表中的所有列。
2.???????列名可以選擇若干個(gè)表中的列名,各個(gè)列表中間用逗號(hào)分隔。
3.???????表達(dá)式可以是列名、函數(shù)、常數(shù)等組成的表達(dá)式。
4.???????WHERE子句是查詢的條件。
5.???????ORDER BY?要求在查詢的結(jié)果中排序,默認(rèn)是升序[D10]?。
?
?
圖2? 數(shù)據(jù)查詢
????????
???????? Oracle中可以把查詢的結(jié)果根據(jù)結(jié)果集中的表結(jié)構(gòu)和數(shù)據(jù)形成一張新表。
?
語(yǔ)法結(jié)構(gòu):根據(jù)結(jié)果集創(chuàng)建表
| CREATE TABLE?表名?AS SELECT語(yǔ)句 |
?
代碼演示:根據(jù)結(jié)果集創(chuàng)建表
| SQL> CREATE TABLE INFOS1 AS SELECT * FROM INFOS; TABLE CREATED |
?
?????????使用上面命令創(chuàng)建的新表中,不存在任何約束,并且把查詢的數(shù)據(jù)一起插入到新表中。如果只復(fù)制表結(jié)構(gòu),只需使查詢的條件不成立(比如where 1=2),就不會(huì)查詢從出任何數(shù)據(jù),從而復(fù)制一個(gè)表結(jié)構(gòu)。
????????
代碼演示:復(fù)制表結(jié)構(gòu)
| SQL> CREATE TABLE INFOS2 AS SELECT * FROM INFOS WHERE 1=2; TABLE CREATED |
?
2??數(shù)據(jù)插入
?
用INSERT命令完成對(duì)數(shù)據(jù)的插入。
?
語(yǔ)法結(jié)構(gòu):根據(jù)結(jié)果集創(chuàng)建表
| INSERT INTO?表名(列名1,列名2……) VALUES (值1,值2……) |
語(yǔ)法解析:
1.???????列名可以省略。當(dāng)省略列名時(shí),默認(rèn)是表中的所有列名,列名順序?yàn)楸矶x中列的先后順序。
2.???????值的數(shù)量和順序要與列名的數(shù)量和順序一致。值的類型與列名的類型一致。
?
代碼演示:向INFOS表和SCORES表中插入數(shù)據(jù)
| SQL> INSERT INTO INFOS VALUES (? ① ? 2? 's100102', '林沖', '男', 22, 2, ? 3? TO_DATE('2009-8-9 06:30:10','YYYY-MM-DD HH24:MI:SS '),? ② ? 4? '西安', '1001' ??5? ) ??6? / 1 row inserted SQL> INSERT INTO INFOS VALUES ( 's100104','阮小二','男',26,3,SYSDATE,default,'1001');? ③ ?1 row inserted SQL>COMMIT;? ④ |
代碼解析:
①??表名后面缺省了列名,默認(rèn)是表Infos中的所有列名,values中的值要與表中列一一對(duì)應(yīng),包括順序和數(shù)據(jù)類型的對(duì)應(yīng)。在SQL*Plus中一條語(yǔ)句可以寫在多行,那么從第二行開(kāi)始,sqlplus會(huì)為每一行前面給出行號(hào)。
②??在Oracle中,日期是國(guó)際化的,不同的區(qū)域安裝的數(shù)據(jù)庫(kù),默認(rèn)的日期格式不同,因此為了程序便于移植,日期的輸入要使用TO_DATE函數(shù)對(duì)日期格式化后輸入,采用格式化字符串對(duì)日期進(jìn)行格式化時(shí),格式化字符串中字符不區(qū)分大小寫,常見(jiàn)的格式化字符如下:
1.?????????yyyy表示四位年份
2.?????????mm表示兩位月份,比如3月表示為03
3.?????????dd表示兩位日期
4.?????????hh24表示小時(shí)從0-23,hh12也表示小時(shí)從0-11。
5.?????????mi?表示分鐘
6.?????????ss表示秒
③??在遇到存在默認(rèn)值的列時(shí),可以使用default值代替。
④??commit是把用戶操作(添加、刪除、修改操作)提交,只有提交操作后,數(shù)據(jù)才能真正更新到表中,否則其他用戶無(wú)法查詢到當(dāng)前用戶操作的結(jié)果。
?
在Oracle中,一個(gè)INSERT命令可以把一個(gè)結(jié)果集一次性插入到一張表中。使用的語(yǔ)句是:INSERT INTO?表?SELECT子句,如下示例:
?
代碼演示:INSERT向表中插入一個(gè)結(jié)果集
| SQL> INSERT INTO INFOS2 SELECT * FROM INFOS; 5 rows inserted |
?
在這種語(yǔ)法下,要求結(jié)果集中每一列的數(shù)據(jù)類型必須與表中的每一列的數(shù)據(jù)類型一致,結(jié)果集中的列的數(shù)量與表中的列的數(shù)量一致。比如表INFOS2,該表的結(jié)構(gòu)與INFO表一樣,那么可以把INFO表中的所有記錄一次性插入到INFOS2表中。
?
Oracle的簡(jiǎn)單查詢和SQL Server一樣都可以在查詢列中使用常量,如圖:
?
?
圖3? Select中的常量
?
可以使用剛才的做法,把該結(jié)果集中的數(shù)據(jù)插入到表INFOS中。
?
代碼演示:INSERT向表中插入一個(gè)常量結(jié)果集
| SQL> INSERT INTO INFOS SELECT 's100106','盧俊義','男',23,5, ?????? ????????TO_DATE('2009-8-9 08:00:10','YYYY-MM-DD HH24:MI:SS'), ?????????????? '青龍寺','1001' FROM DUAL; 1 rows inserted SQL>COMMIT; |
?
2??更新數(shù)據(jù)
?
Oracle在表中更新數(shù)據(jù)的語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):UPDATE操作
| UPDATE?表名?SET?列名1=值,列名2=值…… WHERE?條件 |
?
代碼演示:UPDATE操作
| SQL> UPDATE INFOS SET CLASSNO='1002',STUADDRESS='山東萊蕪' WHERE STUNAME='阮小二'; 1 rows updated SQL> commit; |
?
2??刪除數(shù)據(jù)
?
Oracle在表中刪除數(shù)據(jù)的語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):DELETE操作
| DELETE FROM表名?WHERE?條件 |
?
代碼演示:DELETE操作
| SQL> DELETE FROM INFOS WHERE STUID='s100103'; 1 ROW DELETED SQL> COMMIT; |
?
2??TRUNCATE
?
在數(shù)據(jù)庫(kù)操作中,TRUNCATE[D11]?命令(是一個(gè)DDL命令)可以把表中的所有數(shù)據(jù)一次性全部刪除,語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):TRUNCATE
| TRUNCATE TABLE?表名 |
?
TRUNCATE和DELETE都能把表中的數(shù)據(jù)全部刪除,他們的區(qū)別是:
1.???????TRUNCATE是DDL命令,刪除的數(shù)據(jù)不能恢復(fù);DELETE命令是DML命令,刪除后的數(shù)據(jù)可以通過(guò)日志文件恢復(fù)。
2.???????如果一個(gè)表中數(shù)據(jù)記錄很多,TRUNCATE相對(duì)DELETE速度快。
?
由于TRUNCATE命令比較危險(xiǎn),因此在實(shí)際開(kāi)發(fā)中,TRUNCATE命令慎用。
?
| ? | Oracle默認(rèn)安裝中,已經(jīng)創(chuàng)建了一個(gè)SCOTT用戶,默認(rèn)密碼是:tiger,該用戶下有四張表分別是:雇員表(EMP),部門表(DEPT),工資登記表和獎(jiǎng)金表,請(qǐng)參考本章后面的附表。接下來(lái)很多操作都是在該用戶下完成的。 |
?
5.???操作符
Oracle開(kāi)發(fā)中,依然存在算術(shù)運(yùn)算,關(guān)系運(yùn)算,和邏輯運(yùn)算。
?
2??算術(shù)運(yùn)算
?
Oracle中的算術(shù)運(yùn)算符,沒(méi)有C#中的算術(shù)運(yùn)算符豐富,只有+、-、*、/四個(gè),其中除號(hào)(/)的結(jié)果是浮點(diǎn)數(shù)。求余運(yùn)算只能借助函數(shù):MOD(x,y):返回x除以y的余數(shù)。
?
案例3:每名員工年終獎(jiǎng)是2000元,請(qǐng)顯示基本工資在2000元以上的員工的月工資,年總工資。
該案例的表請(qǐng)參見(jiàn)本章練習(xí)的附表1、附表2、附表3,這三張表是ORACLE 10g自帶的。
?
代碼演示:查詢中的算術(shù)運(yùn)算
| SQL> SELECT ENAME,SAL,(SAL*12+2000) FROM EMP WHERE SAL>2000;
6 rows selected |
?
2??關(guān)系運(yùn)算和邏輯運(yùn)算
?
Oracle中Where子句經(jīng)中經(jīng)常見(jiàn)到關(guān)系運(yùn)算和邏輯運(yùn)算,常見(jiàn)的關(guān)系運(yùn)算有:
?
| 運(yùn)算符 | 說(shuō)明 | 運(yùn)算符 | 說(shuō)明 |
| = | 等于 | >? | 大于 |
| <>或者!= | 不等于 | <= | 小于或者等于 |
| <? | 小于 | >= | 大于或者等于 |
表3??Oracle的關(guān)系運(yùn)算符
?
邏輯運(yùn)算符有三個(gè):AND、OR、NOT
?
關(guān)系運(yùn)算和邏輯運(yùn)算與前面SQL Server學(xué)習(xí)過(guò)的一致。
?
2??字符串連接操作符(||)
?
在Oracle中,字符串的連接用雙豎線(||)表示。比如,在EMP表中,查詢工資在2000元以上的姓名以及工作。
?
代碼演示:字符串連接
| SQL> SELECT (ENAME || 'is a ' || JOB) AS "Employee Details"? ① ? 2? FROM EMP ? 3? WHERE SAL>2000; Employee Details ------------------------ JONESis a MANAGER BLAKEis a MANAGER CLARKis a MANAGER SCOTTis a ANALYST KINGis a PRESIDENT FORDis a ANALYST 6 rows selected |
代碼解析:
①??Oracle中字符串可以用單引號(hào),也可以用雙引號(hào),在別名中存在空格時(shí),必須用雙引號(hào)。在表名、列名時(shí)用雙引號(hào)。
?
6.???高級(jí)查詢
在第一期學(xué)習(xí)過(guò)SQL的簡(jiǎn)單查詢和連接查詢。現(xiàn)在學(xué)習(xí)一些新的SQL操作符。
?
2??消除重復(fù)行
?
在Oracle查詢中結(jié)果中,可能出現(xiàn)若干行相同的情況,那么可以使用DISTINCT消除重復(fù)行。具體的用法如示例:
?
代碼演示:DISTINCT消除重復(fù)行
| SQL> SELECT DISTINCT DEPTNO FROM EMP; DEPTNO ------ ??? 30 ??? 20 ??? 10 |
?
2??NULL操作
?
如果某條記錄中有缺少的數(shù)據(jù)值,就是空值(NULL值)。空值不等于0或者空格,空值是指未賦值、未知或不可用的值。任何數(shù)據(jù)類型的列都可以包括NULL值,除非該列被定義為非空或者主鍵。
????????
代碼演示:EMP中的NULL值
| SQL> SELECT ENAME,JOB,SAL,COMM FROM EMP WHERE SAL<2000;
7 rows selected |
?
?????????在查詢條件中NULL值用IS NULL作條件,非NULL值用NOT IS NULL做條件。???
?
案例4:查詢EMP表中沒(méi)有發(fā)獎(jiǎng)金的員工。
?
代碼演示:NULL值查詢
| SQL> SELECT ENAME,JOB,SAL,COMM FROM EMP 2?? WHERE SAL<2000 AND COMM IS NULL;
? |
?
2??IN 操作
?
在Where子句中可以使用IN操作符來(lái)查詢其列值在指定的列表中的行。比如:查詢出工作職責(zé)是SALESMAN、PRESIDENT或者ANALYST的員工。條件有兩種表示方法:
1.???????WHERE job = 'SALESMAN ' OR job = 'PRESIDENT ' OR job = 'ANALYST '
2.???????WHERE job IN ('SALESMAN', 'PRESIDENT', 'ANALYST')
?
代碼演示:IN操作
| SQL> SELECT ENAME,JOB,SAL FROM EMP 2? WHERE job IN ('SALESMAN', 'PRESIDENT', 'ANALYST');
7 rows selected |
?
?????????對(duì)應(yīng)IN操作的還有NOT IN,用法一樣,結(jié)果相反。
?
2??BETWEEN…AND…
?
在WHERE子句中,可以使用BETWEEN操作符來(lái)查詢列值包含在指定區(qū)間內(nèi)的行。比如,查詢工資從1000到2000之間的員工。可以使用傳統(tǒng)方法:
????????
???????? WHERE SAL>=1000 AND SAL<=2000
????????
?????????也可以使用:
???????? ??? WHERE SAL BETWEEN 1000 AND 2000
?????????BWTWEEN操作所指定的范圍也包括邊界。
?
代碼演示:BETWEEN操作
| SQL> SELECT ename,job,sal FROM EMP WHERE sal BETWEEN 1000 AND 2000;
6 rows selected |
?
2??LIKE模糊查詢
?
在一些查詢時(shí),可能把握不準(zhǔn)需要查詢的確切值,比如百度搜索時(shí)輸入關(guān)鍵字即可查詢出相關(guān)的結(jié)果,這種查詢稱為模糊查詢。模糊查詢使用LIKE關(guān)鍵字通過(guò)字符匹配檢索出所需要的數(shù)據(jù)行。字符匹配操作可以使用通配符“%”和“_”:
???%:表示零個(gè)或者多個(gè)任意字符。
???_:代表一個(gè)任意字符。
?
語(yǔ)法是:LIKE?'字符串'[ESCAPE?'字符']。匹配的字符串中,ESCAPE[D12]?后面的“字符”作為轉(zhuǎn)義字符。與一期SQLServer中ESCAPE用法相同。
?
| 通配符表達(dá)式 | 說(shuō)明 |
| 'S%' | 以S開(kāi)頭的字符串。 |
| '_S%' | 第二個(gè)字符時(shí)S的字符串。 |
| '%30\%%' escape '\' | 包含“30%”的字符串,“\”指轉(zhuǎn)義字符,“\%”在字符串中表示一個(gè)字符“%”。 |
表4? 通配符示例
?
案例5:顯示員工名稱以J開(kāi)頭以S結(jié)尾的員工的姓名、工資和工資。
?
代碼演示:LIKE操作
| SQL> SELECT ENAME,JOB,SAL FROM EMP WHERE ENAME LIKE 'J%S'; ? ENAME??????JOB???????????? SAL ----------???--------- ???????--------- JONES??????MANAGER???? 2975.00 JAMES??????CLERK??????? ?950.00 |
?
2??集合運(yùn)算
?
集合運(yùn)算就是將兩個(gè)或者多個(gè)結(jié)果集組合成為一個(gè)結(jié)果集。集合運(yùn)算包括:
???INTERSECT[D13]?(交集),返回兩個(gè)查詢共有的記錄。
???UNION ALL(并集),返回各個(gè)查詢的所有記錄,包括重復(fù)記錄。
???UNION(并集),返回各個(gè)查詢的所有記錄,不包括重復(fù)記錄。
???MINUS[D14]?(補(bǔ)集),返回第一個(gè)查詢檢索出的記錄減去第二個(gè)查詢檢索出的記錄之后剩余的記錄。
?
當(dāng)使用集合操作的時(shí)候,要注意:查詢所返回的列數(shù)以及列的類型必須匹配,列名可以不同。
????????
?????????案例6:查詢出dept表中哪個(gè)部門下沒(méi)有員工。只需求出dept表中的部門號(hào)和emp表中的部門號(hào)的補(bǔ)集即可。
?
代碼演示:求補(bǔ)運(yùn)算
| SQL> SELECT DEPTNO FROM DEPT ??2? MINUS ??3? SELECT DEPTNO FROM EMP; DEPTNO ------ ????40 |
?
?????????前面學(xué)習(xí)過(guò)可以通過(guò)insert into …select把一個(gè)結(jié)果集插入到另一張結(jié)構(gòu)相同的表中,因此可以使用union把若干條記錄一次性插入到一張表中。
?
代碼演示:用union插入多條數(shù)據(jù)
| SQL> INSERT INTO DEPT ??2? SELECT 50,'公關(guān)部','臺(tái)灣' FROM DUAL ??3? UNION ??4? SELECT 60,'研發(fā)部','西安' FROM DUAL ??5? UNION ??6? SELECT 70,'培訓(xùn)部','西安' FROM DUAL ??7? / 3 rows inserted |
?
2??連接查詢
?
在SQL Server中已經(jīng)學(xué)習(xí)過(guò)內(nèi)聯(lián)接(inner join)、外聯(lián)接(outer join),外聯(lián)接又分為左外聯(lián)接(left outer join)和右外聯(lián)接(right outer join)。Oracle中對(duì)兩個(gè)表或者若干表之間的外聯(lián)接用(+)表示。
?
案例7:請(qǐng)查詢出工資大于2000元的,員工姓名,部門,工作,工資。
?
由于部門名稱在dept中,其他的信息在emp表中,需要內(nèi)聯(lián)接才能完成。
?
代碼演示:內(nèi)聯(lián)接
| SQL> SELECT e.ENAME,e.JOB,e.SAL,d.DNAME ??2? FROM emp e,dept d ??3? WHERE e.deptno=d.deptno ??4? AND e.SAL>2000;
6 rows selected |
?
?????????也可以使用SQL/92標(biāo)準(zhǔn)中的內(nèi)聯(lián)接:
?
代碼演示:內(nèi)聯(lián)接
| SELECT e.ENAME,e.JOB,e.SAL,d.DNAME ?FROM EMP e?INNER JOIN?DEPT d?ON?e.DEPTNO=d.DEPTNO WHERE e.SAL>2000????????????? |
?
這里INNER JOIN中,關(guān)鍵字INNER可以省略。
????????
案例8:請(qǐng)查詢出每個(gè)部門下的員工姓名,工資。
案例分析:
Emp表用外鍵deptno引用Dept表中的deptno,在Dept表中如果有某些部門沒(méi)有員工,那么用內(nèi)聯(lián)接,沒(méi)有員工的部門將無(wú)法顯示,因此必須以Dept表為基準(zhǔn)的外聯(lián)接。
?
代碼演示:外聯(lián)接
| SQL> SELECT e.ENAME,e.JOB,e.SAL,d.DNAME ??2? FROM EMP e ,DEPT d ??3? WHERE? e.DEPTNO(+)=d.DEPTNO??① ??4? /
? ?18 rows selected |
代碼解析:
①???(+):Oracle專用的聯(lián)接符,在條件中出現(xiàn)在左邊指右外聯(lián)接,出現(xiàn)在右邊指左外聯(lián)接。
?
?????????也可以使用SQL/92標(biāo)準(zhǔn)的寫法:
?
代碼演示:外聯(lián)接
| SELECT e.ENAME,e.JOB,e.SAL,d.DNAME FROM EMP e?RIGHT OUTER JOIN?DEPT d?ON?e.DEPTNO=d.DEPTNO |
?
?????????這里RIGHT OUTER JOIN中,關(guān)鍵字OUTER可以省略。
?
| ? | 雖然Oracle自身的聯(lián)接查詢語(yǔ)法比較好寫,同時(shí)容易理解,但是為了程序便于移植,推薦使用SQL/92表中的聯(lián)接查詢。同時(shí)也可以與SQL Server獲得一致。 |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
7.???本章總結(jié)
???Oracle SQL語(yǔ)句中有數(shù)據(jù)操縱語(yǔ)言(DML)、數(shù)據(jù)定義語(yǔ)言(DDL)、數(shù)據(jù)控制語(yǔ)言(DCL)、事務(wù)控制語(yǔ)言(TCL)等等。
???DML語(yǔ)句包括增刪改查語(yǔ)句,DDL語(yǔ)句包括數(shù)據(jù)庫(kù)對(duì)象創(chuàng)建、修改和刪除語(yǔ)句,數(shù)據(jù)控制命令包括GRANT、REVOKE等,事務(wù)控制命令有COMMIT、ROLLBACK等。
???數(shù)據(jù)庫(kù)中建表常用的類型有:數(shù)字類型number(p,s),可變字符串varchar2(length),日期date。
???Oracle中default是一個(gè)值,在Oracle中不存在default約束。
???Oracle的增刪改語(yǔ)句與SQL Server基本一致,都是使用INSERT、UPDATE、DELETE完成。
???Oracle高級(jí)查詢中要注意:DISTINCT、NULL、IN、BETWEEN…AND…。
???集合操作有:UNION、UNION ALL、INTESECT、MINUS。
???聯(lián)接查詢有內(nèi)聯(lián)接和外聯(lián)接。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
8.???本章練習(xí)
1.???????創(chuàng)建一查詢,顯示與Blake在同一部門工作的雇員的項(xiàng)目和受雇日期,但是Blake不包含在內(nèi)。
2.???????顯示位置在Dallas的部門內(nèi)的雇員姓名、變化以及工作。
3.???????顯示被King直接管理的雇員的姓名以及工資。
4.???????創(chuàng)建一查詢,顯示能獲得與Scott一樣工資和獎(jiǎng)金的其他雇員的姓名、受雇日期以及工資。
?
附表1:Scott表中的EMP表:員工表
| 序號(hào) | 列名 | 類型 | 說(shuō)明 |
| 1 | EMPNO | NUMBER(4) | 員工編號(hào),EMP表主鍵 |
| 2 | ENAME | VARCHAR2(10) | 員工姓名 |
| 3 | JOB | VARCHAR2(9) | 員工工作 |
| 4 | MGR | NUMBER(4) | 員工的領(lǐng)導(dǎo)編號(hào),引用EMPNO |
| 5 | HIREDATE | DATE | 入職日期 |
| 6 | SAL | NUMBER(7,2) | 員工工資 |
| 7 | COMM | NUMBER(7,2) | 員工獎(jiǎng)金 |
| 8 | DEPTNO | NUMBER(2) | 員工部門編號(hào),是表DEPT的外鍵。 |
?
附表2:Scott表中的DEPT表:部門表
| 序號(hào) | 列名 | 類型 | 說(shuō)明 |
| 1 | DEPTNO | NUMBER(2) | 部門編號(hào),主鍵 |
| 2 | DNAME | VARCHAR2(14) | 部門名稱 |
| 3 | LOC | VARCHAR2(13) | 部門位置 |
?
附表3:Scott表中的SALGRADE表:工資等級(jí)表
| 序號(hào) | 列名 | 類型 | 說(shuō)明 |
| 1 | GRADE | NUMBER | 等級(jí) |
| 2 | LOSAL | NUMBER | 此等級(jí)下最低工資 |
| 3 | HISAL | NUMBER | 此等級(jí)下最高工資 |
?
?
章節(jié)知識(shí)結(jié)構(gòu)圖
?
?
?
?
?
?
?
?
?
?
?
?
第3章
?
?
子查詢和常用函數(shù)
?
?
?
?
?
???????????????????????????????????????????
?
?
| ? | 主要內(nèi)容 |
| ? | ü? 子查詢 ü? 偽列 ü? 鎖的概念 |
?
?
?
?
?
?
1.???子查詢
子查詢?cè)赟ELECT、UPDATE、DELETE語(yǔ)句內(nèi)部可以出現(xiàn)SELECT語(yǔ)句。內(nèi)部的SELECT語(yǔ)句結(jié)果可以作為外部語(yǔ)句中條件子句的一部分,也可以作為外部查詢的臨時(shí)表。子查詢的類型有:
1.???????單行子查詢:不向外部返回結(jié)果,或者只返回一行結(jié)果。
2.???????多行子查詢:向外部返回零行、一行或者多行結(jié)果。
?
案例1:查詢出銷售部(SALES)下面的員工姓名,工作,工資。
案例分析
該問(wèn)題可以用聯(lián)接查詢實(shí)現(xiàn),由于所需的結(jié)果信息都在Emp表中,可以先從Dept表中查詢出銷售部對(duì)應(yīng)的部門號(hào),然后根據(jù)當(dāng)前部門號(hào)再到Emp表中查詢出符合該部門的員工記錄即可。從銷售表中查詢出的結(jié)果可以作為Emp表中查詢的條件,SQL語(yǔ)句實(shí)現(xiàn)如下:
?
代碼演示:單行子查詢
| SQL> SELECT ENAME,JOB,SAL FROM EMP ? 2? WHERE DEPTNO=(SELECT DEPTNO FROM DEPT WHERE DNAME='SALES')?① ? 3? /
?6 rows selected |
代碼解析:
①??內(nèi)部查詢的結(jié)果作為外部查詢的條件。
?
需要注意:
???如果內(nèi)部查詢不返回任何記錄,則外部條件中字段DEPTNO與NULL比較永遠(yuǎn)為假,也就是說(shuō)外部查詢不返還任何結(jié)果。
???在單行子查詢中外部查詢可以使用=、>、<、>=、<=、<>等比較運(yùn)算符。
???內(nèi)部查詢返回的結(jié)果必須與外部查詢條件中的字段(DEPTNO)匹配。
???如果內(nèi)部查詢返回多行結(jié)果則出現(xiàn)錯(cuò)誤。
?
案例2:查詢出Emp表中比任意一個(gè)銷售員(“SALESMAN”)工資低的員工姓名、工作、工資。
案例分析
銷售員在Emp表中有很多條記錄,每個(gè)人工資不相等,如果返回“比任意員工的工資還低”的條件,返回比“最高工資還低”即可。如果用子查詢做,子查詢中就會(huì)返回多條記錄。用普通的關(guān)系符(>、<等)運(yùn)行就會(huì)出錯(cuò)。這時(shí)候需要用關(guān)鍵字ANY。ANY放在比較運(yùn)算符后面,表示“任意”的意思。
?
代碼演示:ANY子查詢
| SQL> SELECT ENAME,JOB,SAL FROM EMP ? 2? WHERE SAL<ANY (SELECT SAL FROM EMP WHERE JOB='SALESMAN')??① ? 3? /
?7 rows selected |
代碼解析:
①??<any:比子查詢結(jié)果中任意的值都小,也就是說(shuō),比子查詢結(jié)果中最大值還小,那么同理>any表示比子查詢結(jié)果中最小的還大。
?
案例3:查詢出比所有銷售員的工資都高的員工姓名,工作,工資。
?
案例分析
ANY可以表示任意的,但本案例中要求比所有銷售員工資都高,那么就要使用另外一個(gè)關(guān)鍵字ALL。ALL與關(guān)系操作符一起使用,表示與子查詢中所有元素比較。
?
代碼演示:ALL子查詢
| SQL> SELECT ENAME,JOB,SAL FROM EMP ? 2? WHERE SAL>ALL (SELECT SAL FROM EMP WHERE JOB='SALESMAN')??① ? 3? /
6 rows selected |
代碼解析:
①??>ALL:比子查詢結(jié)果中所有值還要大,也就是說(shuō),比子查詢結(jié)果中最大值還要大。<ALL表示比最小值還要小。
?
對(duì)于子查詢還可以使用IN和NOT IN操作符進(jìn)行操作。
?
2.???Oracle中的偽列
在Oracle的表的使用過(guò)程中,實(shí)際表中還有一些附加的列,稱為偽列。偽列就像表中的列一樣,但是在表中并不存儲(chǔ)。偽列只能查詢,不能進(jìn)行增刪改操作。接下來(lái)學(xué)習(xí)兩個(gè)偽列:ROWID和ROWNUM。
?
2??ROWID
?
表中的每一行在數(shù)據(jù)文件中都有一個(gè)物理地址,ROWID偽列返回的就是該行的物理地址。使用ROWID可以快速的定位表中的某一行。ROWID值可以唯一的標(biāo)識(shí)表中的一行。由于ROWID返回的是該行的物理地址,因此使用ROWID可以顯示行是如何存儲(chǔ)的。
?
代碼演示:ROWID
| SQL> SELECT ROWID,ENAME FROM EMP WHERE SAL>2000;
6 rows selected |
?
2??ROWNUM
?
在查詢的結(jié)果集中,ROWNUM為結(jié)果集中每一行標(biāo)識(shí)一個(gè)行號(hào),第一行返回1,第二行返回2,以此類推。通過(guò)ROWNUM偽列可以限制查詢結(jié)果集中返回的行數(shù)。
?
| ? | ROWNUM與ROWID不同,ROWID是插入記錄時(shí)生成,ROWNUM是查詢數(shù)據(jù)時(shí)生成。ROWID標(biāo)識(shí)的是行的物理地址。ROWNUM標(biāo)識(shí)的是查詢結(jié)果中的行的次序。 |
?
案例4:查詢出員工表中前5名員工的姓名,工作,工資。
?
代碼演示:ROWNUM
| SQL> SELECT ROWNUM,ENAME,JOB,SAL FROM EMP WHERE ROWNUM<=5;
|
?
案例5:查詢出工資最高的前5名員工的姓名、工資和工資。
案例分析
“工資最高的前5名”需要先降序排序,再取前5名,但是生成ROWNUM操作比排序要早,排序時(shí)已經(jīng)連同ROWNUM一起排序了,因此不能直接在案例1的語(yǔ)句中直接加上Order by就行,而是需要對(duì)排序的結(jié)果重新做二次查詢,產(chǎn)生新的ROWNUM才能作為查詢的條件依據(jù)。
?
代碼演示:ROWNUM應(yīng)用
| SQL> SELECT ROWNUM,T.* FROM??① ??2????? (SELECT ENAME,JOB,SAL ??3?????? FROM EMP ORDER BY SAL DESC) T??② ??4? WHERE ROWNUM<=5 ??5? / ?
|
代碼解析:
①??T是子查詢②的別名,這里的ROWNUM是第二次查詢后的ROWNUM。
?
案例6:查詢出表EMP中第5條到第10條之間的記錄。
案例分析
這是分頁(yè)的應(yīng)用。在查詢條件中,如果查詢條件中ROWNUM大于某一正整數(shù),則不返還任何結(jié)果。
?
代碼演示:ROWNUM分頁(yè)
| SQL> SELECT * FROM ??2???? (SELECT ROWNUM R,ENAME,JOB,SAL??① ??3????? FROM EMP WHERE ROWNUM<=10)??② ??4? WHERE R>5??③ ??5? /
|
代碼解析:
①??內(nèi)部查詢中得到ROWNUM?并且用別名R記錄,供外層條件③使用。
②??內(nèi)部查詢的ROWNUM,與外出的ROWNUM列是平等的兩列。
③??使用的R是內(nèi)層產(chǎn)生的ROWNUM,在外層看來(lái),內(nèi)層查詢的ROWNUM是正常的一列。
?
3.???Oracle函數(shù)
Oracle SQL提供了用于執(zhí)行特定操作的專用函數(shù)。這些函數(shù)大大增強(qiáng)了SQL語(yǔ)言的功能。函數(shù)可以接受零個(gè)或者多個(gè)輸入?yún)?shù),并返回一個(gè)輸出結(jié)果。Oracle數(shù)據(jù)庫(kù)中主要使用兩種類型的函數(shù):
1.?????????單行函數(shù):對(duì)每一個(gè)函數(shù)應(yīng)用在表的記錄中時(shí),只能輸入一行結(jié)果,返回一個(gè)結(jié)果,比如:MOD(x,y)返回x除以y的余數(shù)(x和y可以是兩個(gè)整數(shù),也可以是表中的整數(shù)列)。常用的單行函數(shù)有:
???字符函數(shù):對(duì)字符串操作。
???數(shù)字函數(shù):對(duì)數(shù)字進(jìn)行計(jì)算,返回一個(gè)數(shù)字。
???轉(zhuǎn)換函數(shù):可以將一種數(shù)據(jù)類型轉(zhuǎn)換為另外一種數(shù)據(jù)類型。
???日期函數(shù):對(duì)日期和時(shí)間進(jìn)行處理。
2.?????????聚合函數(shù):聚合函數(shù)同時(shí)可以對(duì)多行數(shù)據(jù)進(jìn)行操作,并返回一個(gè)結(jié)果。比如SUM(x)返回結(jié)果集中x列的總合。
????????
2??字符函數(shù)
?
字符函數(shù)接受字符參數(shù),這些參數(shù)可以是表中的列,也可以是一個(gè)字符串表達(dá)式。下表列出了常用的字符函數(shù)。
?
| 函數(shù) | 說(shuō)明 |
| ASCII(x) | 返回字符x的ASCII碼。 |
| CONCAT(x,y) | 連接字符串x和y。 |
| INSTR(x, str [,start] [,n) | 在x中查找str,可以指定從start開(kāi)始,也可以指定從第n次開(kāi)始。 |
| LENGTH(x) | 返回x的長(zhǎng)度。 |
| LOWER(x) | x轉(zhuǎn)換為小寫。 |
| UPPER(x) | x轉(zhuǎn)換為大寫。 |
| LTRIM(x[,trim_str]) | 把x的左邊截去trim_str字符串,缺省截去空格。 |
| RTRIM(x[,trim_str]) | 把x的右邊截去trim_str字符串,缺省截去空格。 |
| TRIM([trim_str FROM] x) | 把x的兩邊截去trim_str字符串,缺省截去空格。 |
| REPLACE(x,old,new) | 在x中查找old,并替換為new。 |
| SUBSTR(x,start[,length]) | 返回x的字串,從staart處開(kāi)始,截取length個(gè)字符,缺省length,默認(rèn)到結(jié)尾。 |
表1? 字符函數(shù)
?
| 示例 | 示例結(jié)果 |
| SELECT ASCII('a') FROM DUAL | 97 |
| SELECT CONCAT('Hello', ' world') FROM DUAL | Hello world |
| SELECT INSTR('Hello world','or') FROM DUAL | 8 |
| SELECT LENGTH('Hello') FROM DUAL | 5 |
| SELECT LOWER('hElLO') FROM DUAL; | hello |
| SELECT UPPER('hello') FROM DUAL | HELLO |
| SELECT LTRIM('===HELLO===', '=') FROM DUAL | HELLO=== |
| SELECT '=='||LTRIM('?? HELLO===') FROM DUAL | ==HELLO=== |
| SELECT RTRIM('===HELLO===', '=') FROM DUAL | ===HELLO |
| SELECT '='||TRIM('?? HELLO?? ')||'=' FROM DUAL | =HELLO= |
| SELECT TRIM('=' FROM '===HELLO===') FROM DUAL | HELLO |
| SELECT REPLACE('ABCDE','CD','AAA') FROM DUAL | ABAAAE |
| SELECT SUBSTR('ABCDE',2) FROM DUAL | BCDE |
| SELECT SUBSTR('ABCDE',2,3) FROM DUAL | BCD |
表2? 字符函數(shù)示例
?
2??數(shù)字函數(shù)
?
數(shù)字函數(shù)接受數(shù)字參數(shù),參數(shù)可以來(lái)自表中的一列,也可以是一個(gè)數(shù)字表達(dá)式。
?
| 函數(shù) | 說(shuō)明 | 示例 |
| ABS(x) | x絕對(duì)值 | ABS(-3)=3 |
| ACOS(x) | x的反余弦 | ACOS(1)=0 |
| COS(x) | 余弦 | COS(1)=1.57079633 |
| CEIL(x) | 大于或等于x的最小值 | CEIL(5.4)=6 |
| FLOOR(x) | 小于或等于x的最大值 | FLOOR(5.8)=5 |
| LOG(x,y) | x為底y的對(duì)數(shù) | LOG(2,4)=2 |
| MOD(x,y) | x除以y的余數(shù) | MOD(8,3)=2 |
| POWER(x,y) | x的y次冪 | POWER(2,3)=8 |
| ROUND(x[,y]) | x在第y位四舍五入 | ROUND(3.456,2)=3.46 |
| SQRT(x) | x的平方根 | SQRT(4)=2 |
| TRUNC(x[,y]) | x在第y位截?cái)?/p> | TRUNC(3.456,2)=3.45 |
表3? 數(shù)字函數(shù)
?
說(shuō)明:
1.???????ROUND(X[,Y]),四舍五入。
在缺省y時(shí),默認(rèn)y=0;比如:ROUND(3.56)=4。
y是正整數(shù),就是四舍五入到小數(shù)點(diǎn)后y位。ROUND(5.654,2)=5.65。
y是負(fù)整數(shù),四舍五入到小數(shù)點(diǎn)左邊|y|位。ROUND(351.654,-2)=400。
?
2.????????TRUNC(x[,y]),直接截取,不四舍五入。
在缺省y時(shí),默認(rèn)y=0;比如:TRUNC (3.56)=3。
y是正整數(shù),就是四舍五入到小數(shù)點(diǎn)后y位。TRUNC (5.654,2)=5.65。
y是負(fù)整數(shù),四舍五入到小數(shù)點(diǎn)左邊|y|位。TRUNC (351.654,-2)=300。
?
2??日期函數(shù)
?
日期函數(shù)對(duì)日期進(jìn)行運(yùn)算。常用的日期函數(shù)有:
1.?????????ADD_MONTHS(d,n),在某一個(gè)日期d上,加上指定的月數(shù)n,返回計(jì)算后的新日期。d表示日期,n表示要加的月數(shù)。
?
?
圖1??ADD_MONTHS函數(shù)示例
?
2.?????????LAST_DAY(d),返回指定日期當(dāng)月的最后一天。
?
?
圖2??LAST_DAY函數(shù)示例
?
3.?????????ROUND(d[,fmt]),返回一個(gè)以fmt為格式的四舍五入日期值,d是日期,fmt是格式模型。默認(rèn)fmt為DDD,即月中的某一天。
???如果fmt為“YEAR”則舍入到某年的1月1日,即前半年舍去,后半年作為下一年。
???如果fmt為“MONTH”則舍入到某月的1日,即前月舍去,后半月作為下一月。
???默認(rèn)為“DDD”,即月中的某一天,最靠近的天,前半天舍去,后半天作為第二天。
???如果fmt為“DAY”則舍入到最近的周的周日,即上半周舍去,下半周作為下一周周日。
?
?
圖3? ROUND函數(shù)示例
????????
與ROUND對(duì)應(yīng)的函數(shù)時(shí)TRUNC(d[,fmt])對(duì)日期的操作,TRUNC與ROUND非常相似,只是不對(duì)日期進(jìn)行舍入,直接截取到對(duì)應(yīng)格式的第一天。
?
4.?????????EXTRACT(fmt FROM d),提取日期中的特定部分。
?
fmt為:YEAR、MONTH、DAY、HOUR、MINUTE、SECOND。其中YEAR、MONTH、DAY可以為DATE類型匹配,也可以與TIMESTAMP類型匹配;但是HOUR、MINUTE、SECOND必須與TIMESTAMP類型匹配。
?
HOUR匹配的結(jié)果中沒(méi)有加上時(shí)區(qū),因此在中國(guó)運(yùn)行的結(jié)果小8小時(shí)。
?
圖4??EXTRACT函數(shù)示例
?
2??轉(zhuǎn)換函數(shù)
?
轉(zhuǎn)換函數(shù)將值從一種數(shù)據(jù)類型轉(zhuǎn)換為另外一種數(shù)據(jù)類型。常用的轉(zhuǎn)換函數(shù)有:
?
1.?????????TO_CHAR(d|n[,fmt])
?
把日期和數(shù)字轉(zhuǎn)換為制定格式的字符串。fmt是格式化字符串,日期的格式化字符串前面已經(jīng)學(xué)習(xí)過(guò)。
?
代碼演示:TO_CHAR對(duì)日期的處理
| SQL> SELECT TO_CHAR(SYSDATE,'YYYY"年"MM"月"DD"日" HH24:MI:SS') "date"? ① ? 2? FROM DUAL; ? date ----------------------- 2009年08月11日 12:06:00 |
代碼解析:
①??在格式化字符串中,使用雙引號(hào)對(duì)非格式化字符進(jìn)行引用。
?
針對(duì)數(shù)字的格式化,格式化字符有:
?
| 參數(shù) | 示例 | 說(shuō)明 |
| 9 | 999 | 指定位置處顯示數(shù)字。 |
| . | 9.9 | 指定位置返回小數(shù)點(diǎn) |
| , | 99,99 | 指定位置返回一個(gè)逗號(hào) |
| $ | $999 | 數(shù)字開(kāi)頭返回一個(gè)美元符號(hào) |
| EEEE | 9.99EEEE | 科學(xué)計(jì)數(shù)法表示 |
| L | L999 | 數(shù)字前加一個(gè)本地貨幣符號(hào) |
| PR | 999PR | 如果數(shù)字式負(fù)數(shù)則用尖括號(hào)進(jìn)行表示 |
表4? 數(shù)字格式化字符
?
代碼演示:TO_CHAR對(duì)數(shù)字的處理
| SQL> SELECT TO_CHAR(-123123.45,'L9.9EEEEPR') "date" ? 2? FROM DUAL ? 3? / date -------------------- ?<¥1.2E+05> |
?
2.?????????TO_DATE(x [,fmt])
把一個(gè)字符串以fmt格式轉(zhuǎn)換為一個(gè)日期類型,前面已經(jīng)學(xué)習(xí)過(guò)。
????????
3.?????????TO_NUMBER(x[,fmt])
把一個(gè)字符串以fmt格式轉(zhuǎn)換為一個(gè)數(shù)字。fmt格式字符參考表3。
?
代碼演示:TO_NUM函數(shù)
| SQL> SELECT TO_NUMBER('-$12,345.67','$99,999.99') "NUM" ? 2? FROM DUAL ? 3? / ? ???NUM --------------- ?-12345.67 |
?
2??其他單行函數(shù)
?
1.?????????NVL(x,value)
如果x為空,返回value,否則返回x。
????????
?????????案例7:對(duì)工資是2000元以下的員工,如果沒(méi)有發(fā)獎(jiǎng)金,每人獎(jiǎng)金100元。
?
代碼演示:NVL函數(shù)
| SQL> SELECT ENAME,JOB,SAL,NVL(COMM,100) FROM EMP WHERE SAL<2000;
? 7 rows selected |
?
2.?????????NVL2(x,value1,value2)
如果x非空,返回value1,否則返回value2。
?
案例8:對(duì)EMP表中工資為2000元以下的員工,如果沒(méi)有獎(jiǎng)金,則獎(jiǎng)金為200元,如果有獎(jiǎng)金,則在原來(lái)的獎(jiǎng)金基礎(chǔ)上加100元。
?
代碼演示:NVL2函數(shù)
| SQL> SELECT ENAME,JOB,SAL,NVL2(COMM,comm+100,200) "comm" ? 2? FROM EMP WHERE SAL<2000;
8 rows selected |
?
2??聚合函數(shù)
?
聚合函數(shù)同時(shí)對(duì)一組數(shù)據(jù)進(jìn)行操作,返回一行結(jié)果,比如計(jì)算一組數(shù)據(jù)的總和,平均值等。
?
| 名稱 | 作用 | 語(yǔ)法 |
| AVG | 平均值 | AVG(表達(dá)式) |
| SUM | 求和 | SUM(表達(dá)式) |
| MIN、MAX | 最小值、最大值 | MIN(表達(dá)式)、MAX(表達(dá)式) |
| COUNT | 數(shù)據(jù)統(tǒng)計(jì) | COUNT(表達(dá)式) |
表 5? 聚合函數(shù)
?
案例9:求本月所有員工的基本工資總和。
?
代碼演示:SUM函數(shù)
| SQL> select sum(sal) from emp; ? SUM(SAL) ---------------- ? ???29025 |
?
案例10:求不同部門的平均工資。
?
代碼演示:AVG函數(shù)下的分組查詢
| SQL> SELECT DEPTNO,AVG(SAL) FROM EMP GROUP BY DEPTNO; ? DEPTNO?? AVG(SAL) --------- ?????---------- ??? 30 ???1566.66666 ??? 20??? 2175 ??? 10 ???2916.66666 |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
4.???本章總結(jié)
???Oracle常用函數(shù)有字符相關(guān)的函數(shù)、數(shù)字相關(guān)的函數(shù)、日期相關(guān)的函數(shù)、轉(zhuǎn)換函數(shù)等。
???EXTRACT函數(shù)能夠獲取日期中的某個(gè)字段的值。
???TO_CHAR函數(shù)能夠把數(shù)字和日期轉(zhuǎn)換成固定的字符串格式。TO_DATE?????????函數(shù)能夠把固定格式的字符串轉(zhuǎn)換為日期類型。
???子查詢中有返回單行的子查詢和返回多行的子查詢。
???Oracle中存在ROWID、ROWNUM等偽列。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
5.???本章練習(xí)
1.???????描述TO_CHAR和TO_DATE函數(shù)的用法。
2.???????描述EXTRACT函數(shù)的用法。
3.???????你知道有哪些關(guān)于日期函數(shù)的用法?
?
章節(jié)知識(shí)結(jié)構(gòu)圖
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
第4章
?
?
表空間、數(shù)據(jù)庫(kù)對(duì)象
?
?
?
?
?
???????????????????????????????????????????
?
?
| ? | 主要內(nèi)容 |
| ? | ü? 同義詞概念 ü? 序列的應(yīng)用 ü? 視圖的概念 ü? 索引的概念 ü? 表空間的概念 |
?
?
?
?
1.???Oracle數(shù)據(jù)庫(kù)對(duì)象
數(shù)據(jù)庫(kù)對(duì)象是數(shù)據(jù)庫(kù)的組成部分,常常用CREATE命令進(jìn)行創(chuàng)建,可以使用ALTER命令修改,用DROP執(zhí)行刪除操作。前面已經(jīng)接觸過(guò)的數(shù)據(jù)庫(kù)對(duì)象有表、用戶等。
?
今天將學(xué)習(xí)更多的Oracle數(shù)據(jù)庫(kù)對(duì)象:
???同義詞:就是給數(shù)據(jù)庫(kù)對(duì)象一個(gè)別名。
???序列:Oracle中實(shí)現(xiàn)增長(zhǎng)的對(duì)象。
???視圖:預(yù)定義的查詢,作為表一樣的查詢使用,是一張?zhí)摂M表。
???索引:對(duì)數(shù)據(jù)庫(kù)表中的某些列進(jìn)行排序,便于提高查詢效率。
?
2.???同義詞
同義詞(Synonym)是數(shù)據(jù)庫(kù)對(duì)象的一個(gè)別名,Oracle可以為表、視圖、序列、過(guò)程、函數(shù)、程序包等指定一個(gè)別名。同義詞有兩種類型:
???私有同義詞:擁有CREATE SYNONYM權(quán)限的用戶(包括非管理員用戶)即可創(chuàng)建私有同義詞,創(chuàng)建的私有同義詞只能由當(dāng)前用戶使用。
???公有同義詞:系統(tǒng)管理員可以創(chuàng)建公有同義詞,公有同義詞可以被所有用戶訪問(wèn)。
?
?????????創(chuàng)建同義詞的語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):同義詞
| CREATE [OR REPLACE] [PUBLIC] SYSNONYM [schema.]synonym_name FOR [schema.]object_name |
語(yǔ)法解析:
①??CREATE [OR REPLACE:]表示在創(chuàng)建同義詞時(shí),如果該同義詞已經(jīng)存在,那么就用新創(chuàng)建的同義詞代替舊同義詞。
②??PULBIC:創(chuàng)建公有同義詞時(shí)使用的關(guān)鍵字,一般情況下不需要?jiǎng)?chuàng)建公有同義詞。
③??Oracle中一個(gè)用戶可以創(chuàng)建表、視圖等多種數(shù)據(jù)庫(kù)對(duì)象,一個(gè)用戶和該用戶下的所有數(shù)據(jù)庫(kù)對(duì)象的集合稱為Schema(中文稱為模式或者方案),用戶名就是Schema名。一個(gè)數(shù)據(jù)庫(kù)對(duì)象的全稱是:用戶名.對(duì)象名,即schema.object_name。
?
如果一個(gè)用戶有權(quán)限訪問(wèn)其他用戶對(duì)象時(shí),就可以使用全稱來(lái)訪問(wèn)。比如:
?
代碼演示:System用戶訪問(wèn)Scott用戶的Emp表
| SQL> conn system/manager@orcl; Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 Connected as system ? SQL>? SELECT ENAME,JOB,SAL FROM SCOTT.EMP WHERE SAL>2000;? ①
?6 rows selected |
代碼解析:
①??管理員用戶可以訪問(wèn)任何用戶的數(shù)據(jù)庫(kù)對(duì)象,SYSTEM用戶訪問(wèn)SCOTT用戶的EMP表時(shí),必須使用SCOTT.EMP。
?
案例1:創(chuàng)建一個(gè)用戶XiaoMei,該用戶擁有CONNECT角色和RESOURCE角色。為SCOTT用戶的EMP表創(chuàng)建同義詞,并通過(guò)同義詞訪問(wèn)該EMP表。
?
代碼演示:創(chuàng)建同義詞并訪問(wèn)
| SQL> CONN system/manager@orcl; Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 Connected as system SQL> CREATE USER XiaoMei IDENTIFIED BY XiaoMei; ?① User created SQL> GRANT CONNECT TO XiaoMei; Grant succeeded SQL> GRANT RESOURCE TO XiaoMei; Grant succeeded SQL> GRANT CREATE SYNONYM TO XiaoMei; Grant succeeded ? SQL> CONN XiaoMei/XiaoMei@ORCL; Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 Connected as XiaoMei ? SQL> CREATE SYNONYM MyEmp FOR SCOTT.EMP; ?② Synonym created SQL> SELECT * FROM MYEMP; ?③ SELECT * FROM MYEMP ORA-00942: 表或視圖不存在 ? SQL> CONNECT SCOTT/tiger@ORCL Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 Connected as SCOTT ? SQL> GRANT ALL ON EMP TO XiaoMei; ?④ Grant succeeded ? SQL> CONNECT XiaoMei/XiaoMei@ORCL; Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 Connected as XiaoMei ? SQL>? SELECT ENAME,JOB,SAL FROM MyEmp WHERE SAL>2000;? ⑤
?6 rows selected |
代碼解析:
①??在管理員用戶下創(chuàng)建用戶XiaoMei,對(duì)用戶XiaoMei授予CONNECT和RESOURCE角色。為了XiaoMei能夠創(chuàng)建序列,必須授予系統(tǒng)權(quán)限:CREATE SYNONYM。
②??在XiaoMei用戶下,為SCOTT.EMP創(chuàng)建私有同義詞MyEmp,同義詞MyEmp只能在XiaoMei用戶下使用。訪問(wèn)MyEmp就是訪問(wèn)SCOTT.EMP對(duì)象。
③??訪問(wèn)MyEmp對(duì)象出錯(cuò):對(duì)象不存在。因?yàn)閄iaoMei如果訪問(wèn)MyEmp,就相當(dāng)于訪問(wèn)SCOTT.EMP對(duì)象,那么SCOTT用戶必須對(duì)XiaoMei授予相應(yīng)的權(quán)限。
④??SCOTT用戶下,把EMP表的所有權(quán)限(增刪改查)授予XiaoMei。
⑤??對(duì)MyEmp執(zhí)行查詢操作。MyEmp就可以像在本地的表一樣使用。
?
刪除同義詞使用的語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):刪除同義詞
| DROP [PUBLIC] SYNONYM [schema.]sysnonym_name |
語(yǔ)法解析:
①??PUBLIC:刪除公共同義詞。
②??同義詞的刪除只能被擁有同義詞對(duì)象的用戶或者管理員刪除。
③??此命令只能刪除同義詞,不能刪除同義詞下的源對(duì)象。
?
3.???序列
序列(Sequence)是用來(lái)生成連續(xù)的整數(shù)數(shù)據(jù)的對(duì)象。序列常常用來(lái)作為主鍵中增長(zhǎng)列,序列中的可以升序生成,也可以降序生成。創(chuàng)建序列的語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):創(chuàng)建序列
| CREATE SEQUENCE sequence_name [START WITH num] [INCREMENT BY increment] [MAXVALUE num|NOMAXVALUE] [MINVALUE num|NOMINVALUE] [CYCLE|NOCYCLE] [CACHE num|NOCACHE] |
語(yǔ)法解析:
①??START WITH:從某一個(gè)整數(shù)開(kāi)始,升序默認(rèn)值是1,降序默認(rèn)值是-1。
②??INCREMENT BY:增長(zhǎng)數(shù)。如果是正數(shù)則升序生成,如果是負(fù)數(shù)則降序生成。升序默認(rèn)值是1,降序默認(rèn)值是-1。
③??MAXVALUE:指最大值。
④??NOMAXVALUE:這是最大值的默認(rèn)選項(xiàng),升序的最大值是:1027,降序默認(rèn)值是-1。
⑤??MINVALUE:指最小值。
⑥??NOMINVALUE:這是默認(rèn)值選項(xiàng),升序默認(rèn)值是1,降序默認(rèn)值是-1026。
⑦??CYCLE:表示如果升序達(dá)到最大值后,從最小值重新開(kāi)始;如果是降序序列,達(dá)到最小值后,從最大值重新開(kāi)始。
⑧??NOCYCLE:表示不重新開(kāi)始,序列升序達(dá)到最大值、降序達(dá)到最小值后就報(bào)錯(cuò)。默認(rèn)NOCYCLE。
⑨??CACHE:使用CACHE選項(xiàng)時(shí),該序列會(huì)根據(jù)序列規(guī)則預(yù)生成一組序列號(hào)。保留在內(nèi)存中,當(dāng)使用下一個(gè)序列號(hào)時(shí),可以更快的響應(yīng)。當(dāng)內(nèi)存中的序列號(hào)用完時(shí),系統(tǒng)再生成一組新的序列號(hào),并保存在緩存中,這樣可以提高生成序列號(hào)的效率。Oracle默認(rèn)會(huì)生產(chǎn)20個(gè)序列號(hào)。
⑩??NOCACHE:不預(yù)先在內(nèi)存中生成序列號(hào)。
?
案例2:創(chuàng)建一個(gè)從1開(kāi)始,默認(rèn)最大值,每次增長(zhǎng)1的序列,要求NOCYCLE,緩存中有30個(gè)預(yù)先分配好的序列號(hào)。
?
代碼演示:生成序列號(hào)
| SQL> CREATE SEQUENCE MYSEQ ? 2? MINVALUE 1 ? 3? START WITH 1 ? 4? NOMAXVALUE ? 5? INCREMENT BY 1 ? 6? NOCYCLE ? 7? CACHE 30 ? 8? / ? Sequence created |
?
序列創(chuàng)建之后,可以通過(guò)序列對(duì)象的CURRVAL和NEXTVAL兩個(gè)“偽列”分別訪問(wèn)該序列的當(dāng)前值和下一個(gè)值。
?
代碼演示:序列使用
| SQL> SELECT MYSEQ.NEXTVAL FROM DUAL; NEXTVAL ---------- ?? 1 SQL> SELECT MYSEQ.NEXTVAL FROM DUAL; NEXTVAL ---------- 2 SQL> SELECT MYSEQ.CURRVAL FROM DUAL; CURRVAL ---------- ?? 2 |
?
?????????使用ALTER SEQUENCE可以修改序列,在修改序列時(shí)有如下限制:
1.???????不能修改序列的初始值。
2.???????最小值不能大于當(dāng)前值。
3.???????最大值不能小于當(dāng)前值。
?
使用DROP SEQUENCE命令可以刪除一個(gè)序列對(duì)象。
?
代碼演示:序列修改和刪除
| SQL> ALTER SEQUENCE MYSEQ ? 2? MAXVALUE 10000 ? 3? MINVALUE -300 ? 4? / SEQUENCE ALTERED SQL> DROP SEQUENCE MYSEQ; SEQUENCE DROPPED |
?
4.???視圖
視圖(View)實(shí)際上是一張或者多張表上的預(yù)定義查詢,這些表稱為基表。從視圖中查詢信息與從表中查詢信息的方法完全相同。只需要簡(jiǎn)單的SELECT…FROM即可。
?
視圖具有以下優(yōu)點(diǎn):
1.???????可以限制用戶只能通過(guò)視圖檢索數(shù)據(jù)。這樣就可以對(duì)最終用戶屏蔽建表時(shí)底層的基表。
2.???????可以將復(fù)雜的查詢保存為視圖。可以對(duì)最終用戶屏蔽一定的復(fù)雜性。
3.???????限制某個(gè)視圖只能訪問(wèn)基表中的部分列或者部分行的特定數(shù)據(jù)。這樣可以實(shí)現(xiàn)一定的安全性。
4.???????從多張基表中按一定的業(yè)務(wù)邏輯抽出用戶關(guān)心的部分,形成一張?zhí)摂M表。
?
語(yǔ)法結(jié)構(gòu):創(chuàng)建視圖
| CREATE [OR REPLACE] [{FORCE|NOFORCE}] VIEW view_name AS SELECT查詢 [WITH READ ONLY CONSTRAINT] |
語(yǔ)法解析:
1.???????OR REPLACE:如果視圖已經(jīng)存在,則替換舊視圖。
2.???????FORCE:即使基表不存在,也可以創(chuàng)建該視圖,但是該視圖不能正常使用,當(dāng)基表創(chuàng)建成功后,視圖才能正常使用。
3.???????NOFORCE:如果基表不存在,無(wú)法創(chuàng)建視圖,該項(xiàng)是默認(rèn)選項(xiàng)。
4.???????WITH READ ONLY:默認(rèn)可以通過(guò)視圖對(duì)基表執(zhí)行增刪改操作,但是有很多在基表上的限制(比如:基表中某列不能為空,但是該列沒(méi)有出現(xiàn)在視圖中,則不能通過(guò)視圖執(zhí)行insert操作),WITH READ ONLY說(shuō)明視圖是只讀視圖,不能通過(guò)該視圖進(jìn)行增刪改操作。現(xiàn)實(shí)開(kāi)發(fā)中,基本上不通過(guò)視圖對(duì)表中的數(shù)據(jù)進(jìn)行增刪改操作。
?
案例3:基于EMP表和DEPT表創(chuàng)建視圖
?
代碼演示:視圖
| SQL> CREATE OR REPLACE VIEW EMPDETAIL ? 2? AS ? 3? SELECT EMPNO,ENAME,JOB,HIREDATE,EMP.DEPTNO,DNAME ? 4? FROM EMP JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO ? 5? WITH READ ONLY ? 6? / ? VIEW CREATED ? SQL> SELECT * FROM EMPDETAIL;? ①
14 ROWS SELECTED |
代碼解析:
①???對(duì)視圖可以像表一樣進(jìn)行查詢。該視圖中隱藏了員工的工資。
?
刪除視圖可以使用“DROP VIEW?視圖名稱”,刪除視圖不會(huì)影響基表的數(shù)據(jù)。
?
5.???索引
當(dāng)我們?cè)谀潮緯胁檎姨囟ǖ恼鹿?jié)內(nèi)容時(shí),可以先從書的目錄著手,找到該章節(jié)所在的頁(yè)碼,然后快速的定位到該頁(yè)。這種做法的前提是頁(yè)面編號(hào)是有序的。如果頁(yè)碼無(wú)序,就只能從第一頁(yè)開(kāi)始,一頁(yè)頁(yè)的查找了。
?
數(shù)據(jù)庫(kù)中索引(Index)的概念與目錄的概念非常類似。如果某列出現(xiàn)在查詢的條件中,而該列的數(shù)據(jù)是無(wú)序的,查詢時(shí)只能從第一行開(kāi)始一行一行的匹配。創(chuàng)建索引就是對(duì)某些特定列中的數(shù)據(jù)排序,生成獨(dú)立的索引表。在某列上創(chuàng)建索引后,如果該列出現(xiàn)在查詢條件中,Oracle會(huì)自動(dòng)的引用該索引,先從索引表中查詢出符合條件記錄的ROWID,由于ROWID是記錄的物理地址,因此可以根據(jù)ROWID快速的定位到具體的記錄,表中的數(shù)據(jù)非常多時(shí),引用索引帶來(lái)的查詢效率非常可觀。
?
| ? | 2??如果表中的某些字段經(jīng)常被查詢并作為查詢的條件出現(xiàn)時(shí),就應(yīng)該考慮為該列創(chuàng)建索引。 2??當(dāng)從很多行的表中查詢少數(shù)行時(shí),也要考慮創(chuàng)建索引。有一條基本的準(zhǔn)則是:當(dāng)任何單個(gè)查詢要檢索的行少于或者等于整個(gè)表行數(shù)的10%時(shí),索引就非常有用。 |
?
Oracle數(shù)據(jù)庫(kù)會(huì)為表的主鍵和包含唯一約束的列自動(dòng)創(chuàng)建索引。索引可以提高查詢的效率,但是在數(shù)據(jù)增刪改時(shí)需要更新索引,因此索引對(duì)增刪改時(shí)會(huì)有負(fù)面影響。
?
語(yǔ)法結(jié)構(gòu):創(chuàng)建索引
| CREATE [UNIQUE] INDEX index_name ON table_name(column_name[,column_name…]) |
語(yǔ)法解析:
1.???????UNIQUE:指定索引列上的值必須是唯一的。稱為唯一索引。
2.???????index_name:指定索引名。
3.???????tabl_name:指定要為哪個(gè)表創(chuàng)建索引。
4.???????column_name:指定要對(duì)哪個(gè)列創(chuàng)建索引。我們也可以對(duì)多列創(chuàng)建索引;這種索引稱為組合索引。
?
案例4:為EMP表的ENAME列創(chuàng)建創(chuàng)建唯一索引,為EMP表的工資列創(chuàng)建普通索引,把JOB列先變?yōu)樾懺賱?chuàng)建索引。
?
代碼演示:創(chuàng)建索引
| SQL> CREATE UNIQUE INDEX UQ_ENAME_IDX ON EMP(ENAME); ?① Index created SQL> CREATE INDEX IDX_SAL ON EMP(SAL); ?② Index created SQL> CREATE INDEX IDX_JOB_LOWER ON EMP(LOWER(JOB));? ③ Index created |
代碼解析:
①??為SCOTT.EMP表的ENAME列創(chuàng)建唯一索引。
②??為SCOTT.EMP表的SAL列創(chuàng)建索引。
③??在查詢中可能經(jīng)常使用job的小寫作為條件的表達(dá)式,因此創(chuàng)建索引時(shí),可以先對(duì)JOB列中的所有值轉(zhuǎn)換為小寫后創(chuàng)建索引,而這時(shí)需要使用lower函數(shù),這種索引稱為基于函數(shù)的索引。
?
在select語(yǔ)句查詢時(shí),Oracle系統(tǒng)會(huì)自動(dòng)為查詢條件上的列應(yīng)用索引。索引就是對(duì)某一列進(jìn)行排序,因此在索引列上,重復(fù)值越少,索引的效果越明顯。
Oracle可以為一些列值重復(fù)非常多且值有限的列(比如性別列)上創(chuàng)建位圖索引。關(guān)于Oracle更多的索引類型(比如反向鍵索引等),請(qǐng)參考Oracle官方文檔。
?
6.???表空間
在數(shù)據(jù)庫(kù)系統(tǒng)中,存儲(chǔ)空間是較為重要的資源,合理利用空間,不但能節(jié)省空間,還可以提高系統(tǒng)的效率和工作性能。Oracle可以存放海量數(shù)據(jù),所有數(shù)據(jù)都在數(shù)據(jù)文件中存儲(chǔ)。而數(shù)據(jù)文件大小受操作系統(tǒng)限制,并且過(guò)大的數(shù)據(jù)文件對(duì)數(shù)據(jù)的存取性能影響非常大。同時(shí)Oracle是跨平臺(tái)的數(shù)據(jù)庫(kù),Oracle數(shù)據(jù)可以輕松的在不同平臺(tái)上移植,那么如何才能提供統(tǒng)一存取格式的大容量呢?Oracle采用表空間來(lái)解決。
?
表空間只是一個(gè)邏輯概念,若干操作系統(tǒng)文件(文件可以不是很大)可以組成一個(gè)表空間。表空間統(tǒng)一管理空間中的數(shù)據(jù)文件,一個(gè)數(shù)據(jù)文件只能屬于一個(gè)表空間。一個(gè)數(shù)據(jù)庫(kù)空間由若干個(gè)表空間組成。如圖所示:
?
?
圖1? 數(shù)據(jù)空間、表空間和數(shù)據(jù)文件
?
???????? Oracle中所有的數(shù)據(jù)(包括系統(tǒng)數(shù)據(jù)),全部保存在表空間中,常見(jiàn)的表空間有:
???系統(tǒng)表空間:存放系統(tǒng)數(shù)據(jù),系統(tǒng)表空間在數(shù)據(jù)庫(kù)創(chuàng)建時(shí)創(chuàng)建。表空間名稱為SYSTEM。存放數(shù)據(jù)字典和視圖以及數(shù)據(jù)庫(kù)結(jié)構(gòu)等重要系統(tǒng)數(shù)據(jù)信息,在運(yùn)行時(shí)如果SYSTEM空間不足,對(duì)數(shù)據(jù)庫(kù)影響會(huì)比較大,雖然在系統(tǒng)運(yùn)行過(guò)程中可以通過(guò)命令擴(kuò)充空間,但還是會(huì)影響數(shù)據(jù)庫(kù)的性能,因此有必要在創(chuàng)建數(shù)據(jù)庫(kù)時(shí)適當(dāng)?shù)陌褦?shù)據(jù)文件設(shè)置大一些。
???TMEP表空間:臨時(shí)表空間,安裝數(shù)據(jù)庫(kù)時(shí)創(chuàng)建,可以在運(yùn)行時(shí)通過(guò)命令增大臨時(shí)表空間。臨時(shí)表空間的重要作用是數(shù)據(jù)排序。比如當(dāng)用戶執(zhí)行了諸如Order by等命令后,服務(wù)器需要對(duì)所選取數(shù)據(jù)進(jìn)行排序,如果數(shù)據(jù)很大,內(nèi)存的排序區(qū)可能裝不下太大數(shù)據(jù),就需要把一些中間的排序結(jié)果寫在硬盤的臨時(shí)表空間中。
???用戶表自定義空間:用戶可以通過(guò)CREATE TABLESPACE命令創(chuàng)建表空間。
?
創(chuàng)建表空間需要考慮數(shù)據(jù)庫(kù)對(duì)分區(qū)(Extent,一個(gè)Oracle分區(qū)是數(shù)據(jù)庫(kù)文件中一段連續(xù)的空間,Oracle分區(qū)是Oracle管理中最小的單位)的管理,比如當(dāng)一個(gè)表創(chuàng)建后先申請(qǐng)一個(gè)分區(qū),在Insert執(zhí)行過(guò)程中,如果分區(qū)數(shù)據(jù)已滿,需要重新申請(qǐng)另外的分區(qū)。如果一個(gè)數(shù)據(jù)庫(kù)中的分區(qū)大小不一,創(chuàng)建表空間時(shí)需要考慮一系列問(wèn)題。因此在Oracle8i之后,創(chuàng)建表空間都推薦使用“本地管理表空間”,這種表空間中的分區(qū)是一個(gè)固定大小的值,創(chuàng)建表空間的語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):創(chuàng)建表空間
| CREATE TABLESPACE 空間名稱 DATAFILE '文件名1' SIZE 數(shù)字M [,'文件名2' SIZE 數(shù)字….] EXTENT MANAGEMENT LOCAL UNIFORM SIZE 數(shù)字M |
語(yǔ)法解析:
1.???????文件名包括完整路徑和文件名,每個(gè)數(shù)據(jù)文件定義了文件的初始大小,初始大小一般以“M”為單位。一個(gè)表空間中可以有多個(gè)數(shù)據(jù)文件。
2.???????EXTENT MANAGEMENT LOCAL指明表空間類型是:本地管理表空間。本地管理表空間要求Oracle中的數(shù)據(jù)分區(qū)(Extent)大小統(tǒng)一。
3.???????UNIFORM SIZE:指定每個(gè)分區(qū)的統(tǒng)一大小。
?
案例5:創(chuàng)建一個(gè)表空間,包含兩個(gè)數(shù)據(jù)文件大小分別是10MB,5MB,要求extent的大小統(tǒng)一為1M。
?
代碼演示:創(chuàng)建表空間
| SQL> CREATE TABLESPACE MYSPACE ? 2? DATAFILE 'D:/A.ORA' SIZE 10M, ? 3???????????? 'D:/B.ORA' SIZE 5M ? 4? EXTENT MANAGEMENT LOCAL ? 5? UNIFORM SIZE 1M ? 6? / ? Tablespace created |
?
必須是管理員用戶才能創(chuàng)建表空間,當(dāng)表空間的空間不足時(shí)可以使用ALTER TABLESPACE命令向表空間中追加數(shù)據(jù)文件擴(kuò)充表空間。
?
代碼演示:擴(kuò)充表空間
| SQL> ALTER TABLESPACE MYSPACE ? 2? ADD DATAFILE 'D:/C.ORA' SIZE 10M ? 3? / ? Tablespace altered |
?
?????????表空間可以在不使用時(shí)刪除,使用DROP TABLESPACE命令。
?
?????????數(shù)據(jù)庫(kù)的所有數(shù)據(jù)全部在某一表空間中存放,在創(chuàng)建用戶時(shí),可以為用戶指定某一表空間,那么該用戶下的所有數(shù)據(jù)庫(kù)對(duì)象(比如表)默認(rèn)都存儲(chǔ)在該空間中。
?
代碼演示:為某一用戶指定默認(rèn)表空間
| SQL> CREATE USER ACONG IDENTIFIED BY ACONG ? 2?? DEFAULT TABLESPACE MYSPACE ? 3? / ? User created |
?
?????????在創(chuàng)建表時(shí),表中數(shù)據(jù)存放在用戶的默認(rèn)表空間中,也可以通過(guò)tablespace子句為表指定表中數(shù)據(jù)存放在其他表空間中。
?
代碼演示:為表指定表空間
| SQL> CREATE TABLE SCORES ? 2? ( ? 3????????? ID NUMBER , ? 4????????? TERM VARCHAR2(2), ? 5? ?? ????STUID VARCHAR2(7) NOT NULL, ? 6? ?? ????EXAMNO VARCHAR2(7) NOT NULL, ? 7? ?? ????WRITTENSCORE NUMBER(4,1) NOT NULL, ? 8? ?? ????LABSCORE NUMBER(4,1) NOT NULL ? 9? ) ?10? TABLESPACE MYSPACE ?11? / ? Table created |
?
?????????創(chuàng)建索引時(shí)也可以為索引指定表空間。
?
代碼演示:為索引指定表空間
| SQL> CREATE INDEX UQ_ID ON SCORES(ID) ? 2? TABLESPACE MYSPACE; ? Index created |
?
?????????表和索引一旦創(chuàng)建,表空間無(wú)法修改。
?
?
?
?
?
7.???本章總結(jié)
???Oracle數(shù)據(jù)庫(kù)對(duì)象都是使用CREATE命令創(chuàng)建的。
???同義詞就是數(shù)據(jù)庫(kù)對(duì)象的一個(gè)別名。同義詞的類型有公有同義詞和私有同義詞。只有管理員可以創(chuàng)建共有同義詞。創(chuàng)建同義詞的命令是:CREATE SYNONYM。
???序列能夠產(chǎn)生一個(gè)連續(xù)不重復(fù)的整數(shù)。經(jīng)常作為數(shù)據(jù)庫(kù)的主鍵生成器。創(chuàng)建序列的命令是CREATE SEQUENCE。
???序列的訪問(wèn)使用兩個(gè)“偽列”,CURRVAL表示序列的當(dāng)前值,NEXTVAL表示序列的下一個(gè)值。
???視圖就是一個(gè)預(yù)處理的查詢語(yǔ)句,可以從若干表中過(guò)濾數(shù)據(jù)。
???索引就是在查詢中經(jīng)常使用的列進(jìn)行排序。常見(jiàn)的索引有:普通索引、唯一序列、組合索引以及基于函數(shù)的索引。此外還有位圖索引、反向鍵索引等。
???表空間是數(shù)據(jù)庫(kù)的一個(gè)邏輯概念,表空間由若干個(gè)數(shù)據(jù)文件組成。為數(shù)據(jù)庫(kù)對(duì)象和數(shù)據(jù)提供統(tǒng)一的空間管理。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
8.???本章練習(xí)
1.???????產(chǎn)生一個(gè)用于DEPT表的主鍵值的序列,序列起始值是100,最大值是500,增長(zhǎng)步長(zhǎng)是10。
2.???????用序列產(chǎn)生DEPT表的主鍵,向DEPT表中插入3條記錄。
3.???????為DEPT表創(chuàng)建一個(gè)同義詞。
4.???????創(chuàng)建一個(gè)視圖包括EMP表的EMPNO,ENAME,JOB,部門表的DNAME列,只能包含銷售部的記錄。
5.???????為EMP表的ENAME列創(chuàng)建唯一索引。
6.???????為EMP表的SAL列創(chuàng)建一個(gè)普通索引。
7.???????以學(xué)期和學(xué)生姓名為名稱比如(S2XiaoMei)創(chuàng)建一個(gè)表空間,該表空間是以學(xué)生姓名為用戶的默認(rèn)表空間。
?
章節(jié)知識(shí)結(jié)構(gòu)圖
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
第5章
?
?
PL/SQL程序設(shè)計(jì)
?
?
?
?
?
???????????????????????????????????????????
?
?
| ? | 主要內(nèi)容 |
| ? | ü? PL/SQL數(shù)據(jù)類型 ü? PL/SQL條件和循環(huán)控制 ü? 動(dòng)態(tài)執(zhí)行SQL ü? PL/SQL中的異常處理 |
?
?
?
?
?
1.???PL/SQL簡(jiǎn)介
從第一學(xué)期到現(xiàn)在,在數(shù)據(jù)庫(kù)上一直使用單一的SQL語(yǔ)句進(jìn)行數(shù)據(jù)操作,沒(méi)有流程控制,無(wú)法開(kāi)發(fā)復(fù)雜的應(yīng)用。Oracle PL/SQL語(yǔ)言(Procedural Language/SQL)是結(jié)合了結(jié)構(gòu)化查詢與Oracle自身過(guò)程控制為一體的強(qiáng)大語(yǔ)言,PL/SQL不但支持更多的數(shù)據(jù)類型,擁有自身的變量聲明、賦值語(yǔ)句,而且還有條件、循環(huán)等流程控制語(yǔ)句。過(guò)程控制結(jié)構(gòu)與SQL數(shù)據(jù)處理能力無(wú)縫的結(jié)合形成了強(qiáng)大的編程語(yǔ)言,可以創(chuàng)建過(guò)程和函數(shù)以及程序包。
?
???????? PL/SQL是一種塊結(jié)構(gòu)的語(yǔ)言,它將一組語(yǔ)句放在一個(gè)塊中,一次性發(fā)送給服務(wù)器,PL/SQL引擎分析收到PL/SQL語(yǔ)句塊中的內(nèi)容,把其中的過(guò)程控制語(yǔ)句由PL/SQL引擎自身去執(zhí)行,把PL/SQL塊中的SQL語(yǔ)句交給服務(wù)器的SQL語(yǔ)句執(zhí)行器執(zhí)行。如圖所示:
?
?
圖1? PL/SQL體系結(jié)構(gòu)
?
???????? PL/SQL塊發(fā)送給服務(wù)器后,先被編譯然后執(zhí)行,對(duì)于有名稱的PL/SQL塊(如子程序)可以單獨(dú)編譯,永久的存儲(chǔ)在數(shù)據(jù)庫(kù)中,隨時(shí)準(zhǔn)備執(zhí)行。PL/SQL的優(yōu)點(diǎn)還有:
?
???支持SQL
?
SQL是訪問(wèn)數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)語(yǔ)言,通過(guò)SQL命令,用戶可以操縱數(shù)據(jù)庫(kù)中的數(shù)據(jù)。PL/SQL支持所有的SQL數(shù)據(jù)操縱命令、游標(biāo)控制命令、事務(wù)控制命令、SQL函數(shù)、運(yùn)算符和偽列。同時(shí)PL/SQL和SQL語(yǔ)言緊密集成,PL/SQL支持所有的SQL數(shù)據(jù)類型和NULL值。
?
???支持面向?qū)ο缶幊?/strong>
?
PL/SQL支持面向?qū)ο蟮木幊?#xff0c;在PL/SQL中可以創(chuàng)建類型,可以對(duì)類型進(jìn)行繼承,可以在子程序中重載方法等。
?
???更好的性能
?
SQL是非過(guò)程語(yǔ)言,只能一條一條執(zhí)行,而PL/SQL把一個(gè)PL/SQL塊統(tǒng)一進(jìn)行編譯后執(zhí)行,同時(shí)還可以把編譯好的PL/SQL塊存儲(chǔ)起來(lái),以備重用,減少了應(yīng)用程序和服務(wù)器之間的通信時(shí)間,PL/SQL是快速而高效的。
?
???可移植性
?
使用PL/SQL編寫的應(yīng)用程序,可以移植到任何操作系統(tǒng)平臺(tái)上的Oracle服務(wù)器,同時(shí)還可以編寫可移植程序庫(kù),在不同環(huán)境中重用。
?
???安全性
??????????????????
可以通過(guò)存儲(chǔ)過(guò)程對(duì)客戶機(jī)和服務(wù)器之間的應(yīng)用程序邏輯進(jìn)行分隔,這樣可以限制對(duì)Oracle數(shù)據(jù)庫(kù)的訪問(wèn),數(shù)據(jù)庫(kù)還可以授權(quán)和撤銷其他用戶訪問(wèn)的能力。
?
2.???PL/SQL塊
PL/SQL是一種塊結(jié)構(gòu)的語(yǔ)言,一個(gè)PL/SQL程序包含了一個(gè)或者多個(gè)邏輯塊,邏輯塊中可以聲明變量,變量在使用之前必須先聲明。除了正常的執(zhí)行程序外,PL/SQL還提供了專門的異常處理部分進(jìn)行異常處理。每個(gè)邏輯塊分為三個(gè)部分,語(yǔ)法是:
?
語(yǔ)法結(jié)構(gòu):PL/SQL塊的語(yǔ)法
| [DECLARE ???? --declaration statements]? ① BEGIN ???? --executable statements? ② [EXCEPTION ???? --exception statements]? ③ END; |
語(yǔ)法解析:
①??聲明部分:聲明部分包含了變量和常量的定義。這個(gè)部分由關(guān)鍵字DECLARE開(kāi)始,如果不聲明變量或者常量,可以省略這部分。
②??執(zhí)行部分:執(zhí)行部分是?PL/SQL塊的指令部分,由關(guān)鍵字BEGIN開(kāi)始,關(guān)鍵字END結(jié)尾。所有的可執(zhí)行PL/SQL語(yǔ)句都放在這一部分,該部分執(zhí)行命令并操作變量。其他的PL/SQL塊可以作為子塊嵌套在該部分。PL/SQL塊的執(zhí)行部分是必選的。注意END關(guān)鍵字后面用分號(hào)結(jié)尾。
③??異常處理部分:該部分是可選的,該部分用EXCEPTION關(guān)鍵字把可執(zhí)行部分分成兩個(gè)小部分,之前的程序是正常運(yùn)行的程序,一旦出現(xiàn)異常就跳轉(zhuǎn)到異常部分執(zhí)行。
?
PL/SQL是一種編程語(yǔ)言,與Java和C#一樣,除了有自身獨(dú)有的數(shù)據(jù)類型、變量聲明和賦值以及流程控制語(yǔ)句外,PL/SQL還有自身的語(yǔ)言特性:
?
PL/SQL對(duì)大小寫不敏感,為了良好的程序風(fēng)格,開(kāi)發(fā)團(tuán)隊(duì)都會(huì)選擇一個(gè)合適的編碼標(biāo)準(zhǔn)。比如有的團(tuán)隊(duì)規(guī)定:關(guān)鍵字全部大些,其余的部分小寫。
?
PL/SQL塊中的每一條語(yǔ)句都必須以分號(hào)結(jié)束,SQL語(yǔ)句可以是多行的,但分號(hào)表示該語(yǔ)句結(jié)束。一行中可以有多條SQL語(yǔ)句,他們之間以分號(hào)分隔,但是不推薦一行中寫多條語(yǔ)句。
?
PL/SQL中的特殊符號(hào)說(shuō)明:
?
| 類型 | 符號(hào) | 說(shuō)明 |
| 賦值運(yùn)算符 | := | Java和C#中都是等號(hào),PL/SQL的賦值是:= |
| 特殊字符 | || | 字符串連接操作符。 |
| -- | PL/SQL中的單行注釋。 | |
| /*,*/ | PL/SQL中的多行注釋,多行注釋不能嵌套。 | |
| <<,>> | 標(biāo)簽分隔符。只為了標(biāo)識(shí)程序特殊位置。 | |
| .. | 范圍操作符,比如:1..5?標(biāo)識(shí)從1到5 | |
| 算術(shù)運(yùn)算符 | +,-,*,/ | 基本算術(shù)運(yùn)算符。 |
| ** | 求冪操作,比如:3**2=9 | |
| 關(guān)系運(yùn)算符 | >,<,>=,<=,= | 基本關(guān)系運(yùn)算符,=表示相等關(guān)系,不是賦值。 |
| <>,!= | 不等關(guān)系。 | |
| 邏輯運(yùn)算符 | AND,OR,NOT | 邏輯運(yùn)算符。 |
表1??PL/SQL中的特殊符號(hào)和運(yùn)算符
?
2??變量聲明
?
PL/SQL支持SQL中的數(shù)據(jù)類型,PL/SQL中正常支持NUMBER,VARCHAR2,DATE等Oracle SQL數(shù)據(jù)類型。聲明變量必須指明變量的數(shù)據(jù)類型,也可以聲明變量時(shí)對(duì)變量初始化,變量聲明必須在聲明部分。聲明變量的語(yǔ)法是:
?
語(yǔ)法格式:聲明變量
| 變量名數(shù)據(jù)類型[ :=初始值] |
語(yǔ)法解析:
數(shù)據(jù)類型如果需要長(zhǎng)度,可以用括號(hào)指明長(zhǎng)度,比如:varchar2(20)。
?
代碼演示:聲明變量
| SQL> DECLARE ? 2?????? sname VARCHAR2(20) :='jerry';? ① ? 3? BEGIN ? 4?????? sname:=sname||' and tom';? ② ? 5?????? dbms_output.put_line(sname);? ③ ? 6? END; ? 7? /jerry PL/SQL procedure successfully completed |
代碼解析:
①??聲明一個(gè)變量sname,初始化值是“jerry”。字符串用單引號(hào),如果字符串中出現(xiàn)單引號(hào)可以使用兩個(gè)單引號(hào)(’’)來(lái)表示,即單引號(hào)同時(shí)也具有轉(zhuǎn)義的作用。
②??對(duì)變量sname重新賦值,賦值運(yùn)算符是“:=”。
③??dbms_output.put_line是輸出語(yǔ)句,可以把一個(gè)變量的值輸出,在SQL*Plus中輸出數(shù)據(jù)時(shí),可能沒(méi)有結(jié)果顯示,可以使用命令:set serveroutput on設(shè)置輸出到SQL*Plus控制臺(tái)上。
?
對(duì)變量賦值還可以使用SELECT…INTO?語(yǔ)句從數(shù)據(jù)庫(kù)中查詢數(shù)據(jù)對(duì)變量進(jìn)行賦值。但是查詢的結(jié)果只能是一行記錄,不能是零行或者多行記錄。
?
代碼演示:變量賦值
| SQL> DECLARE ? 2?????? sname VARCHAR2(20) DEFAULT 'jerry';? ① ? 3? BEGIN ? 4?????? SELECT ename INTO sname FROM emp WHERE empno=7934;? ② ? 5?????? dbms_output.put_line(sname); ? 6? END; ? 7? / MILLER PL/SQL procedure successfully completed |
代碼解析:
①??變量初始化時(shí),可以使用DEFAULT關(guān)鍵字對(duì)變量進(jìn)行初始化。
②??使用select…into語(yǔ)句對(duì)變量sname賦值,要求查詢的結(jié)果必須是一行,不能是多行或者沒(méi)有記錄。
?
2??聲明常量
?
常量在聲明時(shí)賦予初值,并且在運(yùn)行時(shí)不允許重新賦值。使用CONSTANT關(guān)鍵字聲明常量。
?
代碼演示:聲明常量
| SQL> DECLARE ? 2?????? pi CONSTANT number :=3.14;?? --圓周率長(zhǎng)值? ① ? 3?????? r number DEFAULT 3;?? --圓的半徑默認(rèn)值3? ② ? 4?????? area number;?? --面積。 ? 5? BEGIN ? 6?????? area:=pi*r*r;?? --計(jì)算面積 ? 7?????? dbms_output.put_line(area);? --輸出圓的面積 ? 8? END; ? 9? / ? 28.26 ? PL/SQL procedure successfully completed |
代碼解析:
①??聲明常量時(shí)使用關(guān)鍵字CONSTANT,常量初值可以使用賦值運(yùn)算符(:=)賦值,也可以使用DEFAULT關(guān)鍵字賦值。
?
在SQL*Plus中還可以聲明Session(會(huì)話,也就是一個(gè)客戶端從連接到退出的過(guò)程稱為當(dāng)前用戶的會(huì)話。)全局級(jí)變量,該變量在整個(gè)會(huì)話過(guò)程中均起作用,類似的這種變量稱為宿主變量。宿主變量在PL/SQL引用時(shí)要用“:變量名”引用。
?
代碼演示:宿主常量
| SQL> var emp_name varchar(30);? ① SQL> BEGIN ? 2? SELECT ename INTO :emp_name FROM emp WHERE empno=7499;? ② ? 3 ?END; ? 4? / PL/SQL procedure successfully completed emp_name --------- ALLEN ? SQL> print emp_name;? ③ emp_name --------- ALLEN |
代碼解析:
①??可以使用var聲明宿主變量。
②??PL/SQL中訪問(wèn)宿主變量時(shí)要在變量前加“:”。
③??在SQL*Plus中,使用print可以輸出變量中的結(jié)果。
?
3.???PL/SQL數(shù)據(jù)類型
前面在建表時(shí),學(xué)習(xí)過(guò)Oracle SQL的數(shù)據(jù)類型,PL/SQL不但支持這些數(shù)據(jù)類型,還具備自身的數(shù)據(jù)類型。PL/SQL的數(shù)據(jù)類型包括標(biāo)量數(shù)據(jù)類型,引用數(shù)據(jù)類型和存儲(chǔ)文本、圖像、視頻、聲音等非結(jié)構(gòu)化的大數(shù)據(jù)類型(LOB數(shù)據(jù)類型)等。下面列舉一些常用的類型。
?
2??標(biāo)量數(shù)據(jù)類型
?
標(biāo)量數(shù)據(jù)類型的變量只有一個(gè)值,且內(nèi)部沒(méi)有分量。標(biāo)量數(shù)據(jù)類型包括數(shù)字型,字符型,日期型和布爾型。這些類型有的是Oracle SQL中定義的數(shù)據(jù)類型,有的是PL/SQL自身附加的數(shù)據(jù)類型。字符型和數(shù)字型又有子類型,子類型只與限定的范圍有關(guān),比如NUMBER類型可以表示整數(shù),也可以表示小數(shù),而其子類型POSITIVE只表示正整數(shù)。
?
| 類型 | 說(shuō)明 |
| VARCHAR2(長(zhǎng)度) | 可變長(zhǎng)度字符串,Oracle SQL定義的數(shù)據(jù)類型,在PL/SQL中使用時(shí)最常32767字節(jié)。在PL/SQL中使用沒(méi)有默認(rèn)長(zhǎng)度,因此必須指定。 |
| NUMBER(精度,小數(shù)) | Oracle SQL定義的數(shù)據(jù)類型,見(jiàn)第二章。 |
| DATE | Oracle SQL定義的日期類型,見(jiàn)第二章。 |
| TIMESTAMP | Oracle SQL定義的日期類型,見(jiàn)第二章。 |
| CHAR(長(zhǎng)度) | Oracle SQL定義的日期類型,固定長(zhǎng)度字符,最長(zhǎng)32767字節(jié),默認(rèn)長(zhǎng)度是1,如果內(nèi)容不夠用空格代替。 |
| LONG | Oracle SQL定義的數(shù)據(jù)類型,變長(zhǎng)字符串基本類型,最長(zhǎng)32760字節(jié)。在Oracle SQL中最長(zhǎng)2147483647字節(jié)。 |
| BOOLEAN | PL/SQL附加的數(shù)據(jù)類型,邏輯值為TRUE、FALSE、NULL |
| BINARY_INTEGER | PL/SQL附加的數(shù)據(jù)類型,介于-231和231之間的整數(shù)。 |
| PLS_INTEGER | PL/SQL附加的數(shù)據(jù)類型,介于-231和231之間的整數(shù)。類似于BINARY_INTEGER,只是PLS_INTEGER值上的運(yùn)行速度更快。 |
| NATURAL | PL/SQL附加的數(shù)據(jù)類型,BINARY_INTEGER子類型,表示從0開(kāi)始的自然數(shù)。 |
| NATURALN | 與NATURAL一樣,只是要求NATURALN類型變量值不能為NULL。 |
| POSITIVE | PL/SQL附加的數(shù)據(jù)類型,BINARY_INTEGER子類型,正整數(shù)。 |
| POSITIVEN | 與POSITIVE一樣,只是要求POSITIVE的變量值不能為NULL。 |
| REAL | Oracle SQL定義的數(shù)據(jù)類型,18位精度的浮點(diǎn)數(shù) |
| INT,INTEGER,SMALLINT | Oracle SQL定義的數(shù)據(jù)類型,NUMBERDE的子類型,38位精度整數(shù)。 |
| SIGNTYPE | PL/SQL附加的數(shù)據(jù)類型,BINARY_INTEGER子類型。值有:1、-1、0。 |
| STRING | 與VARCHAR2相同。 |
表2??PL/SQL中標(biāo)量數(shù)據(jù)類型。
?
2??屬性數(shù)據(jù)類型
?
當(dāng)聲明一個(gè)變量的值是數(shù)據(jù)庫(kù)中的一行或者是數(shù)據(jù)庫(kù)中某列時(shí),可以直接使用屬性類型來(lái)聲明。Oracle中存在兩種屬性類型:%TYPE和%ROWTYPE。
?
???% ROWTYPE
引用數(shù)據(jù)庫(kù)表中的一行作為數(shù)據(jù)類型,即RECORD類型(記錄類型),是PL/SQL附加的數(shù)據(jù)類型。表示一條記錄,就相當(dāng)于C#中的一個(gè)對(duì)象。可以使用“.”來(lái)訪問(wèn)記錄中的屬性。
?
代碼演示:
| SQL> DECLARE ? 2?????? myemp EMP%ROWTYPE;? ① ? 3? BEGIN ? 4?????? SELECT * INTO myemp FROM emp WHERE empno=7934;? ② ? 5?????? dbms_output.put_line(myemp.ename);? ③ ? 6? END; ? 7? / MILLER PL/SQL procedure successfully completed |
代碼解析:
①??聲明一個(gè)myemp對(duì)象,該對(duì)象表示EMP表中的一行。
②??從EMP表中查詢一條記錄放入myemp對(duì)象中。
③??訪問(wèn)該對(duì)象的屬性可以使用“.”。
?
???%TYPE
引用某個(gè)變量或者數(shù)據(jù)庫(kù)的列的類型作為某變量的數(shù)據(jù)類型。
?
代碼演示:%TYPE應(yīng)用
| SQL> DECLARE ? 2?????? sal emp.sal%TYPE;? ① ? 3?????? mysal number(4):=3000; ? 4?????? totalsal mysal%TYPE;? ② ? 5? BEGIN ? 6?????? SELECT SAL INTO sal FROM emp WHERE empno=7934; ? 7?????? totalsal:=sal+mysal; ? 8?????? dbms_output.put_line(totalsal); ?9? END; ?10? / 4300 PL/SQL procedure successfully completed |
代碼解析:
①??定義變量sal為emp表中sal列的類型。
②??定義totalsal是變量mysal的類型。
?
%TYPE可以引用表中的某列作的類型為變量的數(shù)據(jù)類型,也可以引用某變量的類型作為新變量的數(shù)據(jù)類型。
?
4.???PL/SQL條件控制和循環(huán)控制
PL/SQL程序可通過(guò)條件或循環(huán)結(jié)構(gòu)來(lái)控制命令執(zhí)行的流程。PL/SQL提供了豐富的流程控制語(yǔ)句,與C#一樣也有三種控制結(jié)構(gòu):
???順序結(jié)構(gòu)
???條件結(jié)構(gòu)
???循環(huán)結(jié)構(gòu)
?
2??條件控制
?
C#中的條件控制使用關(guān)鍵字if和switch。PL/SQL中關(guān)于條件控制的關(guān)鍵字有IF-THEN、IF-THEN-ELSE、IF-THEN-ELSIF和多分枝條件CASE。
?
???IF-THEN
該結(jié)構(gòu)先判斷一個(gè)條件是否為TRUE,條件成立則執(zhí)行對(duì)應(yīng)的語(yǔ)句塊,與C#中的if語(yǔ)句很相似,具體語(yǔ)法是:
?
| C#中if語(yǔ)法 | PL/SQL中IF語(yǔ)法 |
| if (條件){ ???? //條件結(jié)構(gòu)體 } | IF?條件?THEN ???? --條件結(jié)構(gòu)體 END IF; |
表3 ?PL/SQL中條件語(yǔ)法
?
說(shuō)明:
①??用IF關(guān)鍵字開(kāi)始,END IF關(guān)鍵字結(jié)束,注意END IF后面有一個(gè)分號(hào)。
②??條件部分可以不使用括號(hào),但是必須以關(guān)鍵字THEN來(lái)標(biāo)識(shí)條件結(jié)束,如果條件成立,則執(zhí)行THEN后到對(duì)應(yīng)END IF之間的語(yǔ)句塊內(nèi)容。如果條件不成立,則不執(zhí)行條件語(yǔ)句塊的內(nèi)容。
③??C#結(jié)構(gòu)用一對(duì)大括號(hào)來(lái)包含條件結(jié)構(gòu)體的內(nèi)容。PL/SQL中關(guān)鍵字THEN到END IF之間的內(nèi)容是條件結(jié)構(gòu)體內(nèi)容。
④??條件可以使用關(guān)系運(yùn)算符合邏輯運(yùn)算符。
?
案例1:查詢JAMES的工資,如果大于900元,則發(fā)獎(jiǎng)金800元。
?
代碼演示:IF-THEN應(yīng)用
| DECLARE ????? newSal emp.sal % TYPE; ?BEGIN ????? SELECT sal INTO newSal FROM emp ????? WHERE ename='JAMES'; ????? IF newSal>900 THEN? ① ?????????? UPDATE emp ?????????? SET comm=800 ?????????? WHERE ename='JAMES'; ????? END IF; ????? COMMIT ;? ② END; |
代碼解析:
①??先判斷條件,如果條件為TRUE,則執(zhí)行條件結(jié)構(gòu)體內(nèi)部的內(nèi)容。
②??在PL/SQL塊中可以使用事務(wù)控制語(yǔ)句,該COMMIT同時(shí)也能把PL/SQL塊外沒(méi)有提交的數(shù)據(jù)一并提交,使用時(shí)需要注意。
?
???IF-THEN-ELSE
?
語(yǔ)法格式:IF-THEN-ELSE
| C#中if語(yǔ)法 | PL/SQL中IF語(yǔ)法 |
| if (條件){ ???? //條件成立結(jié)構(gòu)體 } else{ ??? //條件不成立結(jié)構(gòu)體 } | IF?條件?THEN ???? --條件成立結(jié)構(gòu)體 ELSE ???? --條件不成立結(jié)構(gòu)體 END IF; |
表4 ?PL/SQL中條件語(yǔ)法
?
語(yǔ)法解析:
把ELSE與IF-THEN連在一起使用,如果IF條件不成立則執(zhí)行就會(huì)執(zhí)行ELSE部分的語(yǔ)句。
?
案例2:查詢JAMES的工資,如果大于900元,則發(fā)獎(jiǎng)金800元,否則發(fā)獎(jiǎng)金400元。
?
代碼演示:IF-THEN-ELSE應(yīng)用
| DECLARE ????? newSal emp.sal % TYPE; BEGIN ????? SELECT sal INTO newSal FROM emp ????? WHERE ename='JAMES'; ????? IF newSal>900 THEN ?????????? UPDATE emp ?????????? SET comm=800 ?????????? WHERE ename='JAMES'; ??? ??ELSE ?????????? UPDATE emp ?????????? SET comm=400 ?????????? WHERE ename='JAMES'; ????? END IF; END; |
?
???IF-THEN-ELSIF
?
語(yǔ)法格式:IF-THEN-ELSIF
| C#中if語(yǔ)法 | PL/SQL中IF語(yǔ)法 |
| if (條件2){ ???? //條件成立結(jié)構(gòu)體 } else if(條件2){ ??? //條件不成立結(jié)構(gòu)體 } else{ ??? //以上條件都不成立結(jié)構(gòu)體 } | IF?條件1 THEN ???? --條件1成立結(jié)構(gòu)體 ELSIF?條件2 THEN ???? --條件2成立結(jié)構(gòu)體 ELSE ???? --以上條件都不成立結(jié)構(gòu)體 END IF; |
表5 ?PL/SQL中多分枝條件語(yǔ)法
語(yǔ)法解析:
PL/SQL中的再次條件判斷中使用關(guān)鍵字ELSIF,而C#使用else if。
?
案例3:查詢JAMES的工資,如果大于1500元,則發(fā)放獎(jiǎng)金100元,如果工作大于900元,則發(fā)獎(jiǎng)金800元,否則發(fā)獎(jiǎng)金400元。
?
代碼演示:IF-THEN-ELSIF應(yīng)用
| DECLARE ????? newSal emp.sal % TYPE; BEGIN ????? SELECT sal INTO newSal FROM emp ????? WHERE ename='JAMES'; ????? IF newSal>1500 THEN ?????????? UPDATE emp ?????????? SET comm=1000 ?????????? WHERE ename='JAMES'; ????? ELSIF newSal>1500 THEN ?????????? UPDATE emp ?????????? SET comm=800 ?????????? WHERE ename='JAMES'; ????? ELSE ?????????? UPDATE emp ?????????? SET comm=400 ?????????? WHERE ename='JAMES'; ????? END IF; END; |
?
???CASE
?
CASE是一種選擇結(jié)構(gòu)的控制語(yǔ)句,可以根據(jù)條件從多個(gè)執(zhí)行分支中選擇相應(yīng)的執(zhí)行動(dòng)作。也可以作為表達(dá)式使用,返回一個(gè)值。類似于C#中的switch語(yǔ)句。語(yǔ)法是:
?
語(yǔ)法格式:CASE
| CASE [selector] WHEN?表達(dá)式1 THEN?語(yǔ)句序列1; WHEN?表達(dá)式2 THEN?語(yǔ)句序列2; WHEN?表達(dá)式3 THEN?語(yǔ)句序列3; …… [ELSE?語(yǔ)句序列N]; END CASE; |
語(yǔ)法解析:
?????????如果存在選擇器selector,選擇器selector與WHEN后面的表達(dá)式匹配,匹配成功就執(zhí)行THEN后面的語(yǔ)句。如果所有表達(dá)式都與selector不匹配,則執(zhí)行ELSE后面的語(yǔ)句。
?
案例4:輸入一個(gè)字母A、B、C分別輸出對(duì)應(yīng)的級(jí)別信息。
?
代碼演示:CASE中存在selector,不返回值
| DECLARE ????? v_grade CHAR(1):=UPPER('&p_grade');? ① BEGIN ????? CASE v_grade? ② ?????????? WHEN 'A' THEN ?????????????? dbms_output.put_line('Excellent'); ?????????? WHEN 'B' THEN ?????????????? dbms_output.put_line('Very Good'); ?????????? WHEN 'C' THEN ?????????????? dbms_output.put_line('Good'); ?????????? ELSE ?????????????? dbms_output.put_line('No such grade'); ????? END CASE; END; |
代碼解析:
①??& grade表示在運(yùn)行時(shí)由鍵盤輸入字符串到grade變量中。
②??v_grade分別于WHEN后面的值匹配,如果成功就執(zhí)行WHEN后的程序序列。
?
CASE語(yǔ)句還可以作為表達(dá)式使用,返回一個(gè)值。
?
代碼演示:CASE中存在selector,作為表達(dá)式使用
| DECLARE ????? v_grade CHAR(1):=UPPER('&grade'); ????? p_grade VARCHAR(20) ; BEGIN ????? p_grade :=? ① ????? CASE v_grade ?????????? WHEN 'A' THEN ?????????????? 'Excellent' ?????????? WHEN 'B' THEN ?????????????? 'Very Good' ?????????? WHEN 'C' THEN ?????????????? 'Good' ?????????? ELSE ?????????????? 'No such grade' ????? END; ????? dbms_output.put_line('Grade:' ||v_grade||',the result is '||p_grade); END; |
代碼解析:
①??CASE語(yǔ)句可以返回一個(gè)結(jié)果給變量p_grade
?
PL/SQL還提供了搜索CASE語(yǔ)句。也就是說(shuō),不使用CASE中的選擇器,直接在WHEN后面判斷條件,第一個(gè)條件為真時(shí),執(zhí)行對(duì)應(yīng)THEN后面的語(yǔ)句序列。
?
代碼演示:搜索CASE
| DECLARE ????? v_grade CHAR(1):=UPPER('&grade'); ????? p_grade VARCHAR(20) ; BEGIN ????? p_grade := ????? CASE ?????????? WHEN v_grade='A' THEN ?????????????? 'Excellent' ?????????? WHEN v_grade='B' THEN ???????????? ??'Very Good' ?????????? WHEN v_grade='C' THEN ?????????????? 'Good' ?????????? ELSE ?????????????? 'No such grade' ????? END; ????? dbms_output.put_line('Grade:' ||v_grade||',the result is '||p_grade); END; |
?
2??循環(huán)結(jié)構(gòu)
?
PL/SQL提供了豐富的循環(huán)結(jié)構(gòu)來(lái)重復(fù)執(zhí)行一些列語(yǔ)句。Oracle提供的循環(huán)類型有:
1.?????????無(wú)條件循環(huán)LOOP-END LOOP語(yǔ)句
2.?????????WHILE循環(huán)語(yǔ)句
3.?????????FOR循環(huán)語(yǔ)句
?
在上面的三類循環(huán)中EXIT用來(lái)強(qiáng)制結(jié)束循環(huán),相當(dāng)于C#循環(huán)中的break。
?
???LOOP循環(huán)
?
LOOP循環(huán)是最簡(jiǎn)單的循環(huán),也稱為無(wú)限循環(huán),LOOP和END LOOP是關(guān)鍵字。
?
語(yǔ)法格式:LOOP循環(huán)
| LOOP ??? --循環(huán)體 END LOOP; |
語(yǔ)法格式:
1.???????循環(huán)體在LOOP和END LOOP之間,在每個(gè)LOOP循環(huán)體中,首先執(zhí)行循環(huán)體中的語(yǔ)句序列,執(zhí)行完后再重新開(kāi)始執(zhí)行。
2.???????在LOOP循環(huán)中可以使用EXIT或者[EXIT WHEN?條件]的形式終止循環(huán)。否則該循環(huán)就是死循環(huán)。
?
案例5:執(zhí)行1+2+3+…+100的值
?
代碼演示:LOOP循環(huán)
| DECLARE ????? counter number(3):=0; ????? sumResult number:=0; BEGIN ????? LOOP ????????? counter := counter+1; ????????? sumResult := sumResult+counter; ????????? IF counter>=100 THEN? ① ? ????????????EXIT; ????????? END IF; ??????????--EXIT WHEN counter>=100;? ② ????? END LOOP; ?????? dbms_output.put_line('result is :'||to_char(sumResult)); END; |
代碼解析:
①??LOOP循環(huán)中可以使用IF結(jié)構(gòu)嵌套EXIT關(guān)鍵字退出循環(huán)
②??注釋行,該行可以代替①中的循環(huán)結(jié)構(gòu),WHEN后面的條件成立時(shí)跳出循環(huán)。
?
???WHILE循環(huán)
?
與C#中的while循環(huán)很類似。先判斷條件,條件成立再執(zhí)行循環(huán)體。
?
語(yǔ)法格式:WHILE
| C#中while語(yǔ)法 | PL/SQL中WHILE語(yǔ)法 |
| while (條件){ ???? //循環(huán)體體 } | WHILE?條件?LOOP ??? --循環(huán)體 END LOOP; |
表5 ?PL/SQL中LOOP語(yǔ)法
?
案例6:WHILE循環(huán)
?
代碼演示:WHILE循環(huán)
| DECLARE ????? counter number(3):=0; ????? sumResult number:=0; BEGIN ????? WHILE counter<100 LOOP ????????? counter := counter+1; ????????? sumResult := sumResult+counter; ????? END LOOP; ?????? dbms_output.put_line('result is :'||sumResult); END; |
?
???FOR循環(huán)
?
FOR循環(huán)需要預(yù)先確定的循環(huán)次數(shù),可通過(guò)給循環(huán)變量指定下限和上限來(lái)確定循環(huán)運(yùn)行的次數(shù),然后循環(huán)變量在每次循環(huán)中遞增(或者遞減)。FOR循環(huán)的語(yǔ)法是:
?
語(yǔ)法格式:FOR循環(huán)
| FOR?循環(huán)變量?IN [REVERSE]?循環(huán)下限..循環(huán)上限?LOOP LOOP --循環(huán)體 END LOOP; |
語(yǔ)法解析:
循環(huán)變量:該變量的值每次循環(huán)根據(jù)上下限的REVERSE關(guān)鍵字進(jìn)行加1或者減1。
REVERSE:指明循環(huán)從上限向下限依次循環(huán)。
?
案例7:FOR循環(huán)
?
代碼演示:FOR循環(huán)
| DECLARE ????? counter number(3):=0; ????? sumResult number:=0; BEGIN ????? FOR counter IN 1..100 LOOP ????????? sumResult := sumResult+counter; ????? END LOOP; ?????? dbms_output.put_line('result is :'||sumResult); END; |
?
2??順序結(jié)構(gòu)
?
在程序順序結(jié)構(gòu)中有兩個(gè)特殊的語(yǔ)句。GOTO和NULL
?
???GOTO語(yǔ)句
?
GOTO語(yǔ)句將無(wú)條件的跳轉(zhuǎn)到標(biāo)簽指定的語(yǔ)句去執(zhí)行。標(biāo)簽是用雙尖括號(hào)括起來(lái)的標(biāo)示符,在PL/SQL塊中必須具有唯一的名稱,標(biāo)簽后必須緊跟可執(zhí)行語(yǔ)句或者PL/SQL塊。GOTO不能跳轉(zhuǎn)到IF語(yǔ)句、CASE語(yǔ)句、LOOP語(yǔ)句、或者子塊中。
?
???NULL語(yǔ)句
?
NULL語(yǔ)句什么都不做,只是將控制權(quán)轉(zhuǎn)到下一行語(yǔ)句。NULL語(yǔ)句是可執(zhí)行語(yǔ)句。NULL語(yǔ)句在IF或者其他語(yǔ)句語(yǔ)法要求至少需要一條可執(zhí)行語(yǔ)句,但又不需要具體操作的地方。比如GOTO的目標(biāo)地方不需要執(zhí)行任何語(yǔ)句時(shí)。
?
案例8:GOGO?和?NULL
?
代碼演示:GOTO和NULL
| DECLARE ??? sumsal emp.sal%TYPE; BEGIN ??? SELECT SUM(sal) INTO sumsal FROM EMP; ??? IF sumsal>20000 THEN ??????? GOTO first_label;? ① ??? ELSE ??????? GOTO second_label;? ② ??? END IF; ??? <<first_label>>? ③ ??? dbms_output.put_line('ABOVE 20000:' || sumsal); ??? <<second_label>>? ④ ??? NULL; END; |
代碼解析:
①??跳轉(zhuǎn)到程序first_label位置,就是②的位置,first_label是一個(gè)標(biāo)簽,用兩個(gè)尖括號(hào)包含。
②??無(wú)條件跳轉(zhuǎn)到sedond_label位置,就是④的位置。④處不執(zhí)行任何內(nèi)容,因此是一個(gè)NULL語(yǔ)句。
?
與C#一樣,在PL/SQL中,各種循環(huán)之間可以相互嵌套。
?
5.???PL/SQL中動(dòng)態(tài)執(zhí)行SQL語(yǔ)句
在PL/SQL程序開(kāi)發(fā)中,可以使用DML語(yǔ)句和事務(wù)控制語(yǔ)句,但是還有很多語(yǔ)句(比如DDL語(yǔ)句)不能直接在PL/SQL中執(zhí)行。這些語(yǔ)句可以使用動(dòng)態(tài)SQL來(lái)實(shí)現(xiàn)。
?
PL/SQL塊先編譯然后再執(zhí)行,動(dòng)態(tài)SQL語(yǔ)句在編譯時(shí)不能確定,只有在程序執(zhí)行時(shí)把SQL語(yǔ)句作為字符串的形式由動(dòng)態(tài)SQL命令來(lái)執(zhí)行。在編譯階段SQL語(yǔ)句作為字符串存在,程序不會(huì)對(duì)字符串中的內(nèi)容進(jìn)行編譯,在運(yùn)行階段再對(duì)字符串中的SQL語(yǔ)句進(jìn)行編譯和執(zhí)行,動(dòng)態(tài)SQL的語(yǔ)法是:
?
語(yǔ)法格式:動(dòng)態(tài)SQL
| EXECUTE IMMEDIATE?動(dòng)態(tài)語(yǔ)句字符串 [INTO?變量列表] [USING?參數(shù)列表] |
語(yǔ)法解析:
?????????如果動(dòng)態(tài)語(yǔ)句是SELECT語(yǔ)句,可以把查詢的結(jié)果保存到INTO后面的變量中。如果動(dòng)態(tài)語(yǔ)句中存在參數(shù),USING為語(yǔ)句中的參數(shù)傳值。
?????????動(dòng)態(tài)SQL中的參數(shù)格式是:[:參數(shù)名],參數(shù)在運(yùn)行時(shí)需要使用USING傳值。
?????? 案例9:動(dòng)態(tài)SQL
?
代碼演示:動(dòng)態(tài)SQL
| DECLARE ?? sql_stmt??? VARCHAR2(200);? --動(dòng)態(tài)SQL語(yǔ)句 ?? emp_id????? NUMBER(4) := 7566; ?? salary????? NUMBER(7,2); ?? dept_id???? NUMBER(2) := 90; ?? dept_name?? VARCHAR2(14) := 'PERSONNEL'; ?? location??? VARCHAR2(13) := 'DALLAS'; ?? emp_rec???? emp%ROWTYPE; BEGIN ?? --無(wú)子句的execute immediate ?? EXECUTE IMMEDIATE 'CREATE TABLE bonus1 (id NUMBER, amt NUMBER)';? ① ?? ----using子句的execute immediate ?? sql_stmt := 'INSERT INTO dept VALUES (:1, :2, :3)';? ?? EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location;? ② ?? ----into子句的execute immediate ?? sql_stmt := 'SELECT * FROM emp WHERE empno = :id'; ?? EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id;? ③ ? ?? ----returning into子句的execute immediate ?? sql_stmt := 'UPDATE emp SET sal = 2000 WHERE empno = :1 ????? RETURNING sal INTO :2'; ?? EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary;? ④ ? ?? EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = :num' ????? USING dept_id;? ⑤ END; |
代碼解析:
①??動(dòng)態(tài)執(zhí)行一個(gè)完整的SQL語(yǔ)句。
②??SQL語(yǔ)句中存在3個(gè)參數(shù)分別標(biāo)識(shí)為:[:1、:2、:3],因此需要用USING關(guān)鍵字對(duì)三個(gè)參數(shù)分別賦值。
③??對(duì)動(dòng)態(tài)查詢語(yǔ)句可以使用INTO子句把查詢的結(jié)果保存到一個(gè)變量中,要求該結(jié)果只能是單行。
④??在Oracle的insert,update,delete語(yǔ)句都可以使用RETURNING子句把操作影響的行中的數(shù)據(jù)返回,對(duì)SQL語(yǔ)句中存在RETURNING子句時(shí),在動(dòng)態(tài)執(zhí)行時(shí)可以使用RETURNING INTO來(lái)接收。
⑤??動(dòng)態(tài)執(zhí)行參數(shù)中可以是:[:數(shù)字]也可以是[:字符串]。
?
6.???PL/SQL的異常處理
在程序運(yùn)行時(shí)出現(xiàn)的錯(cuò)誤,稱為異常。發(fā)生異常后,語(yǔ)句將停止執(zhí)行,PL/SQL引擎立即將控制權(quán)轉(zhuǎn)到PL/SQL塊的異常處理部分。異常處理機(jī)制簡(jiǎn)化了代碼中的錯(cuò)誤檢測(cè)。PL/SQL中任何異常出現(xiàn)時(shí),每一個(gè)異常都對(duì)應(yīng)一個(gè)異常碼和異常信息。比如:
?
?
圖1 ?PL/SQL中的異常
?
2??預(yù)定義異常
????????
為了Oracle開(kāi)發(fā)和維護(hù)的方便,在Oracle異常中,為常見(jiàn)的異常碼定義了對(duì)應(yīng)的異常名稱,稱為預(yù)定義異常,常見(jiàn)的預(yù)定義異常有:
?
| 異常名稱 | 異常碼 | 描述 |
| DUP_VAL_ON_INDEX | ORA-00001 | 試圖向唯一索引列插入重復(fù)值 |
| INVALID_CURSOR | ORA-01001 | 試圖進(jìn)行非法游標(biāo)操作。 |
| INVALID_NUMBER | ORA-01722 | 試圖將字符串轉(zhuǎn)換為數(shù)字 |
| NO_DATA_FOUND | ORA-01403 | SELECT INTO語(yǔ)句中沒(méi)有返回任何記錄。 |
| TOO_MANY_ROWS | ORA-01422 | SELECT INTO語(yǔ)句中返回多于1條記錄。 |
| ZERO_DIVIDE | ORA-01476 | 試圖用0作為除數(shù)。 |
| CURSOR_ALREADY_OPEN | ORA-06511 | 試圖打開(kāi)一個(gè)已經(jīng)打開(kāi)的游標(biāo) |
表6 ?PL/SQL中預(yù)定義異常
?
???????? PL/SQL中用EXCEPTION關(guān)鍵字開(kāi)始異常處理。具體語(yǔ)法是:
?
語(yǔ)法格式:異常處理
| BEGIN ???????? --可執(zhí)行部分 ???????? EXCEPTION?? --?異常處理開(kāi)始 ?????????????????? WHEN?異常名1 THEN ??????????????????????????? ?--對(duì)應(yīng)異常處理 ??????? WHEN?異常名2 THEN ??????????????????????????? ?--對(duì)應(yīng)異常處理 ???????? …… ?????????????????? WHEN OTHERS THEN ???????????? --其他異常處理 ???????? END; |
語(yǔ)法解析:
?????????異常發(fā)生時(shí),進(jìn)入異常處理部分,具體的異常與若干個(gè)WHEN子句中指明的異常名匹配,匹配成功就進(jìn)入對(duì)應(yīng)的異常處理部分,如果對(duì)應(yīng)不成功,則進(jìn)入OTHERS進(jìn)行處理。
?
?????????案例10 :異常處理
?
代碼演示:異常處理
| SQL> DECLARE ? 2??????? newSal emp.sal % TYPE; ? 3? BEGIN ? 4??????? SELECT sal INTO newSal FROM emp; ? 5? EXCEPTION ? 6??????? WHEN TOO_MANY_ROWS THEN ? 7??????????? dbms_output.put_line('返回的記錄太多了'); ? 8??????? WHEN OTHERS THEN ? 9??????????? dbms_output.put_line('未知異常'); ?10? END; ?11? / 返回的記錄太多了 PL/SQL procedure successfully completed |
?
2??自定義異常。
?
?????????除了預(yù)定義異常外,用戶還可以在開(kāi)發(fā)中自定義異常,自定義異常可以讓用戶采用與PL/SQL引擎處理錯(cuò)誤相同的方式進(jìn)行處理,用戶自定義異常的兩個(gè)關(guān)鍵點(diǎn):
???異常定義:在PL/SQL塊的聲明部分采用EXCEPTION關(guān)鍵字聲明異常,定義方法與定義變量相同。比如聲明一個(gè)myexception異常方法是:
myexception EXCEPTION;
???異常引發(fā):在程序可執(zhí)行區(qū)域,使用RAISE關(guān)鍵字進(jìn)行引發(fā)。比如引發(fā)myexception方法是:
RAISE myexception;
?
?????? 案例11:自定義異常
?
代碼演示:自定義異常
| SQL> DECLARE ? 2????? sal emp.sal%TYPE; ? 3????? myexp EXCEPTION;? ① ? 4? BEGIN ? 5????? SELECT sal INTO sal FROM emp WHERE ename='JAMES'; ? 6????? IF sal<5000 THEN ? 7???????? RAISE myexp;? ② ? 8????? END IF; ? 9? EXCEPTION ?10????? WHEN NO_DATA_FOUND THEN ?11?????????? dbms_output.put_line('NO RECORDSET FIND!'); ?12????? WHEN MYEXP THEN? ③ ?13?????????? dbms_output.put_line('SAL IS TO LESS!'); ?14? END; ?15? / SAL IS TO LESS! PL/SQL procedure successfully completed |
代碼解析:
①??用EXCEPTION定義一個(gè)異常變量myexp
②??在一定條件下用RAISE引發(fā)異常myexp
③??在異常處理部分,捕獲異常,如果不處理異常,該異常就拋給程序執(zhí)行者。
?
2??引發(fā)應(yīng)用程序異常
?
在Oracle開(kāi)發(fā)中,遇到的系統(tǒng)異常都有對(duì)應(yīng)的異常碼,在應(yīng)用系統(tǒng)開(kāi)發(fā)中,用戶自定義的異常也可以指定一個(gè)異常碼和異常信息,Oracle系統(tǒng)為用戶預(yù)留了自定義異常碼,其范圍介于-20000到-20999之間的負(fù)整數(shù)。引發(fā)應(yīng)用程序異常的語(yǔ)法是:
RAISE_APPLICATION_ERROR(異常碼,異常信息)
?
案例12:引發(fā)系統(tǒng)異常
?
代碼演示:引發(fā)應(yīng)用系統(tǒng)異常
| SQL> DECLARE ? 2????? sal emp.sal%TYPE; ? 3????? myexp EXCEPTION; ? 4? BEGIN ? 5????? SELECT sal INTO sal FROM emp WHERE ename='JAMES'; ? 6????? IF sal<5000 THEN ? 7???????? RAISE myexp; ? 8????? END IF; ? 9? EXCEPTION ?10????? WHEN NO_DATA_FOUND THEN ?11?????????? dbms_output.put_line('NO RECORDSET FIND!'); ?12????? WHEN MYEXP THEN ?13?????????? RAISE_APPLICATION_ERROR(-20001,'SAL IS TO LESS!');? ① ?14? END; ?15? / ORA-20001: SAL IS TO LESS!? ② ORA-06512: 在 line 14 |
代碼解析:
①??引發(fā)應(yīng)用系統(tǒng)異常,指明異常碼和異常信息。
②??在控制臺(tái)上顯示異常碼和異常信息。
?
如果要處理未命名的內(nèi)部異常,必須使用OTHERS異常處理器。也可以利用PRAGMA EXCEPTION_INIT把一個(gè)異常碼與異常名綁定。
?
PRAGMA由編譯器控制,PRAGMA在編譯時(shí)處理,而不是在運(yùn)行時(shí)處理。EXCEPTION_INIT告訴編譯器將異常名與ORACLE錯(cuò)誤碼綁定起來(lái),這樣可以通過(guò)異常名引用任意的內(nèi)部異常,并且可以通過(guò)異常名為異常編寫適當(dāng)?shù)漠惓L幚砥鳌RAGMA EXCEPTION_INIT的語(yǔ)法是:
PRAGMA EXCEPTION_INIT(異常名,異常碼)
?
這里的異常碼可以是用戶自定義的異常碼,也可以是Oracle系統(tǒng)的異常碼。
?
案例13:PRAGMA EXCEPTION_INIT異常
?
代碼演示:PRAGMA EXCEPTION_INIT異常
| <<outterseg>> DECLARE ? null_salary EXCEPTION; ? PRAGMA EXCEPTION_INIT(null_salary, -20101);? ① BEGIN ? <<innerStart>>? ② ? DECLARE ??? curr_comm NUMBER; ? BEGIN ??? SELECT comm INTO curr_comm FROM emp WHERE empno = &empno; ??? IF curr_comm IS NULL THEN??? ???????? RAISE_APPLICATION_ERROR(-20101, 'Salary is missing');? ③ ??? ELSE ????? dbms_output.put_line('有津貼'); ??? END IF; ? END;? EXCEPTION ? WHEN NO_DATA_FOUND THEN ????????? dbms_output.put_line('沒(méi)有發(fā)現(xiàn)行'); ? WHEN null_salary THEN ????????? dbms_output.put_line('津貼未知');? ④ ? WHEN OTHERS THEN ?????????? dbms_output.put_line('未知異常'); END; |
代碼解析:
①??把異常名稱null_salary與異常碼-20101關(guān)聯(lián),該語(yǔ)句由于是預(yù)編譯語(yǔ)句,必須放在聲明部分。也就是說(shuō)-20101的異常名稱就是null_salary。
②??嵌套PL/SQL語(yǔ)句塊
③??在內(nèi)部PL/SQL語(yǔ)句塊中引發(fā)應(yīng)用系統(tǒng)異常-20101。
④??在外部的PL/SQL語(yǔ)句塊中就可以用異常名null_salary進(jìn)行捕獲。
?
7.???本章總結(jié)
???PL/SQL是一種塊結(jié)構(gòu)的語(yǔ)言,它將一組語(yǔ)句放在一個(gè)塊中,一次性發(fā)送給服務(wù)器,PL/SQL引擎把接收到PL/SQL語(yǔ)句塊中的內(nèi)容進(jìn)行分析,把其中的過(guò)程控制語(yǔ)句由PL/SQL引擎自身去執(zhí)行,把PL/SQL語(yǔ)句塊中的SQL語(yǔ)句交給服務(wù)器的SQL語(yǔ)句執(zhí)行器執(zhí)行。
???PL/SQL的數(shù)據(jù)類型包括標(biāo)量數(shù)據(jù)類型,引用數(shù)據(jù)類型和存儲(chǔ)文本、圖像、視頻、聲音等非結(jié)構(gòu)化得大數(shù)據(jù)類型(LOB數(shù)據(jù)類型)等。
???Oracle中存在兩種屬性類型:%TYPE和%ROWTYPE。
???PL/SQL程序可通過(guò)控制結(jié)構(gòu)來(lái)控制命令執(zhí)行的流程。PL/SQL中提供三種程序結(jié)構(gòu):順序結(jié)構(gòu)、條件結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。
???在PL/SQL程序開(kāi)發(fā)中,可以使用DML語(yǔ)句和事務(wù)控制語(yǔ)句,還可以動(dòng)態(tài)執(zhí)行SQL語(yǔ)句,動(dòng)態(tài)執(zhí)行SQL語(yǔ)句的命令是:EXECUTE IMMEDIATE。
???在程序運(yùn)行時(shí)出現(xiàn)的錯(cuò)誤,稱為異常。發(fā)生異常后,語(yǔ)句將停止執(zhí)行,PL/SQL引擎立即將控制權(quán)轉(zhuǎn)到PL/SQL塊的異常處理部分。PL/SQL中任何異常出現(xiàn)時(shí),每一個(gè)異常都對(duì)應(yīng)一個(gè)異常碼和異常信息。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
8.???本章練習(xí)
1.???????PL/SQL有哪些優(yōu)點(diǎn)?
2.???????請(qǐng)描述PL/SQL塊的結(jié)構(gòu)。
3.???????請(qǐng)描述多分枝判斷CASE的用法。
4.???????PL/SQL中有哪些循環(huán)控制語(yǔ)句?如何使用它們?
5.???????如何執(zhí)行動(dòng)態(tài)SQL語(yǔ)句?
6.???????如何自定義異常,如何把自定義異常與異常碼綁定?
7.???????編寫一個(gè)程序,輸入一個(gè)整數(shù),使用循環(huán)結(jié)構(gòu)將該數(shù)字左右翻轉(zhuǎn),輸出翻轉(zhuǎn)后的結(jié)果。
8.???????編寫一個(gè)程序,在EMP表查找姓名為ALLEN員工,并獲取TOO_MANY_ROWS和NO_DATA_FOUND異常。
9.???????編寫一個(gè)過(guò)程為班級(jí)每位同學(xué)創(chuàng)建一個(gè)用戶,用戶名和密碼都是:“班級(jí)號(hào)+學(xué)號(hào)”,并為每位用戶授權(quán):CONNECT和RESOURCE。
?
章節(jié)知識(shí)結(jié)構(gòu)圖
?
?
?
?
?
?
?
?
?
?
第6章
?
?
Oracle應(yīng)用于.Net平臺(tái)
?
?
?
?
?
?
?
?
| ? | 主要內(nèi)容 |
| ? | ü? 回顧ADO.NET ü? 使用ADO.NET連接Oracle ü? 抽象工廠加入Oracle ? ? ? |
?
?
?
?
?
?
1.???回顧ADO.NET
ADO.NET是一組用于和數(shù)據(jù)源進(jìn)行交互的面向?qū)ο箢悗?kù)集,它存在于.Net Framework中。通常情況下,數(shù)據(jù)源可以是各種類型的數(shù)據(jù)庫(kù),利用ADO.NET可以訪問(wèn)目前幾乎所有的主流數(shù)據(jù)庫(kù),如Oracle、SQL Server、DB2、Access等,但數(shù)據(jù)源同樣也能夠是文本文件、Excel文件或者XML文件,因此,ADO.NET可以訪問(wèn)的數(shù)據(jù)源是很多的。
?
ADO.NET由兩部分組成:.Net數(shù)據(jù)提供程序和數(shù)據(jù)集。
?
2??.Net數(shù)據(jù)提供程序
?
ADO.NET提供了與常用的各種數(shù)據(jù)源進(jìn)行交互的一些公共方法,但是對(duì)于不同的數(shù)據(jù)源由于它們各采用的協(xié)議是不一樣的,所以會(huì)采用不同的類庫(kù),這些類庫(kù)稱為數(shù)據(jù)提供程序。主要的數(shù)據(jù)提供程序如表1所示:
?
| 數(shù)據(jù)提供程序 | 說(shuō)明 | 對(duì)應(yīng)的命名空間 |
| SQL Server.NET | 訪問(wèn)SQL Server數(shù)據(jù)庫(kù)的提供程序,由于是針對(duì)SQLServer數(shù)據(jù)源而設(shè)計(jì),所以采用本提供程序訪問(wèn)SQL Server數(shù)據(jù)源時(shí)要比采用其它的提供程序,如OLE DB.NET訪問(wèn)SQL Server數(shù)據(jù)源,要快速得多 | System.Data.SqlClient |
| OLE DB.NET | 訪問(wèn)基于OLE DB協(xié)議構(gòu)建的數(shù)據(jù)源 | System.Data.OleDb |
| Oracle.NET | 訪問(wèn)Oracle數(shù)據(jù)庫(kù) | System.Data.OracleClient |
| ODBC.NET | 訪問(wèn)基于ODBC協(xié)議構(gòu)建的數(shù)據(jù)源 | System.Data.Odbc |
表1?主要的.NET數(shù)據(jù)提供程序
?
ADO.NET主要負(fù)責(zé)與數(shù)據(jù)庫(kù)服務(wù)器建立連接通道,并基于此連接通道實(shí)現(xiàn)從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù),并將內(nèi)存中的數(shù)據(jù)回送到數(shù)據(jù)庫(kù)以提交更新或?qū)⒃趦?nèi)存中拼寫好的SQL語(yǔ)句提交到數(shù)據(jù)庫(kù)服務(wù)器并執(zhí)行以實(shí)現(xiàn)某種數(shù)據(jù)操作等等。
?
2??數(shù)據(jù)集
?
數(shù)據(jù)集可以被看作是一個(gè)存儲(chǔ)在內(nèi)存中的離線式的數(shù)據(jù)庫(kù),它很像我們最終存儲(chǔ)數(shù)據(jù)的物理數(shù)據(jù)庫(kù),它將很多物理數(shù)據(jù)庫(kù)的機(jī)制搬到了內(nèi)存中。
?
ADO.NET的主要部分已經(jīng)在之前的章節(jié)介紹過(guò)了,例如:利用SQL Server.NET鏈接SQL Server數(shù)據(jù)庫(kù)。本章將主要介紹利用ADO.NET連接Oracle數(shù)據(jù)庫(kù),實(shí)現(xiàn)數(shù)據(jù)的存取。ADO.NET的結(jié)構(gòu)如圖1所示。
?
?
圖1? ADO.NET結(jié)構(gòu)圖
?
2.???使用ADO.NET連接Oracle
使用ADO.NET數(shù)據(jù)訪問(wèn)技術(shù)連接Oracle數(shù)據(jù)庫(kù)和連接Sql Server數(shù)據(jù)庫(kù)的步驟基本相同:
1.?????????使用Connection對(duì)象建立數(shù)據(jù)庫(kù)連接。
2.?????????使用Command對(duì)象執(zhí)行數(shù)據(jù)庫(kù)操作。
3.?????????采用連線或者斷線的方式進(jìn)行數(shù)據(jù)的存取。
4.?????????使用Connection對(duì)象的Close方法關(guān)閉數(shù)據(jù)庫(kù)連接。
?
連接Sql Server數(shù)據(jù)庫(kù)和Oracle數(shù)據(jù)庫(kù)所使用的數(shù)據(jù)提供程序是不一樣的,連接Sql Server數(shù)據(jù)庫(kù)使用的是SqlServer.NET,包括SqlConnection、SqlCommand等數(shù)據(jù)訪問(wèn)類。而連接Oracle數(shù)據(jù)庫(kù)則使用的是Oracle.NET,包括OracleConnection、OracleCommand等數(shù)據(jù)訪問(wèn)類,包含在System.Data.OracleClient命名空間下,由于該命名空間默認(rèn)并沒(méi)有被添加到項(xiàng)目中來(lái),所以在使用前需要如圖2所示添加響應(yīng)的引用才能使用。
?
圖2??添加System.Data.OracleClient引用
?
案例1:在Oracle數(shù)據(jù)庫(kù)中在System用戶下,創(chuàng)建UserInfo表,并插入一定數(shù)據(jù),使用ADO.NET數(shù)據(jù)訪問(wèn)技術(shù)將UserInfo表中的數(shù)據(jù)檢索出來(lái),并顯示在ASP.NET頁(yè)面中。UserInfo表中的數(shù)據(jù)如圖3所示。
?
?
圖2? UserInfo表中數(shù)據(jù)
?
實(shí)現(xiàn)步驟:
1.?????????使用OracleConnection對(duì)象建立與Oracle之間的連接。
?
代碼演示:建立連接
| //連接字符串 string connectionString = "Data Source=MYORCL;User ID=System;Password=accp;Unicode=True"; //創(chuàng)建Oracle連接對(duì)象 OracleConnection con = new OracleConnection(connectionString); //打開(kāi)連接 con.Open(); |
?
2.?????????創(chuàng)建命令行對(duì)象,準(zhǔn)備執(zhí)行檢索數(shù)據(jù)庫(kù)操作。
?
代碼演示:建立命令行對(duì)象
| //建立Sql查詢語(yǔ)句 string sql = "select * from userinfo"; //創(chuàng)建Oracle命令行對(duì)象 OracleCommand cmd = new OracleCommand(sql, con); //執(zhí)行命令行對(duì)象 OracleDataReader odr = cmd.ExecuteReader(CommandBehavior.CloseConnection); |
?
3.?????????創(chuàng)建實(shí)體類,并遍歷結(jié)果集,將數(shù)據(jù)存放到集合中存儲(chǔ)。
?
代碼演示:創(chuàng)建實(shí)體類
| //實(shí)體類 public class UserInfo { ??? int userID; ? ??? public int UserID ??? { ??????? get { return userID; } ??????? set { userID = value; } ??? } ??? string userName; ? ??? public string UserName ??? { ??????? get { return userName; } ??????? set { userName = value; } ??? } ??? string userAge; ? ??? public string UserAge ??? { ??????? get { return userAge; } ??????? set { userAge = value; } ?? ?} } |
?
代碼演示:遍歷結(jié)果集
| //遍歷結(jié)果集 IList<UserInfo> users = new List<UserInfo>(); while (odr.Read()) { ??? UserInfo user = new UserInfo(); ??? user.UserID = Convert.ToInt32(odr["UserID"]); ??? user.UserName = Convert.ToString(odr["UserName"]); ??? user.UserAge = Convert.ToString(odr["UserAge"]); ? ??? users.Add(user); } |
?
4.?????????將集合中的數(shù)據(jù)綁定到GridView控件上顯示出來(lái)。
?
代碼演示:綁定數(shù)據(jù)
| //綁定DataGridView控件 this.GridView1.DataSource = users; this.GridView1.DataBind(); |
?
根據(jù)上面的操作,不難看出連接Oracle數(shù)據(jù)庫(kù)與連接SqlServer數(shù)據(jù)庫(kù)除了數(shù)據(jù)提供程序方面有所區(qū)別之外,從操作步驟和實(shí)現(xiàn)原理等方面看區(qū)別不大。按照上面步驟操作,在頁(yè)面中運(yùn)行的效果如圖3所示。增刪改操作和檢索操作基本相似,在這里就不再敘述了。
?
圖3??案例效果
?
3.???抽象工廠中加入Oracle
在設(shè)計(jì)模式中介紹過(guò)抽象工廠設(shè)計(jì)模式(Abstract Factory),抽象工廠有四種關(guān)鍵角色:抽象工廠、實(shí)體工廠、抽象產(chǎn)品、實(shí)體產(chǎn)品。抽象工廠模式實(shí)現(xiàn)原理強(qiáng)調(diào)的是對(duì)象組合機(jī)制,由在“父工廠”內(nèi)定義不同的“子工廠”對(duì)象來(lái)負(fù)責(zé)不同的目標(biāo)對(duì)象的創(chuàng)建,也就是說(shuō)利用實(shí)體產(chǎn)品由抽象產(chǎn)品來(lái)約束,而由實(shí)體工廠來(lái)創(chuàng)建,實(shí)體工廠則由抽象工廠約束,可以有效的發(fā)揮工廠模式管理清晰的優(yōu)點(diǎn)。
?
?????????案例2:采用抽象工廠模式實(shí)現(xiàn)在學(xué)員信息管理系統(tǒng)中支持Access、SQLServer以及Oracle三套數(shù)據(jù)庫(kù)的切換(以學(xué)員基本信息模塊為例),以學(xué)員基本信息模塊為例給出概要的實(shí)現(xiàn),并實(shí)現(xiàn)展示所有學(xué)生信息功能。
?
?????????案例分析:本例是抽象工廠課堂案例的延續(xù),需要在項(xiàng)目中多添加一個(gè)Oracle數(shù)據(jù)庫(kù),實(shí)體產(chǎn)品是數(shù)據(jù)訪問(wèn)對(duì)象,三套數(shù)據(jù)庫(kù)相當(dāng)于有三套數(shù)據(jù)庫(kù)訪問(wèn)對(duì)象,通過(guò)三個(gè)實(shí)體工廠管理三套數(shù)據(jù)庫(kù)訪問(wèn)對(duì)象,最后使用抽象工廠管理三個(gè)實(shí)體工廠。
實(shí)現(xiàn)步驟:
1.?????????在Oracle數(shù)據(jù)庫(kù)中使用Sql語(yǔ)句新建Infos表,并添加約束和表數(shù)據(jù),如圖3所示:
?
?
圖3 ?Student表數(shù)據(jù)
2.?????????在VS2008中創(chuàng)建空白解決方案,命名為Test.sln。
3.?????????在解決方案中添加表示層,并添加StudentList.aspx頁(yè)面。
4.?????????在解決方案中添加模型層,根據(jù)上面的表結(jié)構(gòu)新建Student.cs實(shí)體類。
?
代碼演示:Student類
| public class Student { ??? string stuID; ? ??? public string StuID ??? { ??????? get { return stuID; } ??? ????set { stuID = value; } ??? } ? ??? /** * 其他成員… … */ } |
?
5.?????????在解決方案中添加數(shù)據(jù)訪問(wèn)層IDAL(抽象產(chǎn)品)。
?
代碼演示:抽象產(chǎn)品
| public interface IStudentService { ??? //獲取所有學(xué)生信息 ??? IList<Student> GetAllStudents(); } |
?
6.?????????在解決方案中添加數(shù)據(jù)訪問(wèn)層DAL(實(shí)體產(chǎn)品),并利用文件夾將不同的實(shí)體產(chǎn)品分類,如圖4所示。
?
?
圖4 ?實(shí)體產(chǎn)品
?
代碼演示:實(shí)體產(chǎn)品
| /// <summary> /// 獲得所有學(xué)生信息 /// </summary> /// <returns>所有學(xué)生信息集合</returns> public IList<Student> GetAllStudents() { ??? //創(chuàng)建SQL語(yǔ)句 ??? string sql = "select * from sys.infos"; ??? //創(chuàng)建泛型集合 ??? IList<Student> students = new List<Student>(); ??? //執(zhí)行SQL語(yǔ)句得到結(jié)果集 ??? OracleDataReader odr = dbh.ExecuteReader(sql); ??? //遍歷結(jié)果集 ??? while(odr.Read()) ??? { ??????? Student student = new Student(); ? ??????? student.StuID = Convert.ToString(odr["StuID"]); ??????? student.StuName = Convert.ToString(odr["StuName"]); ????? ??student.StuAddress = Convert.ToString(odr["StuAddress"]); ??????? student.Seat = Convert.ToInt32(odr["Seat"]); ??????? student.Gender = Convert.ToString(odr["Gender"]); ??????? student.EnRollDate = Convert.ToDateTime(odr["EnRollDate"]); ??????? student.ClassNo = Convert. ToString (odr["ClassNo"]); ??????? //添加到泛型集合 ??????? students.Add(student); ??? } ??? //返回 ??? return students; } |
?
7.?????????在解決方案中添加業(yè)務(wù)邏輯層,命名為StudentManager.cs。
?
代碼演示:BLL層
| /// <summary> /// 獲取所有學(xué)生信息 /// </summary> /// <returns>所有學(xué)生信息集合</returns> public IList<Student> GetAllStudents() { ??? //利用抽象工廠創(chuàng)建實(shí)體工廠 ??? Factory factory = Factory.CreateFactory(); ??? //利用工廠創(chuàng)建產(chǎn)品 ??? IStudentService iss = factory.GetStudentService(); ??? return iss.GetAllStudents(); } |
?
8.?????????在解決方案中添加抽象工廠,并添加相應(yīng)實(shí)體工廠,如圖5所示。
?
圖5 ?抽象工廠
?
代碼演示:抽象工廠
| //抽象工廠 public abstract class Factory { ??? public static Factory CreateFactory() ??? { ??????? //采用反射技術(shù)得到配置文件中的配置信息 ??????? string factoryType = Config.FactoryType; ??????? Factory factory = ??????????? (Factory)System.Reflection.Assembly.Load("DBFactory").CreateInstance(factoryType); ??????? return factory; ??? } ? ??? //定義子類(實(shí)體工廠)的操作規(guī)則 ??? public abstract IStudentService GetStudentService(); } |
?
9.?????????在表示層添加數(shù)據(jù)展示控件,通過(guò)設(shè)定屬性綁定數(shù)據(jù)提取方法,實(shí)現(xiàn)案例目標(biāo)。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
4.???本章總結(jié)
???ADO.NET是一組用于和數(shù)據(jù)源進(jìn)行交互的面向?qū)ο箢悗?kù)集,它存在于.Net Framework中。通常情況下,數(shù)據(jù)源可以是各種類型的數(shù)據(jù)庫(kù),利用ADO.NET可以訪問(wèn)目前幾乎所有的主流數(shù)據(jù)庫(kù),如Oracle、SQL Server、DB2、Access等。
???使用ADO.NET技術(shù)訪問(wèn)數(shù)據(jù)庫(kù)的大致步驟如下:
1.?????????使用Connection對(duì)象建立數(shù)據(jù)庫(kù)連接。
2.?????????使用Command對(duì)象執(zhí)行數(shù)據(jù)庫(kù)操作。
3.?????????采用連線或者斷線的方式進(jìn)行數(shù)據(jù)的存取。
4.?????????使用Connection對(duì)象的Close方法關(guān)閉數(shù)據(jù)庫(kù)連接。
???抽象工廠有四種關(guān)鍵角色:抽象工廠、實(shí)體工廠、抽象產(chǎn)品、實(shí)體產(chǎn)品。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
5.???本章練習(xí)
1.?????????利用本章所學(xué)知識(shí),完成如下功能:
1)?????????在本章完成項(xiàng)目基礎(chǔ)上,繼續(xù)實(shí)現(xiàn)對(duì)Oracle數(shù)據(jù)庫(kù)的增刪改操作。
2)?????????在StudentList.aspx頁(yè)面添加查看詳細(xì)鏈接,編寫GetStudentById等方法。
3)?????????在StudentList.aspx頁(yè)面中添加刪除鏈接,編寫DeleteStudent等方法。
4)?????????在StudentList.aspx頁(yè)面中添加修改鏈接,編寫UpdateStudent等方法。
?
?
章節(jié)知識(shí)結(jié)構(gòu)圖
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
附錄
?
?
數(shù)據(jù)庫(kù)導(dǎo)入導(dǎo)出
?
?
?
?
?
???????????????????????????????????????????
?
?
| ? | 主要內(nèi)容 |
| ? | ü? 導(dǎo)出 ü? 導(dǎo)入 |
?
?
?
?
?
?
?
?
1.???Oracle導(dǎo)入導(dǎo)出
Oracle的備份是Oracle操作中常見(jiàn)的工作,常見(jiàn)的備份方案有:邏輯備份(IMP&EXP命令進(jìn)行備份)、物理文件備份(脫機(jī)及聯(lián)機(jī)備份)、利用RMAN(Recovery Manager)的增量物理文件系統(tǒng)備份。ORACLE數(shù)據(jù)庫(kù)的邏輯備份分為四種模式:表空間備份(tablespace)、表備份(table)、用戶備份(user)和完全備份(full)。Oracle的邏輯備份是使用IMP&EXP命令進(jìn)行數(shù)據(jù)導(dǎo)入導(dǎo)出的操作。使用EXP命令導(dǎo)出或者使用IMP命令導(dǎo)入時(shí),需要Create Session系統(tǒng)權(quán)限,但是如果要導(dǎo)出其他的表,必須擁有權(quán)限:EXP_FULL_DATABASE。
?
調(diào)用導(dǎo)入導(dǎo)出命令時(shí),首先要估計(jì)所需的空間。EXP命令導(dǎo)出的文件是二進(jìn)制文件(*.dmp)只能由對(duì)應(yīng)的IMP命令進(jìn)行讀取恢復(fù)。導(dǎo)入導(dǎo)出的用途是:
???備份與恢復(fù)
???Oracle平臺(tái)更換:可以在相同版本之間進(jìn)行備份與恢復(fù),Oracle較低版本的export數(shù)據(jù)文件可以import到高版本的Oracle數(shù)據(jù)庫(kù)中,但是Oracle的版本只能是相鄰的,不能垮版本。
?
2.???EXP導(dǎo)出數(shù)據(jù)
EXP命令可以在交互環(huán)境下導(dǎo)出數(shù)據(jù)庫(kù)中的數(shù)據(jù),也可以在非交互環(huán)境下執(zhí)行命令。交互環(huán)境下的命令執(zhí)行,是一步一步執(zhí)行的過(guò)程。
?
代碼演示:exp的交互環(huán)境
| D:\>exp scott/tiger@my_orcl? ① Export: Release 10.2.0.3.0 - Production on 星期一 10月 19 17:04:14 2009 Copyright (c) 1982, 2005, Oracle.? All rights reserved. 連接到: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production With the Partitioning, OLAP and Data Mining options 輸入數(shù)組提取緩沖區(qū)大小: 4096 >? ② ?導(dǎo)出文件: EXPDAT.DMP > scott.dmp? ③ (2)U(用戶), 或 (3)T(表): (2)U > 2? ④ 導(dǎo)出權(quán)限 (yes/no): yes > yes? ⑤ 導(dǎo)出表數(shù)據(jù) (yes/no): yes > yes? ⑥ 壓縮區(qū) (yes/no): yes > no? ⑦ 已導(dǎo)出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集 . 正在導(dǎo)出 pre-schema 過(guò)程對(duì)象和操作 . 正在導(dǎo)出用戶 SCOTT 的外部函數(shù)庫(kù)名 . 導(dǎo)出 PUBLIC 類型同義詞 . 正在導(dǎo)出專用類型同義詞 . 正在導(dǎo)出用戶 SCOTT 的對(duì)象類型定義 即將導(dǎo)出 SCOTT 的對(duì)象... . 正在導(dǎo)出數(shù)據(jù)庫(kù)鏈接 . 正在導(dǎo)出序號(hào) . 正在導(dǎo)出簇定義 . 即將導(dǎo)出 SCOTT 的表通過(guò)常規(guī)路徑... . . 正在導(dǎo)出表?????????????????????????? BONUS導(dǎo)出了?????????? 0 行 . . 正在導(dǎo)出表??????????????????????????? DEPT導(dǎo)出了??????????? 10 行 . . 正在導(dǎo)出表???????????????????????????? EMP導(dǎo)出了??????????? 14 行 . . 正在導(dǎo)出表??????????????????????? SALGRADE導(dǎo)出了?????????? 5 行 . . 正在導(dǎo)出表????????????????????? TBLSTUDENT導(dǎo)出了?????????? 3 行 . 正在導(dǎo)出同義詞 . 正在導(dǎo)出視圖 . 正在導(dǎo)出存儲(chǔ)過(guò)程 . 正在導(dǎo)出運(yùn)算符 . 正在導(dǎo)出引用完整性約束條件 . 正在導(dǎo)出觸發(fā)器 . 正在導(dǎo)出索引類型 . 正在導(dǎo)出位圖, 功能性索引和可擴(kuò)展索引 . 正在導(dǎo)出后期表活動(dòng) . 正在導(dǎo)出實(shí)體化視圖 . 正在導(dǎo)出快照日志 . 正在導(dǎo)出作業(yè)隊(duì)列 . 正在導(dǎo)出刷新組和子組 . 正在導(dǎo)出維 . 正在導(dǎo)出 post-schema 過(guò)程對(duì)象和操作 . 正在導(dǎo)出統(tǒng)計(jì)信息 成功終止導(dǎo)出, 沒(méi)有出現(xiàn)警告。 D:\> |
代碼解析:
①??Exp是導(dǎo)出命令,該命令后面緊跟“用戶名/密碼@服務(wù)器網(wǎng)絡(luò)連接”。
②??Exp程序?qū)С鰰r(shí)使用的緩沖區(qū)大小,緩沖區(qū)越大,導(dǎo)出速度越快。直接回車代表使用默認(rèn)值4096B。
③??Exp命令會(huì)把所有要到處的數(shù)據(jù)導(dǎo)出到一個(gè)Dmp文件中,該步驟是Exp詢問(wèn)導(dǎo)出的數(shù)據(jù)文件名稱。
④??Exp程序詢問(wèn)導(dǎo)出整個(gè)用戶還是導(dǎo)出某個(gè)表。默認(rèn)導(dǎo)出整個(gè)用戶。
⑤??Exp程序詢問(wèn)是否導(dǎo)出每張表的訪問(wèn)權(quán)限。默認(rèn)導(dǎo)出訪問(wèn)權(quán)限。
⑥??Exp程序詢問(wèn)是否導(dǎo)出表中的數(shù)據(jù)。默認(rèn)導(dǎo)出數(shù)據(jù)庫(kù)表中的數(shù)據(jù)。
⑦??Oracle表中的數(shù)據(jù)可能來(lái)自不同的分區(qū)中的數(shù)據(jù)塊,默認(rèn)導(dǎo)出時(shí)會(huì)把所有的數(shù)據(jù)壓縮在一個(gè)數(shù)據(jù)塊上,IMP導(dǎo)入時(shí),如果不存在連續(xù)一個(gè)大數(shù)據(jù)塊,則會(huì)導(dǎo)入失敗。
?
也可以使用Exp命令時(shí),設(shè)置各種參數(shù),使準(zhǔn)備就緒的Exp命令不需要與用戶交互,按照參數(shù)的要求,Exp命令會(huì)一次性執(zhí)行導(dǎo)出工作。要指定參數(shù),您可以使用關(guān)鍵字:
?
EXP KEYWORD=value?或?KEYWORD=(value1,value2,...,valueN)
?
例如: EXP SCOTT/TIGER GRANTS=Y TABLES=(EMP,DEPT,MGR)
?
| 參數(shù)名 | 說(shuō)明 |
| USERID | 表示“用戶名/密碼”。 |
| BUFFER | 數(shù)據(jù)緩沖區(qū)大小。以字節(jié)為單位,一般在64000以上。 |
| FILE | 指定輸出文件的路徑和文件名。一般以.dmp為后綴名,注意該文件包括完整路徑,但是路徑必須存在,導(dǎo)出命令不能自動(dòng)創(chuàng)建路徑。 |
| COMPRESS | 是否壓縮導(dǎo)出,默認(rèn)yes。 |
| GRANTS | 是否導(dǎo)出權(quán)限,默認(rèn)yes |
| INDEXES | 是否導(dǎo)出索引,默認(rèn)yes |
| DIRECT | 是否直接導(dǎo)出,默認(rèn)情況,數(shù)據(jù)先經(jīng)過(guò)Oracle的數(shù)據(jù)緩沖區(qū),然后再導(dǎo)出數(shù)據(jù)。 |
| LOG | 指定導(dǎo)出命令的日志所在的日志文件的位置。 |
| ROWS | 是否導(dǎo)出數(shù)據(jù)行,默認(rèn)導(dǎo)出所有數(shù)據(jù)。 |
| CONSTRAINTS | 是否導(dǎo)出表的約束條件,默認(rèn)yes |
| PARFILE | 可以把各種參數(shù)配置為一個(gè)文本鍵值形式的文件,該參數(shù)可以指定參數(shù)文件的位置。 |
| TRIGGERS | 是否導(dǎo)出觸發(fā)器,默認(rèn)值是yes。 |
| TABLES | 表的名稱列表,導(dǎo)出多個(gè)表可以使用逗號(hào)隔開(kāi)。 |
| TABLESPACES | 導(dǎo)出某一個(gè)表空間的數(shù)據(jù)。 |
| Owner | 導(dǎo)出某一用戶的數(shù)據(jù)。 |
| Full | 導(dǎo)出數(shù)據(jù)庫(kù)的所有數(shù)據(jù)。默認(rèn)值是no。 |
| QUERY | 把查詢的結(jié)果導(dǎo)出。 |
表1? EXP參數(shù)說(shuō)明
?
代碼演示:exp的非交互環(huán)境
| D:\>exp scott/tiger file=employee.dmp tables=(emp,dept) Export: Release 10.2.0.3.0 - Production on 星期一 10月 19 17:38:25 2009 Copyright (c) 1982, 2005, Oracle.? All rights reserved. 連接到: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production With the Partitioning, OLAP and Data Mining options 已導(dǎo)出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集 即將導(dǎo)出指定的表通過(guò)常規(guī)路徑... . . 正在導(dǎo)出表???????????????????????????? EMP導(dǎo)出了????????? 14 行 . . 正在導(dǎo)出表??????????????????????????? DEPT導(dǎo)出了????????? 10 行 成功終止導(dǎo)出, 沒(méi)有出現(xiàn)警告。 D:\> |
?
3.???IMP導(dǎo)入
IMP程序?qū)刖褪前袳xp導(dǎo)出的文件重新導(dǎo)入到數(shù)據(jù)庫(kù)的過(guò)程。導(dǎo)入時(shí)也有一些重要的參數(shù):
???Fromuser:指出導(dǎo)出時(shí)dmp文件中記載的用戶信息。
???Touser:dmp文件要導(dǎo)入到什么目標(biāo)用戶中。
???Commit:默認(rèn)是N,在緩沖區(qū)滿時(shí)是否需要commit,如果設(shè)為N,需要較大的回滾段。
???Igore: Oracle在恢復(fù)數(shù)據(jù)的過(guò)程中,當(dāng)恢復(fù)某個(gè)表時(shí),該表已經(jīng)存在,就要根據(jù)ignore參數(shù)的設(shè)置來(lái)決定如何操作。若ignore=y,Oracle不執(zhí)行CREATE TABLE語(yǔ)句,直接將數(shù)據(jù)插入到表中,如果插入的記錄違背了約束條件,比如主鍵約束,則出錯(cuò)的記錄不會(huì)插入,但合法的記錄會(huì)添加到表中。若ignore=n,Oracle不執(zhí)行CREATE TABLE語(yǔ)句,同時(shí)也不會(huì)將數(shù)據(jù)插入到表中,而是忽略該表的錯(cuò)誤,繼續(xù)恢復(fù)下一個(gè)表。
?
代碼演示:Imp導(dǎo)入
| D:\>imp system/manager file=employee.dmp fromuser=scott touser=employee commit=y Import: Release 10.2.0.3.0 - Production on 星期一 10月 19 17:54:51 2009 Copyright (c) 1982, 2005, Oracle.? All rights reserved. 連接到: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production With the Partitioning, OLAP and Data Mining options 經(jīng)由常規(guī)路徑由 EXPORT:V10.02.01 創(chuàng)建的導(dǎo)出文件 警告: 這些對(duì)象由 SCOTT 導(dǎo)出, 而不是當(dāng)前用戶 已經(jīng)完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的導(dǎo)入 . 正在將 SCOTT 的對(duì)象導(dǎo)入到 EMPLOYEE . . 正在導(dǎo)入表?????????????????????????? "EMP"導(dǎo)入了????????? 14 行 . . 正在導(dǎo)入表????????????????????????? "DEPT"導(dǎo)入了????????? 10 行 即將啟用約束條件... 成功終止導(dǎo)入, 沒(méi)有出現(xiàn)警告。 D:\> |
?
4.???常見(jiàn)問(wèn)題
???數(shù)據(jù)庫(kù)對(duì)象已經(jīng)存在
一般情況,?導(dǎo)入數(shù)據(jù)前應(yīng)該徹底刪除目標(biāo)數(shù)據(jù)下的表,序列,函數(shù)/過(guò)程,觸發(fā)器等。
數(shù)據(jù)庫(kù)對(duì)象已經(jīng)存在,?按缺省的imp參數(shù),則會(huì)導(dǎo)入失敗。
如果用了參數(shù)ignore=y,會(huì)把exp文件內(nèi)的數(shù)據(jù)內(nèi)容導(dǎo)入。
如果表有唯一關(guān)鍵字的約束條件,不合條件將不被導(dǎo)入。
如果表沒(méi)有唯一關(guān)鍵字的約束條件,將引起記錄重復(fù)。
?
???數(shù)據(jù)庫(kù)對(duì)象有主外鍵約束
不符合主外鍵約束時(shí),數(shù)據(jù)會(huì)導(dǎo)入失敗。
解決辦法:?先導(dǎo)入主表,再導(dǎo)入依存表。
disable目標(biāo)導(dǎo)入對(duì)象的主外鍵約束,導(dǎo)入數(shù)據(jù)后,再enable它們。
?
???權(quán)限不夠
如果要把A用戶的數(shù)據(jù)導(dǎo)入B用戶下,?A用戶需要有imp_full_database權(quán)限。
?
???導(dǎo)入大表(?大于80M )?時(shí),存儲(chǔ)分配失敗
默認(rèn)的EXP時(shí),compress = Y,也就是把所有的數(shù)據(jù)壓縮在一個(gè)數(shù)據(jù)塊上。
導(dǎo)入時(shí),如果不存在連續(xù)一個(gè)大數(shù)據(jù)塊,則會(huì)導(dǎo)入失敗。
導(dǎo)出80M以上的大表時(shí),記得compress= N,則不會(huì)引起這種錯(cuò)誤。
?
???Imp和Exp使用的字符集不同
如果字符集不同,導(dǎo)入會(huì)失敗,可以改變unix環(huán)境變量或者NT注冊(cè)表里NLS_LANG相關(guān)信息。
?
???Imp和Exp版本不能往上兼容
Imp可以成功導(dǎo)入低版本Exp生成的文件,?不能導(dǎo)入高版本Exp生成的文件根據(jù)情況我們可以用。
?
?[D1]/?'str?kt??/ /'kw?r?/
?[D2]/,d?f?'n???n?/
?[D3]m??nipju?lei??n
?[D4]k?n?streint
?[D5]在創(chuàng)建數(shù)據(jù)庫(kù)表時(shí)可以指定一個(gè)?DEFAULT?值(即默認(rèn)值)。對(duì)數(shù)據(jù)庫(kù)字段使用默認(rèn)值有助于將數(shù)據(jù)庫(kù)設(shè)計(jì)問(wèn)題與應(yīng)用程序代碼隔離。
可以在以后某個(gè)時(shí)候通過(guò)一條?ALTER TABLE?命令改變一個(gè)字段的默認(rèn)值,改變之后應(yīng)用程序代碼會(huì)立即開(kāi)始使用新值。
有一點(diǎn)是很重要的,即?DEFAULT?值只有當(dāng)一個(gè)字段沒(méi)有在?INSERT?或?MERGE?中指定值,或者使用了?DEFAULT?關(guān)鍵字時(shí)才會(huì)使用。如果你不顯式地聲明一個(gè)?DEFULAT?值,Oracle?將隱式地將默認(rèn)值定義為?NULL,而且?DEFAULT?關(guān)鍵字也是這樣。從?Oracle 9i開(kāi)始,可以在?DEFAULT?子句中使用諸如?SYSDATE?或?CURRENT_TIMESTAMPE?之類的偽字段。
?[D6]主鍵約束:在表中定義一個(gè)主鍵來(lái)唯一確定表中每一行數(shù)據(jù)的標(biāo)識(shí)符。數(shù)據(jù)類型不限,但此列必須是唯一并且非空。
?[D7]CHECK?約束:定義列中可接受的數(shù)據(jù)值。可以將?CHECK?約束應(yīng)用于多個(gè)列,也可以將多個(gè)?CHECK?約束應(yīng)用于單個(gè)列。當(dāng)除去某個(gè)表時(shí),也將除去?CHECK?約束
?[D8]唯一約束保證在一個(gè)字段或者一組字段里的數(shù)據(jù)與表中其它行的數(shù)據(jù)相比是唯一的。
?[D9]可在創(chuàng)建字段之后CONSTRAINT PK_INFOS PRIMARY KEY (STUID)
?[D10]升序:ASC
??????????降序:DESC
?[D11]/tr???keit/v.??切去頭端, 截棱成平面, 縮短
?
?[D12]escape關(guān)鍵字經(jīng)常用于使某些特殊字符,如通配符'%','_'轉(zhuǎn)義為它們?cè)瓉?lái)的字符的意義,被定義的轉(zhuǎn)義字符通常使用'\',但是也可以使用其他的符號(hào)。?[D13]/,?nt?'s?kt/
?[D14]/'ma?n?s/減去,負(fù)的
總結(jié)
以上是生活随笔為你收集整理的《Oracle经典教程》的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python输出CSV乱码
- 下一篇: 流程图制作用这些软件,操作容易好上手