oracle數據庫進階教程

本文主要參考oracle數據庫經典學習教程,對數據庫的安裝、網絡配置不做說明。sql

1、走進oracle

總結:數據庫

Oracle 是基於對象的關係型數據庫,Oracle 產品免費,服務收費。編程

Oracle 安裝後默認會有兩個管理員用戶(system,sys)和一個普通用戶 Scott。數組

Sql*plus 是 Oracle 管理和數據操做的客戶端工具。瀏覽器

客戶端連接服務器前,服務器要啓動監聽服務,而且客戶端工具要安裝 Oracle 客 戶端,而且在客戶端要創建本地網絡服務名。緩存

Oracle 服務和監聽啓動後才能對數據庫進行操做。安全

用 startup 命令啓動數據庫,用 shutdown 命令關閉數據庫。服務器

Oracle 的角色包括了一系列系統權限和普通對象權限,能夠把權限受權給角色,把權限或者角色受權給用戶。網絡

注意:session

管理員用戶system的密碼爲oracle,sys的密碼爲change_on_install。使用plsql鏈接時,權限選擇爲sysdba.

 

1.oracle服務

OracleService+服務名,該服務是數據庫啓動的基礎,只有該服務啓動了,Oracle 數 據庫才能正常啓動。這是必須啓動的服務。

 OracleOraDb10g_home1TNSListener,該服務是服務器端爲客戶端提供的監聽服務, 只有該服務在服務器上正常啓動,客戶端才能鏈接到服務器。該監聽服務接收客戶 端發出的請求,而後將請求傳遞給數據庫服務器。一旦創建了鏈接,客戶端和數據 庫服務器就能直接通訊了。

OracleOraDb10g_home1iSQL*Plus,該服務提供了用瀏覽器對數據庫中數據操做的方 式。該服務啓動後,就可使用瀏覽器進行遠程登陸並進行數據庫操做了。

OracleDBConsole+服務名,Oracle10g 中的一個新服務。在 Oracle9i 以前,Oracle 官 方提供了一個基於圖形界面的企業管理器(EM),從 Oracle10g 開始,Oracle 提供了 一個基於 B/S 的企業管理器,在操做系統的命令行中輸入命令:emctl start dbconsole,就能夠啓動 OracleDbConsole 服務

服務啓動以後,就能夠在瀏覽器中輸入上圖中進入 EM 的地址,使用 B/S 方式管理 Oracle 服務器。

 

2. Oracle 用戶和權限

Oracle 中,通常不會輕易在一個服務器上建立多個數據庫,在一個數據庫中,不一樣的項 目由不一樣的用戶訪問,每個用戶擁有自身建立的數據庫對象,所以用戶的概念在 Oracle 中很是重要。Oracle 的用戶能夠用 CREATE USER 命令來建立。其語法是

語法結構:建立用戶

CREATE USER 用戶名 IDENTIFIED BY 口令 [ACCOUNT LOCK|UNLOCK]

語法解析:

 LOCK|UNLOCK 建立用戶時是否鎖定,默認爲鎖定狀態。鎖定的用戶沒法正常的登陸進 行數據庫操做。

儘管用戶成功建立,可是還不能正常的登陸 Oracle 數據庫系統,由於該用戶尚未任 何權限。若是用戶可以正常登陸,至少須要 CREATE SESSION 系統權限。 Oracle 用戶對數據庫管理或對象操做的權利,分爲系統權限數據庫對象權限。系統權限好比:CREATE SESSION,CREATE TABLE 等,擁有系統權限的用戶,容許擁有相應的系統操 做。數據庫對象權限,好比對錶中的數據進行增刪改操做等,擁有數據庫對象權限的用戶可 以對所擁有的對象進行對應的操做。

還有一個概念就是數據庫角色(role),數據庫角色就是若干個系統權限的集合。下面 介紹幾個經常使用角色:

 CONNECT 角色,主要應用在臨時用戶,特別是那些不須要建表的用戶,一般只賦予 他們 CONNECT role。CONNECT 是使用 Oracle 的簡單權限,擁有 CONNECT 角色的用 戶,能夠與服務器創建鏈接會話(session,客戶端對服務器鏈接,稱爲會話)。

RESOURCE 角色,更可靠和正式的數據庫用戶能夠授予 RESOURCE role。RESOURCE 提供給用戶另外的權限以建立他們本身的表、序列、過程(procedure)、觸發器 (trigger)、索引(index)等。

DBA 角色,DBA role 擁有全部的系統權限----包括無限制的空間限額和給其餘用戶授 予各類權限的能力。用戶 SYSTEM 擁有 DBA 角色。

 通常狀況下,一個普通的用戶(如 SCOTT),擁有 CONNECT 和 RESOURCE 兩個角色便可 進行常規的數據庫開發工做。

能夠把某個權限授予某個角色,能夠把權限、角色授予某個用戶。系統權限只能由 DBA 用戶受權,對象權限由擁有該對象的用戶受權,受權語法是:

語法結構:受權

GRANT角色|權限 TO 用戶(角色)

代碼演示:受權

SQL> GRANT CONNECT TO jerry;

受權成功。

SQL> GRANT RESOURCE TO jerry;

受權成功。

SQL>

 

語法結構:其餘操做

//回收權限

REVOKE 角色|權限 FROM 用戶(角色)

//修改用戶的密碼

ALTER USER 用戶名 IDENTIFIED BY 新密碼

//修改用戶處於鎖定(非鎖定)狀態

ALTER USER 用戶名 ACCOUNT LOCK|UNLOCK

 

 

2、SQL 數據操做和查詢

1. SQL 簡介

SQL 是結構化查詢語言(Structured Query Language),專門用於數據存取、數據更新及數據庫管理等操做。

在 Oracle 開發中,客戶端把 SQL 語句發送給服務器,服務器對 SQL 語句進行編譯、執

行,把執行的結果返回給客戶端。Oracle SQL 語句由以下命令組成:

數據定義語言(DDL,包括 CREATE(建立)命令、ALTER(修改)命令、DROP(刪

除)命令等。

數據操縱語言(DML,包括 INSERT(插入)命令、UPDATE(更新)命令、DELETE

(刪除)命令、SELECT … FOR UPDATE(查詢)等。

數據查詢語言(DQL,包括基本查詢語句、Order By 子句、Group By 子句等。

事務控制語言(TCL,包括 COMMIT(提交)命令、SAVEPOINT(保存點)命令、

ROLLBACK(回滾)命令。

數據控制語言(DCL,GRANT(受權)命令、REVOKE(撤銷)命令。

目前主流的數據庫產品(好比:SQL Server、Oracle)都支持標準的 SQL 語句。數據定義

語言,表的增刪改操做,數據的簡單查詢,事務的提交和回滾,權限的受權和撤銷等,Oracle

與 SQL Server 在操做上基本一致。

2. Oracle 數據類型

Oracle 數據庫的核心是表,表中的列使用到的常見數據類型以下:

 

CHAR(length)   存儲固定長度的字符串。參數 length 指定了長度,若是存儲的字符串長

度小於 length,用空格填充。默認長度是 1,最長不超過 2000 字節。

VARCHAR2(length)   存儲可變長度的字符串。length 指定了該字符串的最大長度。默認長度是 1,最長不超過 4000 字符。

NUMBER(p,s)   既能夠存儲浮點數,也能夠存儲整數,p 表示數字的最大位數(若是是

小數包括整數部分和小數部分和小數點,p 默認是 38 爲),s 是指小數位數。

DATE   存儲日期和時間,存儲紀元、4 位年、月、日、時、分、秒,存儲時間從公元前 4712 年 1 月 1 日到公元后 4712 年 12 月 31 日。

TIMESTAMP   不但存儲日期的年月日,時分秒,以及秒後 6 位,同時包含時區。

CLOB   存儲大的文本,好比存儲非結構化的 XML 文檔

BLOB   存儲二進制對象,如圖形、視頻、聲音等。

 

對應 NUMBER 類型的示例:

格式

輸入的數字

實際的存儲

NUMBER

1234.567

1234.567

NUMBER(6,2)

123.4567

123.46

NUMBER(4,2) 12345.67 輸入的數字超過了所指定的精度,數據庫不能存儲對於日期類型,可使用 sysdate 內置函數能夠獲取當前的系統日期和時間,返回 DATE

類型,用 systimestamp 函數能夠返回當前日期、時間和時區。

 

 

 

Oracle 的查詢中,必須使用「select 列… from 表」的完整語法,當查詢單行函數的時

候,from 後面使用 DUAL 表,dual 表在系統中只有一行一列,該表在輸出單行函數時爲了

select…from 的語法完整性而使用。

 

3. 建立表和約束

Oracle 建立表同 SQL Server 同樣,使用 CREATE TABLE 命令來完成。建立約束則使用以下

命令:

語法格式:ALTER TABLE 命令

 ALTER TABLE 表名 ADD CONSTRAINT 約束名 約束內容。

 

4. 數據操縱語言(DML)

數據操縱語言(DML)用於對數據庫的表中數據進行添加、修改、刪除和 SELECT…For

UPDATE(後面專門學習該查詢)操做。Oracle 中的操做。

簡單查詢

數據查詢是用 SELECT 命令從數據庫的表中提取信息。SELECT 語句的語法是:

語法結構:簡單查詢

SELECT *|列名|表達式 FROM 表名 WHERE 條件 ORDER BY 列名

語法解析:

1. *表示表中的全部列。

2. 列名能夠選擇若干個表中的列名,各個列表中間用逗號分隔。

3. 表達式能夠是列名、函數、常數等組成的表達式。

4. WHERE 子句是查詢的條件。

5. ORDER BY 要求在查詢的結果中排序,默認是升序。

 Oracle 中能夠把查詢的結果根據結果集中的表結構和數據造成一張新表。

語法結構:根據結果集建立表

CREATE TABLE 表名 AS SELECT 語句

代碼演示:根據結果集建立表

SQL> CREATE TABLE INFOS1 AS SELECT * FROM INFOS;

TABLE CREATED

使用上面命令建立的新表中,不存在任何約束,而且把查詢的數據一塊兒插入到新表中。

若是隻複製表結構,只需使查詢的條件不成立(好比 where 1=2),就不會查詢從出任何數

據,從而複製一個表結構。

代碼演示:複製表結構

SQL> CREATE TABLE INFOS2 AS SELECT * FROM INFOS WHERE 1=2;

TABLE CREATED

 

數據插入

用 INSERT 命令完成對數據的插入。

語法結構:數據插入

INSERT INTO 表名(列名 1,列名 2……) VALUES (值 1,值 2……)

語法解析:

1. 列名能夠省略。當省略列名時,默認是表中的全部列名,列名順序爲表定義中列的

前後順序。

2. 值的數量和順序要與列名的數量和順序一致。值的類型與列名的類型一致。

 

代碼演示:向 INFOS 表和 SCORES 表中插入數據

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; ④

代碼解析:

① 表名後面缺省了列名,默認是表 Infos 中的全部列名,values 中的值要與表中列一一

對應,包括順序和數據類型的對應。在 SQL*Plus 中一條語句能夠寫在多行,那麼從

第二行開始,sqlplus 會爲每一行前面給出行號。

② 在 Oracle 中,日期是國際化的,不一樣的區域安裝的數據庫,默認的日期格式不一樣,

所以爲了程序便於移植,日期的輸入要使用 TO_DATE 函數對日期格式化後輸入,採

用格式化字符串對日期進行格式化時,格式化字符串中字符不區分大小寫,常見的

格式化字符以下:

1. yyyy 表示四位年份

2. mm 表示兩位月份,好比 3 月表示爲 03

3. dd 表示兩位日期

4. hh24 表示小時從 0-23,hh12 也表示小時從 0-11。

5. mi 表示分鐘

6. ss 表示秒

③ 在遇到存在默認值的列時,可使用 default 值代替。

④ commit 是把用戶操做(添加、刪除、修改操做)提交,只有提交操做後,數據才

能真正更新到表中,不然其餘用戶沒法查詢到當前用戶操做的結果。

 

 

在 Oracle 中,一個 INSERT 命令能夠把一個結果集一次性插入到一張表中。使用的語句

是:INSERT INTO 表 SELECT 子句,以下示例:

代碼演示:INSERT 向表中插入一個結果集

SQL> INSERT INTO INFOS2 SELECT * FROM INFOS;

5 rows inserted

在這種語法下,要求結果集中每一列的數據類型必須與表中的每一列的數據類型一致,

結果集中的列的數量與表中的列的數量一致。好比表 INFOS2,該表的結構與 INFO 表同樣,

那麼能夠把 INFO 表中的全部記錄一次性插入到 INFOS2 表中。

Oracle 的簡單查詢和 SQL Server 同樣均可以在查詢列中使用常量,

 

 

代碼演示:INSERT 向表中插入一個常量結果集

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;

更新數據

Oracle 在表中更新數據的語法是:

語法結構:UPDATE 操做

UPDATE 表名 SET 列名 1=值,列名 2=值…… WHERE 條件

代碼演示:UPDATE 操做

SQL> UPDATE INFOS SET CLASSNO='1002',STUADDRESS='山東萊蕪'

WHERE STUNAME='阮小二';

1 rows updated

SQL> commit;

 

刪除數據

Oracle 在表中刪除數據的語法是:

語法結構:DELETE 操做

DELETE FROM 表名 WHERE 條件

代碼演示:DELETE 操做

SQL> DELETE FROM INFOS WHERE STUID='s100103';

1 ROW DELETED

SQL> COMMIT;

 

TRUNCATE

在數據庫操做中, TRUNCATE 命令(是一個 DDL 命令)能夠把表中的全部數據一次性

所有刪除,語法是:

語法結構:TRUNCATE

TRUNCATE TABLE 表名

TRUNCATE 和 DELETE 都能把表中的數據所有刪除,他們的區別是:

1. TRUNCATE 是 DDL 命令,刪除的數據不能恢復;DELETE 命令是 DML 命令,刪除後

的數據能夠經過日誌文件恢復。

2. 若是一個表中數據記錄不少,TRUNCATE 相對 DELETE 速度快。

因爲 TRUNCATE 命令比較危險,所以在實際開發中,TRUNCATE 命令慎用。

 

5. 操做符

Oracle 開發中,依然存在算術運算,關係運算,和邏輯運算。

算術運算

Oracle 中的算術運算符,沒有 C#中的算術運算符豐富,只有+、-、*、/四個,其中除號

(/)的結果是浮點數。求餘運算只能藉助函數:MOD(x,y):返回 x 除以 y 的餘數。

 

案例 3:每名員工年終獎是 2000 元,請顯示基本工資在 2000 元以上的員工的月工資,

年總工資。

該案例的表請參見scott用戶,本章練習的附表 一、附表 二、附表 3,這三張表是 ORACLE 10g 自帶的。

代碼演示:查詢中的算術運算

SQL> SELECT ENAME,SAL,(SAL*12+2000) FROM EMP WHERE SAL>2000;

關係運算和邏輯運算

Oracle 中 Where 子句經中常常見到關係運算和邏輯運算,常見的關係運算有:

Oracle 默認安裝中,已經建立了一個 SCOTT 用戶,默認密碼是:tiger,該用戶下有四

張表分別是:僱員表(EMP),部門表(DEPT),工資登記表和獎金錶,接下來不少操做都是在該用戶下完成的。

Oracle 的關係運算符:

運算符

說明

運算符

說明

=

等於

大於

<>或者!=

不等於

<=

小於或者等於

小於

>=

大於或者等於

邏輯運算符有三個:AND、OR、NOT

 

字符串鏈接操做符(||)

在 Oracle 中,字符串的鏈接用雙豎線(||)表示。好比,在 EMP 表中,查詢工資在 2000

元以上的姓名以及工做。

代碼演示:字符串鏈接

SQL> SELECT (ENAME || 'is a ' || JOB) AS "Employee Details" ① FROM EMP WHERE SAL>2000;

注意:as 能夠省略,可是as後邊的內容不能使用單引號

代碼解析: ① Oracle 中字符串能夠用單引號,也能夠用雙引號,在別名中存在空格時,必須用雙 引號。在表名、列名時用雙引號。

 

6. 高級查詢

消除重複行

在 Oracle 查詢中結果中,可能出現若干行相同的狀況,那麼可使用 DISTINCT 消除重

復行。具體的用法如示例:

代碼演示:DISTINCT 消除重複行

SQL> SELECT DISTINCT DEPTNO FROM EMP;

 

NULL 操做

若是某條記錄中有缺乏的數據值,就是空值(NULL 值)。空值不等於 0 或者空格,空值

是指未賦值、未知或不可用的值。任何數據類型的列均可以包括 NULL 值,除非該列被定義

爲非空或者主鍵。

代碼演示:EMP 中的 NULL 值

SQL> SELECT ENAME,JOB,SAL,COMM FROM EMP WHERE SAL<2000;

 

在查詢條件中 NULL 值用 IS NULL 做條件,非 NULL 值用 NOT IS NULL 作條件。

案例 4:查詢 EMP 表中沒有發獎金的員工。

代碼演示:NULL 值查詢

SQL> SELECT ENAME,JOB,SAL,COMM FROM EMP WHERE SAL<2000 AND COMM IS NULL;

 IN 操做

在 Where 子句中可使用 IN 操做符來查詢其列值在指定的列表中的行。好比:查詢出

工做職責是 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  WHERE job IN ('SALESMAN', 'PRESIDENT', 'ANALYST');

對應 IN 操做的還有 NOT IN,用法同樣,結果相反

BETWEEN…AND…

在 WHERE 子句中,可使用 BETWEEN 操做符來查詢列值包含在指定區間內的行。比

如,查詢工資從 1000 到 2000 之間的員工。可使用傳統方法:

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;

 

LIKE 模糊查詢

字符匹配操做可使用通配符「%」和「_」:

 %:表示零個或者多個任意字符。

 _:表明一個任意字符。

語法是:LIKE '字符串'[ESCAPE '字符']。匹配的字符串中,ESCAPE 後面的「字符」做爲轉

義字符。

通配符表達式

說明

'S%'

以S開頭的字符串。

'_S%'

第二個字符時S的字符串。

'%30\%%' escape '\'

包含「30%」的字符串,「\」指轉義字符,「\%」在字符串中表示一個字符「%」。

案例 5:顯示員工名稱以 J 開頭以 S 結尾的員工的姓名和工資。

代碼演示:LIKE 操做

SQL> SELECT ENAME,JOB,SAL FROM EMP WHERE ENAME LIKE 'J%S';

 

集合運算

集合運算就是將兩個或者多個結果集組合成爲一個結果集。集合運算包括:

 INTERSECT(交集),返回兩個查詢共有的記錄。

 UNION ALL(並集),返回各個查詢的全部記錄,包括重複記錄。

 UNION(並集),返回各個查詢的全部記錄,不包括重複記錄。

 MINUS(補集),返回第一個查詢檢索出的記錄減去第二個查詢檢索出的記錄以後剩

餘的記錄。

當使用集合操做的時候,要注意:查詢所返回的列數以及列的類型必須匹配,列名能夠

不一樣。

案例 6:查詢出 dept 表中哪一個部門下沒有員工。只需求出 dept 表中的部門號和 emp

表中的部門號的補集便可。

代碼演示:求補運算

SQL> SELECT DEPTNO FROM DEPT MINUS SELECT DEPTNO FROM EMP;

 

前面學習過能夠經過 insert into …select 把一個結果集插入到另外一張結構相同的表中,因

此可使用 union 把若干條記錄一次性插入到一張表中。

代碼演示:用 union 插入多條數據

SQL> INSERT INTO DEPT

  SELECT 50,'公關部','臺灣' FROM DUAL

  UNION

  SELECT 60,'研發部','西安' FROM DUAL

  UNION

  SELECT 70,'培訓部','西安' FROM DUAL

 

鏈接查詢

在 SQL Server 中已經學習過內聯接(inner join)、外聯接(outer join),外聯接又分爲左外聯

接(left outer join)和右外聯接(right outer join)。Oracle 中對兩個表或者若干表之間的外聯接用

(+)表示。

案例 7:請查詢出工資大於 2000 元的,員工姓名,部門,工做,工資。

因爲部門名稱在 dept 中,其餘的信息在 emp 表中,須要內聯接才能完成。

代碼演示:內聯接

SQL> SELECT e.ENAME,e.JOB,e.SAL,d.DNAME

 FROM emp e,dept d

 WHERE e.deptno=d.deptno

 AND e.SAL>2000;

內聯接

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 中,關鍵字 INNER 能夠省略。

 

請查詢出每一個部門下的員工姓名,工資。

案例分析:

Emp 表用外鍵 deptno 引用 Dept 表中的 deptno,在 Dept 表中若是有某些部門沒有員工,

那麼用內聯接,沒有員工的部門將沒法顯示,所以必須以 Dept 表爲基準的外聯接。

代碼演示:外聯接

SQL> SELECT e.ENAME,e.JOB,e.SAL,d.DNAME

  FROM EMP e ,DEPT d

  WHERE e.DEPTNO(+)=d.DEPTNO ①

代碼解析:

① (+):Oracle 專用的聯接符,在條件中出如今左邊指右外聯接,出如今右邊指左外

聯接。

也可使用 SQL/92 標準的寫法:

代碼演示:外聯接

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 中,關鍵字 OUTER 能夠省略。

 

3、子查詢和經常使用函數

1. 子查詢

子查詢在 SELECT、UPDATE、DELETE 語句內部能夠出現 SELECT 語句。內部的 SELECT 語

句結果能夠做爲外部語句中條件子句的一部分,也能夠做爲外部查詢的臨時表。子查詢的類

型有:

1. 單行子查詢:不向外部返回結果,或者只返回一行結果。

2. 多行子查詢:向外部返回零行、一行或者多行結果。

 

案例 1:查詢出銷售部(SALES)下面的員工姓名,工做,工資。

案例分析

該問題能夠用聯接查詢實現,因爲所需的結果信息都在 Emp 表中,能夠先從 Dept 表中

查詢出銷售部對應的部門號,而後根據當前部門號再到 Emp 表中查詢出符合該部門的員工

記錄便可。從銷售表中查詢出的結果能夠做爲 Emp 表中查詢的條件,SQL 語句實現以下:

代碼演示:單行子查詢

SQL> SELECT ENAME,JOB,SAL FROM EMP

 2 WHERE DEPTNO=(SELECT DEPTNO FROM DEPT WHERE DNAME='SALES') ①

代碼解析:

① 內部查詢的結果做爲外部查詢的條件。

須要注意:

 若是內部查詢不返回任何記錄,則外部條件中字段 DEPTNO 與 NULL 比較永遠爲假,

也就是說外部查詢不返還任何結果。

 在單行子查詢中外部查詢可使用=、>、<、>=、<=、<>等比較運算符。

 內部查詢返回的結果必須與外部查詢條件中的字段(DEPTNO)匹配。

 若是內部查詢返回多行結果則出現錯誤。

 

案例二:查詢出 Emp 表中比任意一個銷售員(「SALESMAN」)工資低的員工姓名、工做、

工資。

案例分析

銷售員在 Emp 表中有不少條記錄,每一個人工資不相等,若是返回「比任意員工的工資

還低」的條件,返回比「最高工資還低」便可。若是用子查詢作,子查詢中就會返回多條記

錄。用普通的關係符(>、<等)運行就會出錯。這時候須要用關鍵字 ANY。ANY 放在比較運算符後面,表示「任意」的意思。

代碼演示:ANY 子查詢

SQL> SELECT ENAME,JOB,SAL FROM EMP

 2 WHERE SAL<ANY (SELECT SAL FROM EMP WHERE JOB='SALESMAN') ①

代碼解析:

①    <any:比子查詢結果中任意的值都小,也就是說,比子查詢結果中最大值還小,那麼

同理>any 表示比子查詢結果中最小的還大。

 

案例 3:查詢出比全部銷售員的工資都高的員工姓名,工做,工資。

案例分析

ANY 能夠表示任意的,但本案例中要求比全部銷售員工資都高,那麼就要使用另一個

關鍵字 ALL。ALL 與關係操做符一塊兒使用,表示與子查詢中全部元素比較。

代碼演示:ALL 子查詢

SQL> SELECT ENAME,JOB,SAL FROM EMP

 2 WHERE SAL>ALL (SELECT SAL FROM EMP WHERE JOB='SALESMAN') ①

代碼解析:

① >ALL:比子查詢結果中最大值還要大。

<ALL 表示比最小值還要小。

對於子查詢還可使用 IN 和 NOT IN 操做符進行操做。

 

2. Oracle 中的僞列

在 Oracle 的表的使用過程當中,實際表中還有一些附加的列,稱爲僞列。僞列就像表中

的列同樣,可是在表中並不存儲。僞列只能查詢,不能進行增刪改操做。接下來學習兩個僞

列:ROWID 和 ROWNUM。

ROWID

表中的每一行在數據文件中都有一個物理地址,ROWID 僞列返回的就是該行的物理地

址。使用 ROWID 能夠快速的定位表中的某一行。ROWID 值能夠惟一的標識表中的一行。由

於 ROWID 返回的是該行的物理地址,所以使用 ROWID 能夠顯示行是如何存儲的。

代碼演示:ROWID

SQL> SELECT ROWID,ENAME FROM EMP WHERE SAL>2000;

ROWNUM

在查詢的結果集中,ROWNUM 爲結果集中每一行標識一個行號,第一行返回 1,第二

行返回 2,以此類推。經過 ROWNUM 僞列能夠限制查詢結果集中返回的行數。

案例 4:查詢出員工表中前 5 名員工的姓名,工做,工資。

代碼演示:ROWNUM

SQL> SELECT ROWNUM,ENAME,JOB,SAL FROM EMP WHERE ROWNUM<=5;

 

注意:ROWNUM 與 ROWID 不一樣,ROWID 是插入記錄時生成,ROWNUM 是查詢數據時生成。

ROWID 標識的是行的物理地址。ROWNUM 標識的是查詢結果中的行的次序。

 

案例 5:查詢出工資最高的前 5 名員工的姓名、工資和工資。

案例分析

「工資最高的前 5 名」須要先降序排序,再取前 5 名,可是生成 ROWNUM 操做比排序

要早,排序時已經連同 ROWNUM 一塊兒排序了,所以不能直接在案例 1 的語句中直接加上

Order by 就行,而是須要對排序的結果從新作二次查詢,產生新的 ROWNUM 才能做爲查詢

的條件依據。

代碼演示:ROWNUM 應用

SQL> SELECT ROWNUM,T.* FROM ①

(SELECT ENAME,JOB,SAL

    FROM EMP ORDER BY SAL DESC) T ②

    WHERE ROWNUM<=5

 

代碼解析: ① T 是子查詢②的別名,這裏的 ROWNUM 是第二次查詢後的 ROWNUM。

 

案例 6:查詢出表 EMP 中第 5 條到第 10 條之間的記錄。

案例分析

這是分頁的應用。在查詢條件中,若是查詢條件中 ROWNUM 大於某一正整數,則不返

還任何結果。

代碼演示:ROWNUM 分頁

SQL> SELECT * FROM

 2 (SELECT ROWNUM R,ENAME,JOB,SAL ①

 3 FROM EMP WHERE ROWNUM<=10) ②

 4 WHERE R>5 ③

 

代碼解析:

① 內部查詢中獲得 ROWNUM 而且用別名 R 記錄,供外層條件③使用。

② 內部查詢的 ROWNUM,與外出的 ROWNUM 列是平等的兩列。

③ 使用的 R 是內層產生的 ROWNUM,在外層看來,內層查詢的 ROWNUM 是正常的一

列。

 

注意:SELECT  ROWNUM R,ENAME,JOB,SAL FROM EMP WHERE ROWNUM>=5這樣查不出任何內容

3. Oracle 函數

Oracle 數據庫中主要使用兩種

類型的函數:

1. 單行函數:對每個函數應用在表的記錄中時,只能輸入一行結果,返回一個結果,

好比:MOD(x,y)返回 x 除以 y 的餘數(x 和 y 能夠是兩個整數,也能夠是表中的整

數列)。經常使用的單行函數有:

 字符函數:對字符串操做。

 數字函數:對數字進行計算,返回一個數字。

 轉換函數:能夠將一種數據類型轉換爲另一種數據類型。

 日期函數:對日期和時間進行處理。

2. 聚合函數:聚合函數同時能夠對多行數據進行操做,並返回一個結果。好比 SUM(x)

返回結果集中 x 列的總合。

字符函數

字符函數接受字符參數,這些參數能夠是表中的列,也能夠是一個字符串表達式。下表

列出了經常使用的字符函數。

 

 

數字函數

數字函數接受數字參數,參數能夠來自表中的一列,也能夠是一個數字表達式。

 

日期函數

日期函數對日期進行運算。經常使用的日期函數有:

1. ADD_MONTHS(d,n),在某一個日期 d 上,加上指定的月數 n,返回計算後的新日期。

d 表示日期,n 表示要加的月數

 

2.LAST_DAY(d),返回指定日期當月的最後一天。

 

3. ROUND(d[,fmt]),返回一個以 fmt 爲格式的四捨五入日期值,d 是日期,fmt 是格式

模型。默認 fmt 爲 DDD,即月中的某一天。

 若是 fmt 爲「YEAR」則舍入到某年的 1 月 1 日,即前半年捨去,後半年做爲下

一年。

 若是 fmt 爲「MONTH」則舍入到某月的 1 日,即前月捨去,後半月做爲下一

月。

 默認爲「DDD」,即月中的某一天,最靠近的天,前半天捨去,後半天做爲第

二天。

 若是 fmt 爲「DAY」則舍入到最近的周的週日,即上半周捨去,下半周做爲下

一週週日。

 

與 ROUND 對應的函數時 TRUNC(d[,fmt])對日期的操做,TRUNC 與 ROUND 很是類似,只 是不對日期進行舍入,直接截取到對應格式的第一天。

 

4. EXTRACT(fmt FROM d),提取日期中的特定部分。

fmt 爲:YEAR、MONTH、DAY、HOUR、MINUTE、SECOND。其中 YEAR、MONTH、DAY

能夠爲 DATE 類型匹配,也能夠與 TIMESTAMP 類型匹配;可是 HOUR、MINUTE、SECOND 必

須與 TIMESTAMP 類型匹配。

HOUR 匹配的結果中沒有加上時區,所以在中國運行的結果小 8 小時。

select sysdate "date",

       EXTRACT(YEAR from sysdate) "year",

       EXTRACT(MONTH from sysdate) "month",

       EXTRACT(DAY from sysdate) "day",

       EXTRACT(HOUR from systimestamp) "hour",

       EXTRACT(MINUTE from systimestamp) "minute",

       EXTRACT(SECOND from systimestamp) "second"

 from dual

 

 

轉換函數

轉換函數將值從一種數據類型轉換爲另一種數據類型。經常使用的轉換函數有:

1. TO_CHAR(d|n[,fmt])

把日期和數字轉換爲制定格式的字符串。fmt 是格式化字符串,日期的格式化字符串前

面已經學習過。

代碼演示:TO_CHAR 對日期的處理

SQL> SELECT TO_CHAR(SYSDATE,'YYYY"年"MM"月"DD"日" HH24:MI:SS') "date" ①

 2 FROM DUAL;

date

-----------------------

2009年08月11日 12:06:00

代碼解析:

①            在格式化字符串中,使用雙引號對非格式化字符進行引用。

 

針對數字的格式化,格式化字符有:

 

代碼演示:TO_CHAR 對數字的處理

SQL> SELECT TO_CHAR(-123123.45,'L9.9EEEEPR') "date" FROM DUAL

<¥1.2E+05>

 

 

2. TO_DATE(x [,fmt])

把一個字符串以 fmt 格式轉換爲一個日期類型。

3. TO_NUMBER(x[,fmt])

把一個字符串以 fmt 格式轉換爲一個數字。fmt 格式字符參考表 3。

代碼演示:TO_NUM 函數

SQL> SELECT TO_NUMBER('-$12,345.67','$99,999.99') "NUM"

 2 FROM DUAL

 3 /

 NUM

---------------

-12345.67

其餘單行函數

1. NVL(x,value)

若是 x 爲空,返回 value,不然返回 x。

案例 7:對工資是 2000 元如下的員工,若是沒有發獎金,每人獎金 100 元。

代碼演示:NVL 函數

SQL> SELECT ENAME,JOB,SAL,NVL(COMM,100) FROM EMP WHERE SAL<2000;

2. NVL2(x,value1,value2)

若是 x 非空,返回 value1,不然返回 value2。

案例 8:對 EMP 表中工資爲 2000 元如下的員工,若是沒有獎金,則獎金爲 200 元,如

果有獎金,則在原來的獎金基礎上加 100 元。

代碼演示:NVL2 函數

SQL> SELECT ENAME,JOB,SAL,NVL2(COMM,comm+100,200) "comm"

 2 FROM EMP WHERE SAL<2000;

 

 

 

聚合函數

聚合函數同時對一組數據進行操做,返回一行結果,好比計算一組數據的總和,平均值

等。

 

案例 9:求本月全部員工的基本工資總和。

代碼演示:SUM 函數

SQL> select sum(sal) from emp;

 

案例 10:求不一樣部門的平均工資。

代碼演示:AVG 函數下的分組查詢

SQL> SELECT DEPTNO,AVG(SAL) FROM EMP GROUP BY DEPTNO;

 

4、表空間、數據庫對象

1. Oracle 數據庫對象

數據庫對象是數據庫的組成部分,經常用 CREATE 命令進行建立,可使用 ALTER 命令

修改,用 DROP 執行刪除操做。前面已經接觸過的數據庫對象有表、用戶等。

今天將學習更多的 Oracle 數據庫對象:

 同義詞:就是給數據庫對象一個別名。

 序列:Oracle 中實現增加的對象。

 視圖:預約義的查詢,做爲表同樣的查詢使用,是一張虛擬表。

 索引:對數據庫表中的某些列進行排序,便於提升查詢效率。

2. 同義詞

同義詞(Synonym)是數據庫對象的一個別名,Oracle 能夠爲表、視圖、序列、過程、

函數、程序包等指定一個別名。同義詞有兩種類型:

 私有同義詞:擁有 CREATE SYNONYM 權限的用戶(包括非管理員用戶)便可建立私

有同義詞,建立的私有同義詞只能由當前用戶使用。

 公有同義詞:系統管理員能夠建立公有同義詞,公有同義詞能夠被全部用戶訪問。

建立同義詞的語法是:

語法結構:同義詞

CREATE [OR REPLACE] [PUBLIC] SYSNONYM [schema.]synonym_name

FOR [schema.]object_name

如:CREATE SYNONYM MyEmp FOR SCOTT.EMP;

語法解析:

① CREATE [OR REPLACE:]表示在建立同義詞時,若是該同義詞已經存在,那麼就用新

建立的同義詞代替舊同義詞。

② PULBIC:建立公有同義詞時使用的關鍵字,通常狀況下不須要建立公有同義詞。

③ Oracle 中一個用戶能夠建立表、視圖等多種數據庫對象,一個用戶和該用戶下的所

有數據庫對象的集合稱爲 Schema(中文稱爲模式或者方案),用戶名就是 Schema

名。一個數據庫對象的全稱是:用戶名.對象名,即 schema.object_name。

 

若是一個用戶有權限訪問其餘用戶對象時,就可使用全稱來訪問。好比:

代碼演示:System 用戶訪問 Scott 用戶的 Emp 表

SQL> SELECT ENAME,JOB,SAL FROM SCOTT.EMP WHERE SAL>2000; ①

代碼解析: ① 管理員用戶能夠訪問任何用戶的數據庫對象,SYSTEM 用戶訪問 SCOTT 用戶的 EMP 表時,必須使用 SCOTT.EMP。

 

案例 1:建立一個用戶 XiaoMei,該用戶擁有 CONNECT 角色和 RESOURCE 角色。爲 SCOTT

用戶的 EMP 表建立同義詞,並經過同義詞訪問該 EMP 表。

 

代碼演示:建立同義詞並訪問

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; ⑤

代碼解析:

① 在管理員用戶下建立用戶 XiaoMei,對用戶 XiaoMei 授予 CONNECT 和 RESOURCE 角

色。爲了 XiaoMei 可以建立序列,必須授予系統權限:CREATE SYNONYM。

② 在 XiaoMei 用戶下,爲 SCOTT.EMP 建立私有同義詞 MyEmp,同義詞 MyEmp 只能在

XiaoMei 用戶下使用。訪問 MyEmp 就是訪問 SCOTT.EMP 對象。

③ 訪問 MyEmp 對象出錯:對象不存在。由於 XiaoMei 若是訪問 MyEmp,就至關於訪

問 SCOTT.EMP 對象,那麼 SCOTT 用戶必須對 XiaoMei 授予相應的權限。

④ SCOTT 用戶下,把 EMP 表的全部權限(增刪改查)授予 XiaoMei。

⑤ 對 MyEmp 執行查詢操做。MyEmp 就能夠像在本地的表同樣使用。

 

 

刪除同義詞使用的語法是:

語法結構:刪除同義詞

DROP [PUBLIC] SYNONYM [schema.]sysnonym_name

語法解析:

① PUBLIC:刪除公共同義詞。

②    同義詞的刪除只能被擁有同義詞對象的用戶或者管理員刪除。

③    此命令只能刪除同義詞,不能刪除同義詞下的源對象。

 

3. 序列

序列(Sequence)是用來生成連續的整數數據的對象。序列經常用來做爲主鍵中增加列,

序列中的能夠升序生成,也能夠降序生成。建立序列的語法是:

語法結構:建立序列

CREATE SEQUENCE sequence_name

[START WITH num]

[INCREMENT BY increment]

[MAXVALUE num|NOMAXVALUE]

[MINVALUE num|NOMINVALUE]

[CYCLE|NOCYCLE]

[CACHE num|NOCACHE]

語法解析:

① START WITH:從某一個整數開始,升序默認值是 1,降序默認值是-1。

② INCREMENT BY:增加數。若是是正數則升序生成,若是是負數則降序生成。升序默

認值是 1,降序默認值是-1。

③ MAXVALUE:指最大值。

④ NOMAXVALUE:這是最大值的默認選項,升序的最大值是:1027,降序默認值是-1。

⑤ MINVALUE:指最小值。

⑥ NOMINVALUE:這是默認值選項,升序默認值是 1,降序默認值是-1026。

⑦ CYCLE:表示若是升序達到最大值後,從最小值從新開始;若是是降序序列,達到最

小值後,從最大值從新開始。

⑧ NOCYCLE:表示不從新開始,序列升序達到最大值、降序達到最小值後就報錯。默

認 NOCYCLE。

⑨ CACHE:使用 CACHE 選項時,該序列會根據序列規則預生成一組序列號。保留在內

存中,當使用下一個序列號時,能夠更快的響應。當內存中的序列號用完時,系統

再生成一組新的序列號,並保存在緩存中,這樣能夠提升生成序列號的效率。Oracle

默認會生產 20 個序列號。

⑩ NOCACHE:不預先在內存中生成序列號

 

案例 2:建立一個從 1 開始,默認最大值,每次增加 1 的序列,要求 NOCYCLE,緩存中

有 30 個預先分配好的序列號。

代碼演示:生成序列號

SQL> CREATE SEQUENCE MYSEQ

  MINVALUE 1

  START WITH 1

  NOMAXVALUE

  INCREMENT BY 1

  NOCYCLE

  CACHE 30

序列建立以後,能夠經過序列對象的 CURRVAL 和 NEXTVAL 兩個「僞列」分別訪問該序

列的當前值和下一個值。

代碼演示:序列使用

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 能夠修改序列,在修改序列時有以下限制:

1. 不能修改序列的初始值。

2. 最小值不能大於當前值。

3. 最大值不能小於當前值。

 

使用 DROP SEQUENCE 命令能夠刪除一個序列對象。

 

代碼演示:序列修改和刪除

SQL> ALTER SEQUENCE MYSEQ

 MAXVALUE 10000

MINVALUE -300

SEQUENCE ALTERED

 

SQL> DROP SEQUENCE MYSEQ;

SEQUENCE DROPPED

 

4. 視圖

視圖(View)其實是一張或者多張表上的預約義查詢,這些表稱爲基表。從視圖中

查詢信息與從表中查詢信息的方法徹底相同。只須要簡單的 SELECT…FROM 便可。

視圖具備如下優勢:

1. 能夠限制用戶只能經過視圖檢索數據。這樣就能夠對最終用戶屏蔽建表時底層的基

表。

2. 能夠將複雜的查詢保存爲視圖。能夠對最終用戶屏蔽必定的複雜性。

3. 限制某個視圖只能訪問基表中的部分列或者部分行的特定數據。這樣能夠實現必定

的安全性。

4. 從多張基表中按必定的業務邏輯抽出用戶關心的部分,造成一張虛擬表。

 

語法結構:建立視圖

CREATE [OR REPLACE] [{FORCE|NOFORCE}] VIEW view_name

AS

SELECT查詢

[WITH READ ONLY CONSTRAINT]

語法解析:

1. OR REPLACE:若是視圖已經存在,則替換舊視圖。

2. FORCE:即便基表不存在,也能夠建立該視圖,可是該視圖不能正常使用,當基表

建立成功後,視圖才能正常使用。

3. NOFORCE:若是基表不存在,沒法建立視圖,該項是默認選項。

4. WITH READ ONLY:默承認以經過視圖對基表執行增刪改操做,可是有不少在基表上

的限制(好比:基表中某列不能爲空,可是該列沒有出如今視圖中,則不能經過視

圖執行 insert 操做),WITH READ ONLY 說明視圖是隻讀視圖,不能經過該視圖進行

增刪改操做。現實開發中,基本上不經過視圖對錶中的數據進行增刪改操做。

 

 

案例 3:基於 EMP 表和 DEPT 表建立視圖

代碼演示:視圖

SQL> CREATE OR REPLACE VIEW EMPDETAIL

  AS

  SELECT EMPNO,ENAME,JOB,HIREDATE,EMP.DEPTNO,DNAME

  FROM EMP JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO

  WITH READ ONLY

 

代碼解析:

①            對視圖能夠像表同樣進行查詢。該視圖中隱藏了員工的工資。

刪除視圖可使用「DROP VIEW 視圖名稱」,刪除視圖不會影響基表的數據。

 

5. 索引

數據庫中索引(Index)的概念與目錄的概念很是相似。若是某列出如今查詢的條件中,

而該列的數據是無序的,查詢時只能從第一行開始一行一行的匹配。建立索引就是對某些特

定列中的數據排序,生成獨立的索引表。在某列上建立索引後,若是該列出如今查詢條件中,

Oracle 會自動的引用該索引,先從索引表中查詢出符合條件記錄的 ROWID,因爲 ROWID 是

記錄的物理地址,所以能夠根據 ROWID 快速的定位到具體的記錄,表中的數據很是多時,

引用索引帶來的查詢效率很是可觀。

 

若是表中的某些字段常常被查詢並做爲查詢的條件出現時,就應該考

慮爲該列建立索引。

當從不少行的表中查詢少數行時,也要考慮建立索引。有一條基本的準則是:當任何單個查詢要檢索的行少於或者等於整個錶行數的 10%時,索引就很是有用。

Oracle 數據庫會爲表的主鍵和包含惟一約束的列自動建立索引。索引能夠提升查詢的效 率,可是在數據增刪改時須要更新索引,所以索引對增刪改時會有負面影響。

語法結構:建立索引

CREATE [UNIQUE] INDEX index_name ON

table_name(column_name[,column_name…])

語法解析:

1. UNIQUE:指定索引列上的值必須是惟一的。稱爲惟一索引。

2. index_name:指定索引名。

3. tabl_name:指定要爲哪一個表建立索引。

4. column_name:指定要對哪一個列建立索引。咱們也能夠對多列建立索引;這種索引

稱爲組合索引。

 

案例 4:爲 EMP 表的 ENAME 列建立建立惟一索引,爲 EMP 表的工資列建立普通索引,

把 JOB 列先變爲小寫再建立索引。

代碼演示:建立索引

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 列建立惟一索引。

② 爲 SCOTT.EMP 表的 SAL 列建立索引。

③ 在查詢中可能常用 job 的小寫做爲條件的表達式,所以建立索引時,能夠先對

JOB 列中的全部值轉換爲小寫後建立索引,而這時須要使用 lower 函數,這種索引

稱爲基於函數的索引。

 

在 select 語句查詢時,Oracle 系統會自動爲查詢條件上的列應用索引。索引就是對某一

列進行排序,所以在索引列上,重複值越少,索引的效果越明顯。

Oracle 能夠爲一些列值重複很是多且值有限的列(好比性別列)上建立位圖索引。關於

Oracle 更多的索引類型(好比反向鍵索引等),請參考 Oracle 官方文檔。

6. 表空間

在數據庫系統中,存儲空間是較爲重要的資源,合理利用空間,不但能節省空間,還可

以提升系統的效率和工做性能。Oracle 能夠存放海量數據,全部數據都在數據文件中存儲。

而數據文件大小受操做系統限制,而且過大的數據文件對數據的存取性能影響很是大。同時

Oracle 是跨平臺的數據庫,Oracle 數據能夠輕鬆的在不一樣平臺上移植,那麼如何才能提供統

一存取格式的大容量呢?Oracle 採用表空間來解決。

表空間只是一個邏輯概念,若干操做系統文件(文件能夠不是很大)能夠組成一個表空

間。表空間統一管理空間中的數據文件,一個數據文件只能屬於一個表空間。一個數據庫空

間由若干個表空間組成。如圖所示:

 

Oracle 中全部的數據(包括系統數據),所有保存在表空間中,常見的表空間有:

 系統表空間:存放系統數據,系統表空間在數據庫建立時建立。表空間名稱爲

SYSTEM。存放數據字典和視圖以及數據庫結構等重要系統數據信息,在運行時如

果 SYSTEM 空間不足,對數據庫影響會比較大,雖然在系統運行過程當中能夠經過命

令擴充空間,但仍是會影響數據庫的性能,所以有必要在建立數據庫時適當的把數

據文件設置大一些。

 TMEP 表空間:臨時表空間,安裝數據庫時建立,能夠在運行時經過命令增大臨時

表空間。臨時表空間的重要做用是數據排序。好比當用戶執行了諸如 Order by 等

命令後,服務器須要對所選取數據進行排序,若是數據很大,內存的排序區可能裝

不下太大數據,就須要把一些中間的排序結果寫在硬盤的臨時表空間中。

 用戶表自定義空間:用戶能夠經過 CREATE TABLESPACE 命令建立表空間。

 

建立表空間須要考慮數據庫對分區(Extent,一個 Oracle 分區是數據庫文件中一段連續 的空間,Oracle 分區是 Oracle 管理中最小的單位)的管理,好比當一個表建立後先申請一個 分區,在 Insert 執行過程當中,若是分區數據已滿,須要從新申請另外的分區。若是一個數據 庫中的分區大小不一,建立表空間時須要考慮一系列問題。所以在 Oracle8i 以後,建立表空間都推薦使用「本地管理表空間」,這種表空間中的分區是一個固定大小的值,建立表空間 的語法是:

語法結構:建立表空間

CREATE  TABLESPACE  空間名稱

DATAFILE  '文件名1'  SIZE  數字M

[,'文件名2' SIZE 數字….]

EXTENT  MANAGEMENT  LOCAL

UNIFORM  SIZE 數字M

語法解析:

1. 文件名包括完整路徑和文件名,每一個數據文件定義了文件的初始大小,初始大小一

般以「M」爲單位。一個表空間中能夠有多個數據文件。

2. EXTENT MANAGEMENT LOCAL 指明表空間類型是:本地管理表空間。本地管理表空

間要求 Oracle 中的數據分區(Extent)大小統一。

3. UNIFORM SIZE:指定每一個分區的統一大小。

 

案例 5:建立一個表空間,包含兩個數據文件大小分別是 10MB,5MB,要求 extent 的

大小統一爲 1M。

代碼演示:建立表空間

CREATE  TABLESPACE  myspace

DATAFILE  'E://A.ORA'  SIZE  10M,

          'E://B.ORA'  SIZE  5M

EXTENT  MANAGEMENT  LOCAL

UNIFORM  SIZE 1M

而後打開對應盤符查看

 

必須是管理員用戶才能建立表空間,當表空間的空間不足時可使用 ALTER TABLESPACE

命令向表空間中追加數據文件擴充表空間。

 

代碼演示:擴充表空間

ALTER TABLESPACE myspace

 ADD DATAFILE 'E:/C.ORA' SIZE 10M

 

表空間能夠在不使用時刪除,使用 DROP TABLESPACE 命令。

DROP TABLESPACE myspace

注意該命令並不能刪除建立的.ORA文件

 

數據庫的全部數據所有在某一表空間中存放,在建立用戶時,能夠爲用戶指定某一表空

間,那麼該用戶下的全部數據庫對象(好比表)默認都存儲在該空間中。

代碼演示:爲某一用戶指定默認表空間

SQL> CREATE USER ACONG IDENTIFIED BY ACONG

  DEFAULT TABLESPACE MYSPACE

 

在建立表時,表中數據存放在用戶的默認表空間中,也能夠經過 tablespace 子句爲表指

定表中數據存放在其餘表空間中。

代碼演示:爲表指定表空間

CREATE TABLE SCORES

  (

  ID NUMBER ,

  TERM VARCHAR2(2),

  STUID VARCHAR2(7) NOT NULL,

  EXAMNO VARCHAR2(7) NOT NULL,

  WRITTENSCORE NUMBER(4,1) NOT NULL,

  LABSCORE NUMBER(4,1) NOT NULL

  )

 TABLESPACE myspace

 

建立索引時也能夠爲索引指定表空間。

代碼演示:爲索引指定表空間

CREATE INDEX UQ_ID ON SCORES(ID)

  TABLESPACE myspace

 

表和索引一旦建立,表空間沒法修改。

5、Oracle存儲過程

1.定義
所謂存儲過程(Stored Procedure),就是一組用於完成特定數據庫功能的SQL語句集,該SQL語句集通過編譯後存儲在數據庫系統中。在使用時候,用戶經過指定已經定義的存儲過程名字並給出相應的存儲過程參數來調用並執行它,從而完成一個或一系列的數據庫操做。

2.存儲過程的建立
Oracle存儲過程包含三部分:過程聲明,執行過程部分,存儲過程異常。

(1)無參存儲過程語法

create or replace procedure NoParPro 

 as  //聲明 

 ; 

 begin // 執行 

 ; 

 exception//存儲過程異常 

 ; 

 end;

(2)帶參存儲過程實例

create or replace procedure queryempname(sfindno emp.empno%type)  

as 

   sName emp.ename%type; 

   sjob emp.job%type; 

begin 

       .... 

exception 

       .... 

end;

(3)帶參數存儲過程含賦值方式

create or replace procedure runbyparmeters   

    (isal in emp.sal%type,  

     sname out varchar, 

     sjob in out varchar) 

 as  

    icount number; 

 begin 

      select count(*) into icount from emp where sal>isal and job=sjob; 

      if icount=1 then 

        .... 

      else 

       .... 

     end if; 

exception 

     when too_many_rows then 

     DBMS_OUTPUT.PUT_LINE('返回值多於1行'); 

     when others then 

     DBMS_OUTPUT.PUT_LINE('在RUNBYPARMETERS過程當中出錯!'); 

end;

其中參數IN表示輸入參數,是參數的默認模式。
OUT表示返回值參數,類型可使用任意Oracle中的合法類型。
OUT模式定義的參數只能在過程體內部賦值,表示該參數能夠將某個值傳遞迴調用他的過程
IN OUT表示該參數能夠向該過程當中傳遞值,也能夠將某個值傳出去。

(4)存儲過程當中遊標定義使用

as //定義(遊標一個能夠遍歷的結果集)  

CURSOR cur_1 IS  

  SELECT area_code,CMCODE,SUM(rmb_amt)/10000 rmb_amt_sn, 

         SUM(usd_amt)/10000 usd_amt_sn  

  FROM BGD_AREA_CM_M_BASE_T  

  WHERE ym >= vs_ym_sn_beg  

       AND ym <= vs_ym_sn_end  

  GROUP BY area_code,CMCODE;  

     

begin //執行(經常使用For語句遍歷遊標)      

FOR rec IN cur_1 LOOP  

  UPDATE xxxxxxxxxxx_T  

   SET rmb_amt_sn = rec.rmb_amt_sn,usd_amt_sn = rec.usd_amt_sn  

   WHERE area_code = rec.area_code  

   AND CMCODE = rec.CMCODE  

   AND ym = is_ym;  

END LOOP;

(5)遊標的定義

--顯示cursor的處理

declare  

---聲明cursor,建立和命名一個sql工做區

cursor cursor_name is 

    select real_name from account_hcz;

    v_realname varchar2(20);

begin

    open cursor_name;---打開cursor,執行sql語句產生的結果集

    fetch cursor_name into v_realname;--提取cursor,提取結果集中的記錄

    dbms_output.put_line(v_realname);

    close cursor_name;--關閉cursor

end;

三、在Oracle中對存儲過程的調用

 

(1)過程調用方式一

declare 

      realsal emp.sal%type; 

      realname varchar(40); 

      realjob varchar(40); 

begin   //過程調用開始 

      realsal:=1100; 

      realname:=''; 

      realjob:='CLERK'; 

      runbyparmeters(realsal,realname,realjob);--必須按順序 

      DBMS_OUTPUT.PUT_LINE(REALNAME||'   '||REALJOB); 

END;  //過程調用結束

(2)過程調用方式二

declare 

     realsal emp.sal%type; 

     realname varchar(40); 

     realjob varchar(40); 

begin    //過程調用開始 

     realsal:=1100; 

     realname:=''; 

     realjob:='CLERK'; 

     --指定值對應變量順序可變 

     runbyparmeters(sname=>realname,isal=>realsal,sjob=>realjob);          

    DBMS_OUTPUT.PUT_LINE(REALNAME||'   '||REALJOB); 

END;  //過程調用結束

(3)過程調用方式三(SQL命令行方式下)

1、SQL>exec  proc_emp('參數1','參數2');//無返回值過程調用 

2、SQL>var vsal number 

     SQL> exec proc_emp ('參數1',:vsal);// 有返回值過程調用 

      或者:call proc_emp ('參數1',:vsal);// 有返回值過程調用 

 

 

6、PL/SQL 程序設計

1.PL/SQL 簡介

Oracle PL/SQL 語言(Procedural Language/SQL)是結合告終構化 查詢與 Oracle 自身過程控制爲一體的強大語言,PL/SQL 不但支持更多的數據類型,擁有自 身的變量聲明、賦值語句,並且還有條件、循環等流程控制語句。過程控制結構與 SQL 數 據處理能力無縫的結合造成了強大的編程語言,能夠建立過程和函數以及程序包。

PL/SQL 是一種塊結構的語言,它將一組語句放在一個塊中,一次性發送給服務器,PL/SQL 引擎分析收到 PL/SQL 語句塊中的內容,把其中的過程控制語句由 PL/SQL 引擎自身去執行, 把 PL/SQL 塊中的 SQL 語句交給服務器的 SQL 語句執行器執行。如圖所示:

 

PL/SQL 塊發送給服務器後,先被編譯而後執行,對於有名稱的 PL/SQL 塊(如子程序) 能夠單獨編譯,永久的存儲在數據庫中,隨時準備執行。PL/SQL 的優勢還有:

支持 SQL

SQL 是訪問數據庫的標準語言,經過 SQL 命令,用戶能夠操縱數據庫中的數據。PL/SQL

支持全部的 SQL 數據操縱命令、遊標控制命令、事務控制命令、SQL 函數、運算符和僞列。

同時 PL/SQL 和 SQL 語言緊密集成,PL/SQL 支持全部的 SQL 數據類型和 NULL 值。

支持面向對象編程

PL/SQL 支持面向對象的編程,在 PL/SQL 中能夠建立類型,能夠對類型進行繼承,能夠

在子程序中重載方法等。

更好的性能

SQL 是非過程語言,只能一條一條執行,而 PL/SQL 把一個 PL/SQL 塊統一進行編譯後執

行,同時還能夠把編譯好的 PL/SQL 塊存儲起來,以備重用,減小了應用程序和服務器之間

的通訊時間,PL/SQL 是快速而高效的。

可移植性

使用 PL/SQL 編寫的應用程序,能夠移植到任何操做系統平臺上的 Oracle 服務器,同時

還能夠編寫可移植程序庫,在不一樣環境中重用。

安全性

能夠經過存儲過程對客戶機和服務器之間的應用程序邏輯進行分隔,這樣能夠限制對

Oracle 數據庫的訪問,數據庫還能夠受權和撤銷其餘用戶訪問的能力。

 

2.PL/SQL 塊

PL/SQL 是一種塊結構的語言,一個 PL/SQL 程序包含了一個或者多個邏輯塊,邏輯塊中

能夠聲明變量,變量在使用以前必須先聲明。除了正常的執行程序外,PL/SQL 還提供了專

門的異常處理部分進行異常處理。每一個邏輯塊分爲三個部分,語法是:

語法結構:PL/SQL 塊的語法

[DECLARE

 --declaration statements] ①

BEGIN

 --executable statements ②

[EXCEPTION

 --exception statements] ③

END;

語法解析:

① 聲明部分:聲明部分包含了變量和常量的定義。這個部分由關鍵字 DECLARE 開始,

若是不聲明變量或者常量,能夠省略這部分。

② 執行部分:執行部分是 PL/SQL 塊的指令部分,由關鍵字 BEGIN 開始,關鍵字 END

結尾。全部的可執行 PL/SQL 語句都放在這一部分,該部分執行命令並操做變量。

其餘的 PL/SQL 塊能夠做爲子塊嵌套在該部分。PL/SQL 塊的執行部分是必選的。注

意 END 關鍵字後面用分號結尾。

③ 異常處理部分:該部分是可選的,該部分用 EXCEPTION 關鍵字把可執行部分分紅兩

個小部分,以前的程序是正常運行的程序,一旦出現異常就跳轉到異常部分執行。

PL/SQL 是一種編程語言,與 Java 和 C#同樣,除了有自身獨有的數據類型、變量聲明和賦

值以及流程控制語句外,PL/SQL 還有自身的語言特性:

PL/SQL 對大小寫不敏感,爲了良好的程序風格,開發團隊都會選擇一個合適的編碼標準。

好比有的團隊規定:關鍵字所有大些,其他的部分小寫。

PL/SQL 塊中的每一條語句都必須以分號結束,SQL 語句能夠是多行的,但分號表示該語

句結束。一行中能夠有多條 SQL 語句,他們之間以分號分隔,可是不推薦一行中寫多條語

句。

PL/SQL 中的特殊符號說明:

 

變量聲明

PL/SQL 支持 SQL 中的數據類型,PL/SQL 中正常支持 NUMBER,VARCHAR2,DATE 等 Oracle

SQL 數據類型。聲明變量必須指明變量的數據類型,也能夠聲明變量時對變量初始化,變量

聲明必須在聲明部分。聲明變量的語法是:

語法格式:聲明變量

變量名 數據類型[ :=初始值]

語法解析: 數據類型若是須要長度,能夠用括號指明長度,好比:varchar2(20)。

代碼演示:聲明變量

DECLARE

 sname VARCHAR2(20) :='jerry'; ①

 BEGIN

 sname:=sname||' and tom'; ②

 dbms_output.put_line(sname); ③

 END;

代碼解析:

① 聲明一個變量 sname,初始化值是「jerry」。字符串用單引號,若是字符串中出現單

引號可使用兩個單引號(’’)來表示,即單引號同時也具備轉義的做用。

② 對變量 sname 從新賦值,賦值運算符是「:=」。

③ dbms_output.put_line 是輸出語句,能夠把一個變量的值輸出,在 SQL*Plus 中輸出

數據時,可能沒有結果顯示,可使用命令:set serveroutput on 設置輸出到 SQL*Plus

控制檯上。

 

對變量賦值還可使用 SELECT…INTO 語句從數據庫中查詢數據對變量進行賦值。可是

查詢的結果只能是一行記錄,不能是零行或者多行記錄。

代碼演示:變量賦值

DECLARE

  sname VARCHAR2(20) DEFAULT 'jerry'; ①

  BEGIN

  SELECT ename INTO sname FROM emp WHERE empno=7934; ②

  dbms_output.put_line(sname);

  END;

代碼解析:

① 變量初始化時,可使用 DEFAULT 關鍵字對變量進行初始化。

② 使用 select…into 語句對變量 sname 賦值,要求查詢的結果必須是一行,不能是多

行或者沒有記錄。

 

聲明常量

常量在聲明時賦予初值,而且在運行時不容許從新賦值。使用 CONSTANT 關鍵字聲明常

量。

代碼演示:聲明常量

DECLARE

  pi CONSTANT number :=3.14; --圓周率長值

  r number DEFAULT 3; --圓的半徑默認值3

  area number; --面積。

  BEGIN

  area:=pi*r*r; --計算面積

  dbms_output.put_line(area); --輸出圓的面積

  END;

代碼解析:

① 聲明常量時使用關鍵字 CONSTANT,常量初值可使用賦值運算符(:=)賦值,也

可使用 DEFAULT 關鍵字賦值。

在 SQL*Plus 中還能夠聲明 Session(會話,也就是一個客戶端從鏈接到退出的過程稱爲

當前用戶的會話。)全局級變量,該變量在整個會話過程當中均起做用,相似的這種變量稱爲

宿主變量。宿主變量在 PL/SQL 引用時要用「:變量名」引用。

代碼演示:宿主常量

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 中訪問宿主變量時要在變量前加「:」。

③ 在 SQL*Plus 中,使用 print 能夠輸出變量中的結果。

3. PL/SQL 數據類型

標量數據類型

標量數據類型的變量只有一個值,且內部沒有份量。標量數據類型包括數字型,字符型, 日期型和布爾型。這些類型有的是 Oracle SQL 中定義的數據類型,有的是 PL/SQL 自身附加 的數據類型。字符型和數字型又有子類型,子類型只與限定的範圍有關,好比 NUMBER 類 型能夠表示整數,也能夠表示小數,而其子類型 POSITIVE 只表示正整數。

 

 

 

屬性數據類型

當聲明一個變量的值是數據庫中的一行或者是數據庫中某列時,能夠直接使用屬性類型

來聲明。Oracle 中存在兩種屬性類型:%TYPE 和%ROWTYPE。

 % ROWTYPE

引用數據庫表中的一行做爲數據類型,即 RECORD 類型(記錄類型),是 PL/SQL 附加的

數據類型。表示一條記錄,就至關於 C#中的一個對象。可使用「.」來訪問記錄中的屬性。

代碼演示:

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

代碼解析:

① 聲明一個 myemp 對象,該對象表示 EMP 表中的一行。

② 從 EMP 表中查詢一條記錄放入 myemp 對象中。

③ 訪問該對象的屬性可使用「.」。

 

 %TYPE

引用某個變量或者數據庫的列的類型做爲某變量的數據類型。

代碼演示:%TYPE 應用

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 能夠引用表中的某列做的類型爲變量的數據類型,也能夠引用某變量的類型做爲

新變量的數據類型。

 

4.PL/SQL 條件控制和循環控制

PL/SQL 程序可經過條件或循環結構來控制命令執行的流程。PL/SQL 提供了豐富的流程

控制語句,與 C#同樣也有三種控制結構:

 順序結構

 條件結構

 循環結構

條件控制

PL/SQL 中關於條件控制的關鍵字有 IF-THEN、IF-THEN-ELSE、IF-THEN-ELSIF 和多分枝條件 CASE。

 IF-THEN

該結構先判斷一個條件是否爲 TRUE,條件成立則執行對應的語句塊,

具體語法是:

IF 條件 THEN

 --條件結構體

END IF;

說明:

① 用 IF 關鍵字開始,END IF 關鍵字結束,注意 END IF 後面有一個分號。

② 條件部分能夠不使用括號,可是必須以關鍵字 THEN 來標識條件結束,若是條件成

立,則執行 THEN 後到對應 END IF 之間的語句塊內容。若是條件不成立,則不執行

條件語句塊的內容。

④   PL/SQL 中關鍵字 THEN 到 END IF 之間的內容是條件結構體內容。

⑤    條件可使用關係運算符合邏輯運算符。

 

案例 1:查詢 JAMES 的工資,若是大於 900 元,則發獎金 800 元。

代碼演示:IF-THEN 應用

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,則執行條件結構體內部的內容。

② 在 PL/SQL 塊中可使用事務控制語句,該 COMMIT 同時也能把 PL/SQL 塊外沒有提

交的數據一併提交,使用時須要注意。

 

 IF-THEN-ELSE

語法格式:IF-THEN-ELSE

IF 條件 THEN

 --條件成立結構體

ELSE

 --條件不成立結構體

END IF;

語法解析:

把 ELSE 與 IF-THEN 連在一塊兒使用,若是 IF 條件不成立則執行就會執行 ELSE 部分的語句。

 

案例 2:查詢 JAMES 的工資,若是大於 900 元,則發獎金 800 元,不然發獎金 400 元。

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;

  COMMIT ;

  END;

 

 IF-THEN-ELSIF

語法格式:IF-THEN-ELSIF

IF 條件 1 THEN

 --條件 1 成立結構體

ELSIF 條件 2 THEN

 --條件 2 成立結構體

ELSE

 --以上條件都不成立結構體

END IF;

 

語法解析:

PL/SQL 中的再次條件判斷中使用關鍵字 ELSIF。

 

案例 3:查詢 JAMES 的工資,若是大於 1500 元,則發放獎金 100 元,若是工做大於 900

元,則發獎金 800 元,不然發獎金 400 元。

代碼演示:

DECLARE

 newSal emp.sal % TYPE;

BEGIN

 SELECT sal INTO newSal FROM emp

 WHERE ename='JAMES';

 IF newSal>1500 THEN

 UPDATE emp

 SET comm=100

 WHERE ename='JAMES';

 ELSIF newSal>900 THEN

 UPDATE emp

 SET comm=800

 WHERE ename='JAMES';

 Else

 UPDATE emp

 SET comm=400

 WHERE ename='JAMES';

 END IF;

  COMMIT ;

  END;

 

 CASE

CASE 是一種選擇結構的控制語句,能夠根據條件從多個執行分支中選擇相應的執行動

做。也能夠做爲表達式使用,返回一個值。語法是:

語法格式:CASE

CASE [selector]

WHEN 表達式 1 THEN 語句序列 1;

WHEN 表達式 2 THEN 語句序列 2;

WHEN 表達式 3 THEN 語句序列 3;

……

[ELSE 語句序列 N];

END CASE;

語法解析:

若是存在選擇器 selector,選擇器 selector 與 WHEN 後面的表達式匹配,匹配成功就執

行 THEN 後面的語句。若是全部表達式都與 selector 不匹配,則執行 ELSE 後面的語句。

 

案例 4:輸入一個字母 A、B、C 分別輸出對應的級別信息。

代碼演示: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 表示在運行時由鍵盤輸入字符串到 grade 變量中。

② v_grade 分別於 WHEN 後面的值匹配,若是成功就執行 WHEN 後的程序序列。

 

CASE 語句還能夠做爲表達式使用,返回一個值。

代碼演示:CASE 中存在 selector,做爲表達式使用

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 語句能夠返回一個結果給變量 p_grade

 

PL/SQL 還提供了搜索 CASE 語句。也就是說,不使用 CASE 中的選擇器,直接在 WHEN

後面判斷條件,第一個條件爲真時,執行對應 THEN 後面的語句序列。

代碼演示:搜索 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;

循環結構

PL/SQL 提供了豐富的循環結構來重複執行一些列語句。Oracle 提供的循環類型有:

1. 無條件循環 LOOP-END LOOP 語句

2. WHILE 循環語句

3. FOR 循環語句

在上面的三類循環中 EXIT 用來強制結束循環,至關於 C#循環中的 break。

LOOP 循環

LOOP 循環是最簡單的循環,也稱爲無限循環,LOOP 和 END LOOP 是關鍵字。

語法格式:LOOP 循環

LOOP

 --循環體

END LOOP;

語法格式:

1. 循環體在 LOOP 和 END LOOP 之間,在每一個 LOOP 循環體中,首先執行循環體中的語

句序列,執行完後再從新開始執行。

2. 在 LOOP 循環中可使用 EXIT 或者[EXIT WHEN 條件]的形式終止循環。不然該循環

就是死循環。

 

案例 5:執行 1+2+3+…+100 的值

代碼演示:LOOP 循環

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 循環中可使用 IF 結構嵌套 EXIT 關鍵字退出循環

② 註釋行,該行能夠代替①中的循環結構,WHEN 後面的條件成立時跳出循環。

WHILE 循環

語法格式:WHILE

WHILE 條件 LOOP

 --循環體

END LOOP;

案例 6:WHILE 循環

代碼演示:WHILE 循環

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 循環

FOR 循環須要預先肯定的循環次數,可經過給循環變量指定下限和上限來肯定循環運行

的次數,而後循環變量在每次循環中遞增(或者遞減)。FOR 循環的語法是:

語法格式:FOR 循環

FOR 循環變量 IN [REVERSE] 循環下限..循環上限 LOOP LOOP

--循環體

END LOOP;

語法解析:

循環變量:該變量的值每次循環根據上下限的 REVERSE 關鍵字進行加 1 或者減 1。

REVERSE:指明循環從上限向下限依次循環。

案例 7:FOR 循環

代碼演示:FOR 循環

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;

 

順序結構

在程序順序結構中有兩個特殊的語句。GOTO 和 NULL

GOTO 語句

GOTO 語句將無條件的跳轉到標籤指定的語句去執行。標籤是用雙尖括號括起來的標示

符,在 PL/SQL 塊中必須具備惟一的名稱,標籤後必須緊跟可執行語句或者 PL/SQL 塊。

GOTO 不能跳轉到 IF 語句、CASE 語句、LOOP 語句、或者子塊中。

NULL 語句

NULL 語句什麼都不作,只是將控制權轉到下一行語句。NULL 語句是可執行語句。NULL

語句在 IF 或者其餘語句語法要求至少須要一條可執行語句,但又不須要具體操做的地

方。好比 GOTO 的目標地方不須要執行任何語句時。

案例 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;

代碼解析:

① 跳轉到程序 first_label 位置,就是②的位置,first_label 是一個標籤,用兩個尖括號

包含。

② 無條件跳轉到 sedond_label 位置,就是④的位置。④處不執行任何內容,所以是一

個 NULL 語句。

在 PL/SQL 中,各類循環之間能夠相互嵌套

 

5. PL/SQL 中動態執行 SQL 語句

在 PL/SQL 程序開發中,可使用 DML 語句和事務控制語句,可是還有不少語句(好比

DDL 語句)不能直接在 PL/SQL 中執行。這些語句可使用動態 SQL 來實現。

PL/SQL 塊先編譯而後再執行,動態 SQL 語句在編譯時不能肯定,只有在程序執行時把

SQL 語句做爲字符串的形式由動態 SQL 命令來執行。在編譯階段 SQL 語句做爲字符串存在,

程序不會對字符串中的內容進行編譯,在運行階段再對字符串中的 SQL 語句進行編譯和執

行,動態 SQL 的語法是:

語法格式:動態 SQL

EXECUTE IMMEDIATE 動態語句字符串

[INTO 變量列表]

[USING 參數列表]

語法解析:

若是動態語句是 SELECT 語句,能夠把查詢的結果保存到 INTO 後面的變量中。若是動態

語句中存在參數,USING 爲語句中的參數傳值。

動態 SQL 中的參數格式是:[:參數名],參數在運行時須要使用 USING 傳值。

 

案例 9:動態 SQL

代碼演示:動態 SQL

DECLARE

 sql_stmt VARCHAR2(200); --動態SQL語句

 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

 --無子句的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;

 

代碼解析:

① 動態執行一個完整的 SQL 語句。

② SQL 語句中存在 3 個參數分別標識爲:[:一、:二、:3],所以須要用 USING 關鍵字對三

個參數分別賦值。

③ 對動態查詢語句可使用 INTO 子句把查詢的結果保存到一個變量中,要求該結果

只能是單行。

④ 在 Oracle 的 insert,update,delete 語句均可以使用 RETURNING 子句把操做影響的

行中的數據返回,對 SQL 語句中存在 RETURNING 子句時,在動態執行時可使用

RETURNING INTO 來接收。

⑥    動態執行參數中能夠是:[:數字]也能夠是[:字符串]。

7、數據庫導入導出

1. Oracle 導入導出

Oracle 的備份是 Oracle 操做中常見的工做,常見的備份方案有:邏輯備份(IMP&EXP

命令進行備份)、物理文件備份(脫機及聯機備份)、利用 RMAN(Recovery Manager)的增量

物理文件系統備份。ORACLE 數據庫的邏輯備份分爲四種模式:表空間備份(tablespace)、表

備份(table)、用戶備份(user)和徹底備份(full)。Oracle 的邏輯備份是使用 IMP&EXP 命令進行

數據導入導出的操做。使用 EXP 命令導出或者使用 IMP 命令導入時,須要 Create Session 系

統權限,可是若是要導出其餘的表,必須擁有權限:EXP_FULL_DATABASE。

調用導入導出命令時,首先要估計所需的空間。EXP 命令導出的文件是二進制文件

(*.dmp)只能由對應的 IMP 命令進行讀取恢復。導入導出的用途是:

 備份與恢復

 Oracle 平臺更換:能夠在相同版本之間進行備份與恢復,Oracle 較低版本的 export

數據文件能夠 import 到高版本的 Oracle 數據庫中,可是 Oracle 的版本只能是相鄰

的,不能垮版本。

 

2. EXP 導出數據

EXP 命令能夠在交互環境下導出數據庫中的數據,也能夠在非交互環境下執行命令。交

互環境下的命令執行,是一步一步執行的過程。

代碼演示:exp 的交互環境

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

輸入數組提取緩衝區大小: 4096 > ②

導出文件: EXPDAT.DMP > scott.dmp ③

(2)U(用戶), 或 (3)T(表): (2)U > 2 ④

導出權限 (yes/no): yes > yes ⑤

導出表數據 (yes/no): yes > yes ⑥

壓縮區 (yes/no): yes > no ⑦

已導出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

. 正在導出 pre-schema 過程對象和操做

. 正在導出用戶 SCOTT 的外部函數庫名

. 導出 PUBLIC 類型同義詞

. 正在導出專用類型同義詞

. 正在導出用戶 SCOTT 的對象類型定義

即將導出 SCOTT 的對象...

. 正在導出數據庫連接

. 正在導出序號

. 正在導出簇定義

. 即將導出 SCOTT 的表經過常規路徑...

. . 正在導出表 BONUS導出了 0 行

. . 正在導出表 DEPT導出了 10 行

. . 正在導出表 EMP導出了 14 行

. . 正在導出表 SALGRADE導出了 5 行

. . 正在導出表 TBLSTUDENT導出了 3 行

. 正在導出同義詞

. 正在導出視圖

. 正在導出存儲過程

. 正在導出運算符

. 正在導出引用完整性約束條件

. 正在導出觸發器

. 正在導出索引類型

. 正在導出位圖, 功能性索引和可擴展索引

. 正在導出後期表活動

. 正在導出實體化視圖

. 正在導出快照日誌

. 正在導出做業隊列

. 正在導出刷新組和子組

. 正在導出維

. 正在導出 post-schema 過程對象和操做

. 正在導出統計信息

成功終止導出, 沒有出現警告。

D:\>

代碼解析:

① Exp 是導出命令,該命令後面緊跟「用戶名/密碼@服務器網絡鏈接」。

② Exp 程序導出時使用的緩衝區大小,緩衝區越大,導出速度越快。直接回車表明使

用默認值 4096B。

③ Exp 命令會把全部要處處的數據導出到一個 Dmp 文件中,該步驟是 Exp 詢問導出的

數據文件名稱。

④ Exp 程序詢問導出整個用戶仍是導出某個表。默認導出整個用戶。

⑤ Exp 程序詢問是否導出每張表的訪問權限。默認導出訪問權限。

⑥ Exp 程序詢問是否導出表中的數據。默認導出數據庫表中的數據。

⑦ Oracle 表中的數據可能來自不一樣的分區中的數據塊,默認導出時會把全部的數據壓

縮在一個數據塊上,IMP 導入時,若是不存在連續一個大數據塊,則會導入失敗

 

也可使用 Exp 命令時,設置各類參數,使準備就緒的 Exp 命令不須要與用戶交互,按

照參數的要求,Exp 命令會一次性執行導出工做。要指定參數,您可使用關鍵字:

EXP KEYWORD=value 或 KEYWORD=(value1,value2,...,valueN)

例如: EXP SCOTT/TIGER GRANTS=Y TABLES=(EMP,DEPT,MGR)

 

代碼演示:exp 的非交互環境

D:\>exp scott/tiger@orcl  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

已導出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

即將導出指定的表經過常規路徑...

. . 正在導出表 EMP導出了 14 行

. . 正在導出表 DEPT導出了 10 行

成功終止導出, 沒有出現警告。

D:\>

3. IMP 導入

IMP 程序導入就是把 Exp 導出的文件從新導入到數據庫的過程。導入時也有一些重要的

參數:

 Fromuser:指出導出時 dmp 文件中記載的用戶信息。

 Touser:dmp 文件要導入到什麼目標用戶中。

 Commit:默認是 N,在緩衝區滿時是否須要 commit,若是設爲 N,須要較大的回滾段。

 Igore: Oracle在恢復數據的過程當中,當恢復某個表時,該表已經存在,就要根據ignore

參數的設置來決定如何操做。若 ignore=y,Oracle 不執行 CREATE TABLE 語句,直接

將數據插入到表中,若是插入的記錄違背了約束條件,好比主鍵約束,則出錯的記

錄不會插入,但合法的記錄會添加到表中。若 ignore=n,Oracle 不執行 CREATE TABLE

語句,同時也不會將數據插入到表中,而是忽略該表的錯誤,繼續恢復下一個表。

 

代碼演示:Imp 導入

D:\>imp test/test@orcl  file=employee.dmp commit=y full=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

經由常規路徑由 EXPORT:V10.02.01 建立的導出文件

警告: 這些對象由 SCOTT 導出, 而不是當前用戶

已經完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的導入

. 正在將 SCOTT 的對象導入到 EMPLOYEE

. . 正在導入表 "EMP"導入了 14 行

. . 正在導入表 "DEPT"導入了 10 行

即將啓用約束條件...

成功終止導入, 沒有出現警告。

D:\>

 

 

4. 常見問題

 數據庫對象已經存在

通常狀況, 導入數據前應該完全刪除目標數據下的表,序列,函數/過程,觸發器等。

數據庫對象已經存在, 按缺省的 imp 參數,則會導入失敗。

若是用了參數 ignore=y,會把 exp 文件內的數據內容導入。

若是表有惟一關鍵字的約束條件,不合條件將不被導入。

若是表沒有惟一關鍵字的約束條件,將引發記錄重複。

 數據庫對象有主外鍵約束

不符合主外鍵約束時,數據會導入失敗。

解決辦法: 先導入主表,再導入依存表。

disable 目標導入對象的主外鍵約束,導入數據後,再 enable 它們。

 權限不夠

若是要把 A 用戶的數據導入 B 用戶下, A 用戶須要有 imp_full_database 權限。

 導入大表( 大於 80M ) 時,存儲分配失敗

默認的 EXP 時,compress = Y,也就是把全部的數據壓縮在一個數據塊上。

導入時,若是不存在連續一個大數據塊,則會導入失敗。

導出 80M 以上的大表時,記得 compress= N,則不會引發這種錯誤。

 Imp 和 Exp 使用的字符集不一樣

若是字符集不一樣,導入會失敗,能夠改變 unix 環境變量或者 NT 註冊表裏 NLS_LANG 相

關信息。

 Imp 和 Exp 版本不能往上兼容

Imp 能夠成功導入低版本 Exp 生成的文件, 不能導入高版本 Exp 生成的文件根據狀況我

們能夠用。

相關文章
相關標籤/搜索