SQL語言共分爲四大類:數據查詢語言DQL,數據操縱語言DML, 數據定義語言DDL,數據控制語言DCL。其中用於定義數據的結構,比如 創建、修改或者刪除數據庫;DCL用於定義數據庫用戶的權限;在這篇文章中我將詳細講述這兩種語言在Oracle中的使用方法。
DML語言
DML是SQL的一個子集,主要用於修改數據,下表列出了ORACLE支持的DML語句。
語句 |
用途 |
INSERT |
向表中添加行 |
UPDATE |
更新存儲在表中的數據 |
DELETE |
刪除行 |
SELECT FOR UPDATE |
禁止其他用戶訪問DML語句正在處理的行。 |
LOCK TABLE |
禁止其他用戶在表中使用DML語句 |
插入數據
INSERT語句常常用於向表中插入行,行中可以有特殊數據字段,或者可以用子查詢從已存在的數據中建立新行。
列目錄是可選的,缺省的列的目錄是所有的列名,包括comlumn_id,comlumn_id可以在數據字典視圖ALL_TAB_COLUMNS,USER_TAB_COLUMNS,或者DBA_TAB_COLUMNS中找到。
插入行的數據的數量和數據類型必須和列的數量和數據類型相匹配。不符合列定義的數據類型將對插入值實行隱式數據轉換。NULL字符串將一個NULL值插入適當的列中。關鍵字NULL常常用於表示將某列定義爲NULL值。
下面的兩個例子是等價的。
INSERT INTO customers(cust_id,state,post_code) |
或
INSERT INTO customers(cust_id,state,post_code) |
更新數據
UPDATE命令用於修改表中的數據。
UPDATE order_rollup |
刪除數據
DELETE語句用來從表中刪除一行或多行數據,該命令包含兩個語句:
1、關鍵字DELETE FROM後跟準備從中刪除數據的表名。
2、WHERE後跟刪除條件
DELETE FROM po_lines |
清空表
如果你想刪除表中所有數據,清空表,可以考慮使用DDL語言的TRUNCATE語句。TRUNCATE就像沒有WHERE子句的DELETE命令一樣。TRUNCATE將刪除表中所有行。TRUNCATE不是DML語句是DDL語句,他和DELETE右不同的特點。
TRUNCATE TABLE (schema)table DROP(REUSE) STORAGE |
STORAGE子串是可選的,缺省是DROP STORAGE。當使用DROP STORAGE時將縮短表和表索引,將表收縮到最小範圍,並重新設置NEXT參數。REUSE STORAGE不會縮短表或者調整NEXT參數。
TRUNCATE和DELETE有以下幾點區別
1、TRUNCATE在各種表上無論是大的還是小的都非常快。如果有ROLLBACK命令DELETE將被撤銷,而TRUNCATE則不會被撤銷。
2、TRUNCATE是一個DDL語言,向其他所有的DDL語言一樣,他將被隱式提交,不能對TRUNCATE使用ROLLBACK命令。
3、TRUNCATE將重新設置高水平線和所有的索引。在對整個表和索引進行完全瀏覽時,經過TRUNCATE操作後的表比DELETE操作後的表要快得多。
4、TRUNCATE不能觸發任何DELETE觸發器。
5、不能授予任何人清空他人的表的權限。
6、當表被清空後表和表的索引講重新設置成初始大小,而delete則不能。
7、不能清空父表。
SELECT FOR UPDATE
select for update語句用於鎖定行,阻止其他用戶在該行上修改數據。當該行被鎖定後其他用戶可以用SELECT語句查詢該行的數據,但不能修改或鎖定該行。
鎖定表
LOCK語句常常用於鎖定整個表。當表被鎖定後,大多數DML語言不能在該表上使用。LOCK語法如下:
LOCK schema table IN lock_mode |
其中lock_mode有兩個選項:
share 共享方式
exclusive 唯一方式
例:
LOCK TABLE intentory IN EXCLUSIVE MODE |
死鎖
當兩個事務都被鎖定,並且互相都在等待另一個被解鎖,這種情況稱爲死鎖。
當出現死鎖時,ORACLE將檢測死鎖條件,並返回一個異常。
事務控制
事務控制包括協調對相同數據的多個同步的訪問。當一個用戶改變了另一個用戶正在使用的數據時,oracle使用事務控制誰可以操作數據。
事務
事務表示工作的一個基本單元,是一系列作爲一個單元被成功或不成功操作的SQL語句。在SQL和PL/SQL中有很多語句讓程序員控制事務。程序員可以:
1、顯式開始一個事物,選擇語句級一致性或事務級一致性
2、設置撤銷回滾點,並回滾到回滾點
3、完成事務永遠改變數據或者放棄修改。
事務控制語句
語句 |
用途 |
Commit |
完成事務,數據修改成功並對其他用戶開放 |
Rollback |
撤銷事務,撤銷所有操作 |
rollback to savepoint |
撤銷在設置的回滾點以後的操作 |
set transaction |
響應事務或語句的一致性;特別對於事務使用回滾段 |
例:
BEGIN |
Savepoint 和 部分回滾(Partial Rollback)
在SQL和PL/SQL中Savepoint是在一事務範圍內的中間標誌。經常用於將一個長的事務劃分爲小的部分。保留點Savepoint可標誌長事務中的任何點,允許可回滾該點之後的操作。在應用程序中經常使用Savepoint;例如一過程包含幾個函數,在每個函數前可建立一個保留點,如果函數失敗,很容易返回到每一個函數開始的情況。在回滾到一個Savepoint之後,該Savepoint之後所獲得的數據封鎖被釋放。爲了實現部分回滾可以用帶TO Savepoint子句的ROLLBACK語句將事務回滾到指定的位置。
例
BEGIN |
關鍵字SAVEPOINT是可選的,所以下面兩個語句是等價的:
ROLLBACK TO ATM_LOGGED; |
一致性和事務
一致性是事物控制的關鍵慨念。掌握了oracle 的一致性模型,能使您更好的,更恰當的使用事務控制。oracle通過一致性保證數據只有在事務全部完成後才能被用戶看見和使用。這項技術對多用戶數據庫有巨大的作用。
oracle常常使用語句級(state-level)一致性,保證數據在語句的生命期之間是可見的但不能被改變。事務由多個語句組成,當使用事務時,事物級(transaction-level)一致性在整個事務生命期中保證數據對所有語句都是可見的。
oracle通過SCN(syatem change number)實施一致性。一個SCN是一個面向時間的數據庫內部鍵。SCN只會增加不會減少,SCN表示了時間上的一個點,每個數據塊都有一個SCN,通過比較這個點實施操作。
事務級一致性
SET TRANSACTION 的一個作用是確保事務級一致或語句級一致中有一個實施。ORACLE使用這些術語:
ISOLATION LEVEL READ COMMIT 表示語句級一致
ISOLATION LEVEL SERIALIZABLE 表示事務級一致。
例:
SET TRANSACTION ISOLATION LEVEL READ COMMIT; |
下面的語句也能確保事務級一致:
SET TRANSCATION READ ONLY |
任何企圖在只讀(READ ONLY)事務中修改數據的操作都會拋出一個異常。但是,READ ONLY事務只能在下列語句中使用:
SELECT(沒有FOR UPDATE子句) |
即使沒有改變任何數據,READ ONLY事務依然必須使用一個COMMIT或ROLLBACK以結束整個事務。
SET TRANSCTION的另外一個應用是在回滾時直接使用回滾段(ROLLBACK SEGMENT)。回滾段是ORACLE的一個特殊的數據對象,回滾段的頭部包含正在使用該回滾段事務的信息。當用戶回滾事務(ROLLBACK)時,ORACLE將會利用回滾段中的數據前影像來將修改的數據恢復到原來的值。oracle用round-robin給事務隨機分配回滾段。一個大的事務可以分配任何回滾段,這也許會導致回滾段的大小變得很大。因此要避免讓大的事務隨機分配回滾段。
事務以SET TRANSACTION開始,象下面這樣:
SET TRANSACTION USE ROLLBACK SEGMENT rb_large; |
rb_large是一個大的回滾段的名稱,現在就給一個大的事務分配了一個大的回滾段,其他的小的回滾段將不由動態空間管理,這樣就更有效率。
下面我們看一個例子.我們有一個回滾段表空間大小是
rb_large(initial |
所有的都非常恰當的安排在
SET TRANSACTION USE ROLLBACK SEGMENT rb_large |
現在 4個事務重用相同的表空間,保正4個回滾段的表空間在
建立和修改用戶
CREATE USER 語句將建立一個用戶。當一個用戶連接到ORACLE數據庫時,它必須被驗證。ORACLE中驗證有三種類型:
Database
external
Global
缺省是數據庫驗證,當用戶連接到數據庫時,oracle將檢測用戶是否是數據庫的合法用戶,並且要提供正確的password.external驗證,oracle將只檢測用戶是否是合法用戶,password已經被網絡或系統驗證了。global驗證也是隻檢測是否是合法用戶,password由oraclesecurity server驗證。
Database驗證用戶賬號
數據庫驗證賬號是張好的缺省類型,也是最普通的類型。建立一個賬號是piyush,口令是welcome的賬號,只需執行下面的命令:
CREATE USE piyush IDENTIFIED BY welcome |
piyush可以通過下面的語句將口令改變爲saraswatt:
ALTER USER piyush IDENTIFIED BY saraswati; |
外部驗證用戶賬號
用戶賬號進入數據庫時可以不提供口令,這種情況下代替數據庫識別口令的是客戶端操作系統。外部驗證賬號有時也叫OPS$賬號,當他們最初在oracle6開始介紹時,oracle賬號都有關鍵字前綴OPS$,這也就是爲什麼init.ora 參數os_authent_prefix是OPS$--默認特徵與oracle6保持一致。os_authent_prefix定義的字符串必須被預處理爲用於Oracle外部識別賬號的操作系統賬號名。創建操作系統用戶appl的語句是:
CREATE USER ops$appl IDENTIFIED EATERNALLY |
但在通常情況下,os_authent_prefix將被設置爲空,像下面這樣:
CREATE USER appl IDENTIFIED EATERNALLY |
這樣效果是一樣的,關鍵字IDENTIFIED EXTERNALLY告訴ORACLE這是一個外部識別賬號。
GLOBAL用戶賬號
GLOBAL類型的用戶賬號數據庫不檢測口令,而是由X.509目錄服務器檢測口令。創建一個GLOBAL類型的用戶賬號的方法是:
CREATE USER scott IDENTIFIED GLOBALLY AS "CN=scott,OU=divisional,O=sybex,C=US" |
關鍵字IDENTIFIED GLOBALLY AS表示建立的是一個GLOBAL類型的用戶賬號.
創建和更改用戶賬號
CREATE USER 用於建立用戶賬號和給用戶賬號的屬性賦值。ALTER USER用於更改用戶賬號和屬性。但CREATE USER語句必須包括用戶名和口令。
有部分屬性能用CREATER USER和ALTER USER語句設置,下面對是這些的屬性具體描述:
給用戶分配缺省表空間
表空間(tablespace)是放置表、索引、叢等用戶對象的。如果在create user語句中沒有包含表空間,那麼缺省的是系統表空間。
CREATE USER piyush IDENTIFIED BY saraswati |
給用戶分配臨時表空間
臨時表空間,顧名思義是臨時存放表、索引等用戶對象的臨時段。建立方法一樣
CREATE USER piyush IDENTIFIED BY saraswati |
給用戶分配表空間的使用定額
使用定額限制用戶在表空間中使用磁盤的數量。定額可以按字節、千字節、兆字節或者無限制來制定。
CREATE USER piyush IDENTIFIED BY saraswati |
給用戶分配一個簡表
簡表可以限制用戶在會話時消耗的資源。這些資源包括:連接數據庫的時間,空閒時間,每次會話的邏輯讀數據的數量等等,缺省的簡表對資源無限制。
CREATE USER piyush IDENTIFIED BY saraswati |
爲用戶響應指定角色
這個屬性只能由ALTER USER語句設置,試圖用CREATE USER語句設置將回返回一個例外。
ALTER USER manoj DEFAULT ROLE ALL EXCEPT salary_adm; |
爲用戶的password設定到期時間以便在用戶下次登錄時更改
當用戶的password到期,在下一次登錄時將強迫修改password,oracle提示用戶輸入舊的password,然後輸入新的password。這項功能常用於新用戶,當新用戶用缺省的password登錄時必須修改立即修改password.
ALTER USER manoj IDENTIFIED BY welcome; |
鎖定賬號,是用戶不能登錄
ALTER USER ql AC |
對賬號解鎖,以便用戶能登錄數據庫
ALTER USER ql ACCOUNT UNLOCK |
權限和角色
權限允許用戶訪問屬於其它用戶的對象或執行程序,ORACLE系統提供三種權限:
Object 對象級
System 系統級
Role 角色級
這些權限可以授予給用戶、特殊用戶public或角色,如果授予一個權限給特殊用戶"Public"(用戶public是oracle預定義的,每個用戶享有這個用戶享有的權限),那麼就意味作將該權限授予了該數據庫的所有用戶。
對管理權限而言,角色是一個工具,權限能夠被授予給一個角色,角色也能被授予給另一個角色或用戶。用戶可以通過角色繼承權限,除了管理權限外角色服務沒有其它目的。權限可以被授予,也可以用同樣的方式撤銷。
建立和使用角色
如前所訴,角色存在的目的就是爲了使權限的管理變得輕鬆。建立角色使用CREATE ROLE語句,他的語法如下:
CREATE ROLE role_name IDENTIFIED BY password |
缺省情況下建立的角色沒有password或者其他的識別。如果使用IDENTIFIED BY 子句建立,那麼角色不會自動響應,必須用SET ROLE激活。
SET ROLE role_name IDENTIFIED BY password |
EXTERNALLY和GLOBALLY類型的角色由操作系統和ORACLE Service server驗證。通常用戶需要權限修改應用程序中使用的表單中的數據,但是隻有在應用程序運行時而不是在使用ad hoc工具時,這種上下文敏感安全可以通過有PASSWORD的角色來實現。當用戶在應用程序內部連結數據庫時,代碼將執行SET ROLE命令,通過安全驗證。所以用戶不需要知道角色的password,也不需要自己輸入SET ROLE命令。
對象權限
對象權限就是指在表、視圖、序列、過程、函數或包等對象上執行特殊動作的權利。有九種不同類型的權限可以授予給用戶或角色。如下表:
權限 |
ALTER |
DELETE |
EXECUTE |
INDEX |
INSERT |
READ |
REFERENCE |
SELECT |
UPDATE |
Directory |
no |
no |
no |
no |
no |
yes |
no |
no |
no |
function |
no |
no |
yes |
no |
no |
no |
no |
no |
no |
procedure |
no |
no |
yes |
no |
no |
no |
no |
no |
no |
package |
no |
no |
yes |
no |
no |
no |
no |
no |
no |
DB Object |
no |
no |
yes |
no |
no |
no |
no |
no |
no |
Libary |
no |
no |
yes |
no |
no |
no |
no |
no |
no |
Operation |
no |
no |
yes |
no |
no |
no |
no |
no |
no |
Sequence |
yes |
no |
no |
no |
no |
no |
no |
no |
no |
Table |
yes |
yes |
no |
yes |
yes |
no |
yes |
yes |
yes |
Type |
no |
no |
yes |
no |
no |
no |
no |
no |
no |
View |
no |
yes |
no |
no |
yes |
no |
no |
yes |
yes |
對象由不止一個權限,特殊權限ALL可以被授予或撤銷。如TABLE的ALL權限就包括:
SELECT,INSERT,UPDATE和DELETE,還有INDEX,ALTER,和REFERENCE。
如何看這個表我們以ALTER權限爲例進行說明
ALTER權限
允許執行ALTER TABLE和LOCK TABLE操作,ALTER TABLE可以進行如下操作:
. 更改表名
. 增加或刪除列
. 改變列的數據類型或大小
. 將錶轉變爲分區表
在SEQUENCE上的ALTER權限允許執行ALTER Sequence語句,重新給sequence分配最小值、增量和緩衝區大小。
系統權限
系統權限需要授予者有進行系統級活動的能力,如連接數據庫,更改用戶會話、建立表或建立用戶等等。你可以在數據字典視圖SYSTEM_PRIVILEGE_MAP上獲得完整的系統權限。對象權限和系統權限都通過GRANT語句授予用戶或角色。需要注意的是在授予對象權限時語句應該是WITH GRANT OPTION子句,但在授予系統權象時語句是WITH ADMIN OPTION,所以在你試圖授予系統權限時,使用語句WITH GRANT OPTION系統會報告一個錯誤:ONLY ADMIN OPTION can be specified。在考試中要特別注意這個語法和錯誤信息。
角色和角色權限
角色權限就是將屬於用戶的權限授予一個角色。任何權限都可以授予給一個角色。授予系統權限給被授予者必須使用WITH_ADMIN_OPTION子句,在會話期間通過SET ROLE語句授予或撤銷角色權限。然而,角色權限不能依靠存儲在SQL中的權限。如果函數、程序、包、觸發器或者方法使用另一個計劃擁有的對象,那麼就必須直接給對象的擁有者授權,這是因爲權限不會在會話之間改變。
授予和撤銷權限
給用戶或者角色授予權限使用GRANT 語句,GRANT語句的語法如下:
GRANT ROLE(或system privilege) TO user(role,Public) WITH ADMIN OPTION(可選) |
對象權限被授予 WITH GRANT OPTION,
權限和數據字典
數據字典是ORACLE存儲有關數據庫結構信息的地方,數據本身存放在其他地方,數據字典由表和視圖組成。在考試中關於數據字典最容易考的內容是:查看那一類權限已經被授予。比如DBA_TAB_PRIV包含了用戶授予給另一用戶的對象權限和在授予時是否帶有WITH GRANT OTPION子串的信息。注意DBA_TAB_PRIV不僅僅包含了對錶的權限的關係,他還包括函數、包、隊列等等上的權限的關係。下表列出了所有的權限和角色的數據字典視圖:
表: 權限的數據字典視圖
視圖 |
作用 |
ALL_COL_PRIVS |
表示列上的授權,用戶和PUBLIC是被授予者 |
ALL_COL_PRIVS_MADE |
表示列上的授權,用戶是屬主和被授予者 |
ALL_COL_RECD |
表示列上的授權,用戶和PUBLIC是被授予者 |
ALL_TAB_PRIVS |
表示對象上的授權,用戶是PUBLIC或被授予者或用戶是屬主 |
ALL_TAB_PRIVS_MADE |
表示對象上的權限,用戶是屬主或授予者 |
ALL_TAB_PRIVS_RECD |
表示對象上的權限, 用戶是PUBLIC或被授予者 |
DBA_COL_PRIVS |
數據庫列上的所有授權 |
DBA_ROLE_PRIVS |
顯示已授予用戶或其他角色的角色 |
DBA_SYS_PRIVS |
已授予用戶或角色的系統權限 |
DBA_TAB_PRIVS |
數據庫對象上的所有權限 |
ROLE_ROLE_PRIVS |
顯示已授予用戶的角色 |
ROLE_SYS_PRIVS |
顯示通過角色授予用戶的系統權限 |
ROLE_TAB_PRIVS |
顯示通過角色授予用戶的對象權限 |
SESSION_PRIVS |
顯示用戶現在可利用的所有系統權限 |
USER_COL_PRIVS |
顯示列上的權限,用戶是屬主、授予者或被授予者 |
USER_COL_PRIVS_MADE |
顯示列上已授予的權限,用戶是屬主或授予者 |
USER_COL_PRIVS_RECD |
顯示列上已授予的權限,用戶是屬主或被授予者 |
USER_ROLE_PRIVS |
顯示已授予給用戶的所有角色 |
USER_SYS_PRIVS |
顯示已授予給用戶的所有系統權限 |
USER_TAB_PRIVS |
顯示已授予給用戶的所有對象權限 |
USER_TAB_PRIVS_MADE |
顯示已授予給其他用戶的對象權限,用戶是屬主 |
USER_TAB_PRIVS_RECD |
顯示已授予給其他用戶的對象權限,用戶是被授予者 |