Copyright © 2019 Linyer. All Rights Reserved
目錄
第9章:創建和管理表
數據庫對象
對象 | 說明 |
---|---|
表 | 用於存儲數據 |
視圖 | 一個或多個表中數據的子集 |
序列 | 數字值生成器 |
索引 | 提高某些查詢的性能 |
同義詞 | 給出對象的替代名稱 |
命名規則
- 表名 和 列名
- 必須以字母開頭
- 長度必須是 1-30 個字符
- 只能包含A-Z,a-z,0-9,_,$ 和 #
- 不能與同一用戶擁有的其它對象重名
- 不能是Oracle服務器的保留字
創建表
- 使用 CREATE TABLE
creat table
語句創建表- 此命令爲一條 DDL 語句
創建具有以下三個列的DEPT表:DEPTNO、DNAME 和 LOC
CREATE TABLE dept
(deptno NUMBER(2),
dname VARCHAR2(14),
loc VARCHAR2(13));
確認表的創建
DESCRIBE dept
- DEFAULT 選項
- 指定插入時的列的默認值。
- 文字值、表達式或SQL函數都是合法的值。
- 其它列的名稱或僞列是不合法的值。
- 默認數據類型必須與列數據類型匹配。
Oracle 數據庫中的表
用戶表
- 是由用戶創建和維護的表的集合
- 包含用戶信息
數據字典
- 是由 Oracle Server 創建和維護的表的集合
- 包含數據庫信息
- 在 Oracle 數據庫中有一個表和視圖的集合,稱爲數據字典
- 此集合是由 Oracle 服務器創建和維護的,並且包含有關數據庫的信息
- 存儲在數據字典中的信息包括 Oracle 服務器用戶的姓名、授予用戶的權限、數據庫對象名稱、表約束和審計信息
- 數據字典視圖共有四類,每一類都有反映其預期用途的獨特前綴
前綴 | 說明 |
---|---|
USER_ | 這些視圖包含關於用戶擁有的對象的信息 |
ALL_ | 這些視圖包含關於用戶可以訪問的所有表(對象表和關係表)的信息。 |
DBA_ | 這些視圖是受限視圖,它們只能由被指定了 DBA 角色的人員訪問。 |
v$ | 這些視圖是動態性能視圖,反映數據庫服務器性能、內存和鎖的動態性能。 |
查詢數據字典
查看用戶擁有的表的名稱
SELECT table_name
FROM user_tables ;
查看用戶擁有的獨特的對象類型
SELECT DISTINCT object_type
FROM user_objects ;
查看用戶擁有的表、視圖、同義詞和序列
SELECT *
FROM user_catalog ;
數據類型
數據類型 | 說明 |
---|---|
VARCHAR2(size) | 可變長度字符數據(必須指定最大size;最小size爲1;最大size爲4000) |
CHAR[(size)] | 固定長度字符數據,長度爲size字節(默認和最小size爲1;最大size爲2000) |
NUMBER[(D,s)] | 精度爲p、小數位數爲s的數(精度是指十進制數字的總數,而小數位數是指小數點右邊的數字的位數;精度範圍可以從1到38,而小數位數範圍可以從-84到127) |
DATE | 公元前4712年1月1日到公元9999年12月31日之間的日期和時間值,精確到最接近的那一秒。 |
LONG | 可變長度字符數據,最多爲2千兆字節 |
CLOB | 字符數據,最多爲4千兆字節 |
RAW(size) | 長度爲size的原始二進制數據(必須指定最大size。最大的size爲2000) |
LONG RAW | 可變長度的原始二進制數據,最多爲2千兆字節 |
BLOB | 二進制數據,最多爲4千兆字節 |
BFTLE | 存儲在外部文件的二進制數據,最多爲4千兆字節 |
ROWID | 64位基本編號系統,表示行在表中的唯一地址。 |
- 當使用子查詢創建表時,不會複製 LONG 列。
- LONG 列不能包含在 GROUP BY 或 ORDER BY 子句中。
- 每個表只能使用一個 LONG 列。不能在 LONG 列上定義約束。
- 您可能希望使用 CLOB 列,而不使用 LONG 列。
日期時間數據類型
數據類型 | 說明 |
---|---|
TIMESTAMP | 允許將時間存儲爲帶有零點幾秒的日期。這種數據類型有幾種變體。 |
INTERVAL YEAR TO | 允許將時間存儲爲年和月的間隔。用於表示兩個日期時間值之間的 |
MONTH | 差異,其中有效的取值部分只是年和月。 |
INTERVAL DAY TO | 允許將時間存儲爲天、小時、分鐘和秒的間隔。用於表示兩個日期 |
SECOND | 時間值之間的精確差異。 |
TIMESTAMP 數據類型是 DATE 數據類型的擴展。
它可以存儲 DATE 數據類型的年、月和日,加上小時、分鐘和秒值以及零點幾秒值。
CREATE TABLE new_employees
(employee_id NUMBER,
first_name VARCHAR2(15),
last_name VARCHAR2(15),
...
start_date TIMESTAMP(7),
...);
- TIMESTAMP WITH TIME ZONE
timestamp with time zone
數據類型- TIMESTAMP WITH TIME ZONE 是 TIMESTAMP 的變體,它的值中包含了時區偏移量。
- 時區偏移量是當地時間和 UTC 之間的差值(以小時和分鐘數表示)。
- TIMESTAMP WITH LOCAL TIME 數據類型
- TIMESTAMP WITH LOCAL TIME ZONE是TIMESTAMP 的另一個變體,它的值中包含了時區偏移量。
- 存儲在數據庫中的數據會被標準化爲數據庫時區。時區偏移量不是作爲列數據的一部分進行存儲的;Oracle 將按用戶的本地會話時區返回數據。
CREATE TABLE time_example
(order_date TIMESTAMP WITH LOCAL TIME ZONE)
INSERT INTO time_example VALUES('15-NOV-00 09:34:28 AM');
SELECT *
FROM time_example;
- INTERVAL YEAR TO MONTH
interval year to month
數據類型- 通過使用 YEAR 和 MONTH 日期時間字段存儲一個時段。
- INTERVAL DAY TO SECOND
interval day to second
數據類型- INTERVAL DAY TO SECOND用於按照日、小時、分鐘和秒存儲時段。
使用 子查詢語法 創建表
- 通過組合 CREATE TABLE 語句和 AS subguery 選項可以創建表並插入行。
CREATE TABLE table
[(column, column...)]
AS subquery;
table 是表的名稱
column 是列名、默認值和完整性約束
subquery 是一條 SELECT 語句,它定義要插入到新表中的一組行
- 該表在創建時具有指定的列名,並且 SELECT 語句檢索到的行將插入到該表中。
- 列定義只能包含列名和默認值。
- 如果已經給出了列的規格,則列數必須等於子查詢 SELECT 列表中的列數。
- 如果沒有給出列的規格,則表的列名將和子查詢中的列名相同。完整性規則不會傳遞到新表中,只有列數據類型定義纔會被傳遞。
CREATE TABLE dept80
AS
SELECT employee_id, last_name,
salary*12 ANNSAL,
hire_date
FROM employees
WHERE department_id = 80;
ALTER TABLE 語句
- 使用 ALTER TABLE
alter table
語句可以執行以下任務:- 添加新列
- 修改現有列
- 爲新列定義默認值
- 刪除列
ALTER TABLE table
ADD (column datatype [DEFAULT expr]
[, column datatype]...);
ALTER TABLE table
MODIFY (column datatype [DEFAULT expr]
[, column datatype]...);
ALTER TABLE table
DROP (column);
- table 是表的名稱
- ADD|MODIFY|DROP 是修改的類型
- column 是新列的名稱
- datatype 是新列的數據類型和長度
- DEFAULT expr 指定新列的默認值
添加新列
ALTER TABLE dept80
ADD (job_id VARCHAR2(9));
修改列
ALTER TABLE dept80
MODIFY (last_name VARCHAR2(30));
- 可以增大數字列的寬度或精確度。
- 可以增大數字列或字符列的寬度。
- 只有在列僅包含空值或表沒有行時,纔可以減少列的寬度。
- 只有在列包含空值時,纔可以更改數據類型。
- 只有在列包含空值或您沒有更改列的大小時,纔可以將 CHAR 類型的列轉換爲 VARCHAR2 數據類型,或將 VARCHAR2 類型的列轉換爲 CHAR 數據類型。
- 對列的默認值的更改隻影響以後對錶的插入操作。
刪除列
ALTER TABLE dept80
DROP COLUMN job_id;
SET UNUSED 選項
- 可以使用 SET UNUSED 選項將一個或多個列標記爲“不使用”。
- 可以使用 DROP UNUSED COLUMNS 選項刪除標記爲“不使用”的列。
ALTER TABLE table
SET UNUSED (column);
ALTER TABLE table
SET UNUSED COLUMN column;
ALTER TABLE table c
DROP UNUSED COLUMNS;
- DROP UNUSED COLUMINS
drop unused columins
將從表中刪除當前標記爲“不使用”的所有列。如果您要從表的“不使用”
列中回收額外的磁盤空間,則可以使用此語句。如果表不包含“不使用”的列,該語句也不會返回錯誤。
ALTER TABLE dept80
SET UNUSED (last_name);
ALTER TABLE dept80
DROP UNUSED COLUMNS;
刪除表
- 該表的所有數據和結構都會被刪除。
- 所有待定事務處理都會被提交。
- 所有索引都會被刪除。
- 無法回退 DROP TABLE 語句。
DROP TABLE dept80;
- 所有數據都會從該表中刪除。
- 所有視圖和同義詞都會保留,但卻不再有效。
- 所有待定事務處理都會被提交。
- 只有表的創建者或具有 DROP ANY TABLE 權限的用戶才能刪除表。
更改對象名
- 要更改表、視圖、序列或同義詞的名稱,可以執行 RENAME 語句。
RENAME dept TO detail_dept;
捨去表的內容
- TRUNCATE TABLE 語句
- 刪除表的所有行
- 釋放該表使用的存儲空間
TRUNCATE TABLE detail_dept;
向表中添加備註
- 可以使用 COMMENT 語句向表或列添加備註。
COMMENT ON TABLE employees
IS 'Employee Information';
第10章:包括約束
- 您可以使用約束執行以下任務:
- 在對錶執行插入、更新或刪除行操作時,對錶中的數據強制執行規則。必須滿足約束,操作才能成功。
- 防止在其它表對該表存在依賴性時將其刪除
- 爲 Oracle 工具(例如 Oracle Developer )提供規則
數據完整性約束
約束 | 說明 |
---|---|
NOT NULL | 指定該列不能包含空值 |
UNIQUE | 指明一個列或列組合中的值對於該表中的所有行來說必須是唯一的 |
PRIMARY KEY | 唯一標識表中的每一行 |
FOREIGN KEY | 在列和被引用表的列之間建立並實施一個外鍵關係 |
CHECK | 指定條件必須爲真 |
- 可以給約束命名,也可以由 Oracle 服務器使用 SYS_Cn 格式產生一個名稱。
- 可以在以下的任一時刻創建約束:
- 在創建表的同時創建約束
- 在表創建之後創建約束
- 可以在列或表級別上定義約束。
- 可以在數據字典中查看約束。
定義 約束
CREATE TABLE [schema.]table
(column datatype [DEFAULT expr]
[column_constraint],
...
[table_constraint][,...]);
CREATE TABLE employees(
employee_id NUMBER(6),
first_name VARCHAR2(20),
...
job_id VARCHAR2(10) NOT NULL,
CONSTRAINT emp_emp_id_pk
PRIMARY KEY (EMPLOYEE_ID));
- schema 是所有者的姓名
- table 是表的名稱
- DEFAULT expr 指定一個默認值,當INSERT語句中沒有指定值時,則使用該默認值
- column 是列的名稱
- datatype 是列的數據類型和長度
- column constraint 是作爲列定義的一部分的完整性約束
- table constraint 是作爲表定義的一部分的完整性約束
NOT NULL 約束
- 確保該列不允許有空值
將 NOT NULL 約束應用於表 EMPLOYEES的 LAST_NAME 和 HIRE_DATE 列
因爲用戶沒有命名這些約束,所以Oracle服務器爲它們創建了名稱。
CREATE TABLE employees(
employee_id NUMBER(6),
last_name VARCHAR2(25) NOT NULL,
salary NUMBER(8,2),
commission_pct NUMBER(2,2),
hire_date DATE
CONSTRAINT emp_hire_date_nn
NOT NULL,
UNIQUE 約束
- UNIOUE 關鍵字完整性約束要求列或列集合中的每個值(關鍵字)都是唯一的。
- 即,表的任意兩行在指定列或列集合中都沒有重複的值。
示例將 UNIQUE 約束應用於 EMPLOYEES 表的 EMAIL 列。該約束的名稱爲EMP_EMAIL_UK。
CREATE TABLE employees(
employee_id NUMBER(6),
last_name VARCHAR2(25) NOT NULL,
email VARCHAR2(25),
salary NUMBER(8,2),
commission_pct NUMBER(2,2),
hire_date DATE NOT NULL,
...
CONSTRAINT emp_email_uk UNIQUE(email));
PRIMARY KEY 約束
- PRIMARY KEY 約束將爲表創建一個主鍵。
- 每個表只能創建一個主鍵。
- PRIMARY KEY 約束是唯一標識表中每行的一個列或列集合。
- 此約束將強制實行列或列組合的唯一性,並且確保作爲主鍵的一部分的列不包含空值。
- PRIMARY KEY 約束可以在列級別或表級別上定義。
- 組合 PRIMARY KEY 是通過使用表級別定義來創建的。
- 一個表只能有一個 PRIMARY KEY 約束,但是可以有多個 UWIQUE 約束。
示例在表 DEPARTMENTS 的 DEPARTMENT_ID 列上定義了 PRIMARY KEY 約束。該約束的名稱爲 DEP_TID_PK。
CREATE TABLE departments(
department_id NUMBER(4),
department_name VARCHAR2(30)
CONSTRAINT dept_name_nn NOT NULL,
manager_id NUMBER(6),
location_id NUMBER(4),
CONSTRAINT dept_id_pk PRIMARY KEY(department_id));
FOREIGN KEY 約束
- FOREIGN KEY(或引用完整性約束)將指定一個列或列組合作爲外鍵,並建立與同一表或不同表中主鍵或唯一關鍵字之間的關係。
- 外鍵值必須與父表中的現有值匹配或者爲 NULL。
- 外鍵基於數據值,是純邏輯指針,而不是實際指針。
- 外鍵是在子表中定義的,而包含被引用列的表是父表。外鍵是使用以下關鍵字組合定義的:
- FOREIGN KEY 用於在表約束級別上定義子表中的列。
- REFERENCES 用於標識父表中的表和列。
- ON DELETE CASCADE 指明當刪除父表中的行時,也將同時刪除子表中的相關行。
- ON DELETE SET NULL 在刪除父值時將外鍵值轉換爲空值。
示例中,DEPARTMENT_ID 定義爲表EMPLOYEES(相關表或子表)中的外鍵,它將引用表 DEPARTMENTS(被引用表或父表)的DEPARTMEINT_ID 列。
CREATE TABLE employees(
employee_id NUMBER(6),
last_name VARCHAR2(25) NOT NULL,
email VARCHAR2(25),
salary NUMBER(8,2),
commission_pct NUMBER(2,2),
hire_date DATE NOT NULL,
...
department_id NUMBER(4),
CONSTRAINT emp_dept_fk FOREIGN KEY (department_id)
REFERENCES departments(department_id),
CONSTRAINT emp_email_uk UNIQUE(email));
CHECK 約束
- 用於定義每行都必須滿足的一個條件
- 以下表達式是不允許的:
- 對 CURRVAL、NEXTVAL、LEVEL 和 ROWNUM 僞列的引用
- 對 SYSDATE、UID、USER 和 USERENV 函數的調用
- 涉及到其它行中的其它值的查詢
..., salary NUMBER(2)
CONSTRAINT emp_salary_min
CHECK (salary > 0),...
添加 約束語法
- 使用 ALTER TABLE 語句可以執行以下任務:
- 添加或刪除約束,但不修改它的結構
- 啓用或禁用約束
- 使用 MODIFY 子句添加 NOT NULL 約束
ALTER TABLE table
ADD [CONSTRAINT constraint] type (column);
- table 是表的名稱
- constraint 是約束的名稱
- type 是約束類型
- column 是受約束影響的列的名稱
示例將在 EMPLOYEES 表上創建一個 FOREIGN KEY 約束。該約束確保經理作爲一個有效的員工存在於 EMPLOYEES 表中
ALTER TABLE employees
ADD CONSTRAINT emp_manager_fk
FOREIGN KEY(manager_id)
REFERENCES employees(employee_id);
刪除 約束
- 要刪除約束,您可以從USER_CONSTRAINTS 和 USER_CONS_COLUMNS 數據字典視圖中確定約束名。
- 然後在 ALTER TABLE 語句中使用 DROP 子句。
- 如果在 DROP 子句中使用 CASCADE 選項,將同時刪除所有相關的約束。
ALTER TABLE table
DROP PRIMARY KEY | UNIQUE (column) |
CONSTRAINT constraint [CASCADE];
- table 是表的名稱
- column 是受約束影響的列的名稱
- constraint 是約束的名稱
從 EMPLOYEES 表中刪除經理約束
ALTER TABLE employees
DROP CONSTRAINT emp_manager_fk;
刪除 DEPARTMENTS 表上的 PRIMARY KEY 約束,並刪除 EMPLOYEES.DEPARTMENT_ID 列上關聯的 FOREIGN KEY 約束
ALTER TABLE departments
DROP PRIMARY KEY CASCADE;
禁用 約束
- 執行 ALTER TABLE 語句的 DISABLE 子句可以停用完整性約束。
- 應用 CASCADE 選項可以禁用相關的完整性約束。
ALTER TABLE table
DISABLE CONSTRAINT constraint [CASCADE];
- table 是表的名稱
- constraint 是約束的名稱
- 在 CREATE TABLE 語句和 ALTER TABLE 語句中都可以使用 DISABLE 子句。
- CASCADE 子句將禁用相關的完整性約束。
- 禁用唯一關鍵字或主鍵約束將會刪除唯一索引。
ALTER TABLE employees
DISABLE CONSTRAINT emp_emp_id_pk CASCADE;
啓用 約束
- 使用 ENABLE 子句可以激活表定義中當前禁用的完整性約束。
- 如果啓用了UNIQUE 關鍵字或 PRIMARY KEY 約束,系統會自動創建一個 UNIQUE 或 PRIMARY KEY 索引。
ALTER TABLE table
ENABLE CONSTRAINT constraint;
- table 是表的名稱
- constraint 是約束的名稱
ALTER TABLE employees
ENABLE CONSTRAINT emp_emp_id_pk;
級聯 約束
- CASCADE CONSTRAINTS 子句是和 DROP COLUN 子句一起使用的。
- CASCADE CONSTRAINTS 子句會刪除涉及到在已刪除列上定義的主鍵或唯一關鍵字的所有引用完整性約束。
- CASCADE CONSTRAINTS 子句還將刪除在已刪除列上定義的所有多列約束。
下面的語句說明了 CASCADE CONSTRAINTS 子句的用法。假設用下面的語句創建了表 TEST1:
CREATE TABLE test1 (
pk NUMBER PRIMARY KEY,
fk NUMBER,
col1 NUMBER,
col2 NUMBER,
CONSTRAINT fk_constraint FOREIGN KEY (fk) REFERENCES test1,
CONSTRAINT ck1 CHECK (pk > 0 and col1 > 0),
CONSTRAINT ck2 CHECK (col2 > 0));
以下語句會返回錯誤:
ALTER TABLE test1 DROP (pk);
pk是一個父鍵
ALTER TABLE test1 DROP (col1);
col1 被多列約束 ck1 所引用
提交下面的語句將刪除列PK、主鍵約束、fk_constraint外鍵約束和檢查約束CK1:
ALTER TABLE test1
DROP (pk) CASCADE CONSTRAINTS;
如果已刪除列上定義的約束所引用的所有列也已被刪除,則不需要使用CASCADE CONSTRAINTS。例如,假設其它表的其它引用約束都不涉及PK列,則提交以下沒有CASCADE CONSTRAINTS子句的語句是有效的:
ALTER TABLE test1
DROP (pk, fk, col1) CASCADE CONSTRAINTS;
查看 約束
查詢 USER_CONSTRAINTS 表可以查看所有約束定義和名稱
SELECT constraint_name, constraint_type,
search_condition
FROM user_constraints
WHERE table_name = 'EMPLOYEES';
在 USER_CON_SCOLUMNS 視圖中查看與約束名關聯的列
SELECT constraint_name, column_name
FROM user_cons_columns
WHERE table_name = 'EMPLOYEES';
第11章:創建視圖
數據庫對象
對象 | 說明 |
---|---|
表 | 基本的存儲單元;由行和列組成 |
視圖 | 在邏輯上代表來自一個或多個表的數據的子集 |
序列 | 生成主鍵值 |
索引 | 提高某些查詢的性能 |
同義詞 | 對象的替代名稱 |
什麼是 視圖
- 通過創建表的視圖可以顯示數據的邏輯子集或組合。
- 視圖是基於表或另一個視圖的邏輯表。
- 視圖沒有自己的數據,但它如同一個窗口,通過它可以查看或更改表中的數據。
- 視圖所基於的表稱爲基表。
- 視圖以 SELECT 語句的形式存儲在數據字典中。
視圖 的 作用
- 限制數據訪問
- 使複雜的查詢變得容易
- 提供數據獨立性
- 提供相同數據的不同視圖
視圖 的 優點
- 由於視圖能夠選擇性地顯示錶中的列,因而可以限制對數據的訪問。
- 視圖可以用來進行簡單的查詢,從而檢索複雜查詢的結果。
- 例如,用戶可以通過視圖查詢多個表中的信息,而無需瞭解如何編寫聯結語句。
- 視圖可以爲即席用戶和應用程序提供數據獨立性。可以用一個視圖檢索多個表中的數據。
- 視圖支持用戶組根據其特定標準來訪問數據。
簡單視圖 和 複雜視圖
特性 | 簡單視圖 | 複雜視圖 |
---|---|---|
表的數量 | 一個 | 一個或多個 |
是否包含函數 | 否 | 是 |
是否包含數據組 | 否 | 是 |
能否通過視圖執行 DML 操作 | 能 | 不一定 |
- 簡單視圖有如下特點:
- 只從一個表中導出數據
- 不包含函數或數據組
- 可以通過該視圖執行DML操作
- 複雜視圖有如下特點:
- 從多個表中導出數據
- 包含函數或數據組
- 不一定能夠通過該視圖執行DML操作
創建 視圖
- 定義視圖的子查詢可以包含複雜的 SELECT 語法,包括聯結、分組和子查詢。
- 定義視圖的子查詢不能包含 ORDER BY 子句。ORDER BY子句是在從視圖中檢索數據時指定的。
- 如果您不爲用 WITH CHECK OPTION 創建的視圖指定約束名,系統會以 SYS_Cn 格式指定一個默認名稱。
- 可以使用 OR REPLACE 選項更改視圖定義,而不必先刪除再重新創建它,也不必重新授予以前授予它的對象權限。
創建視圖 EMPVU80,該視圖要包含部門 80 中員工的詳細信息
CREATE VIEW empvu80
AS SELECT employee_id, last_name, salary
FROM employees
WHERE department_id = 80;
DESCRIBE empvu80
示例創建了一個視圖,其中包含部門 50 中每位員工的員工編號(EMPLOYEE_ID)、姓名(LAST_NAME)和年薪(SALARY);員工編號、姓名和年薪的分別使用了別名 ID_NUMBER、NAME 和 ANN_SALARY。
CREATE VIEW salvu50
AS SELECT employee_id ID_NUMBER, last_name NAME,
salary*12 ANN_SALARY
FROM employees
WHERE department_id = 50;
從 視圖 中檢索 數據
- 可以從視圖中檢索數據,就像從任何表中檢索數據一樣。
- 可以顯示整個視圖的內容,也可以只顯示特定的行或列。
SELECT *
FROM salvu50;
查詢 視圖
SELECT *
FROM empvu80;
等效於:
SELECT employee_id,
last_name, salary
FROM employees
WHERE department_id=80;
- 當使用視圖訪問數據時,Oracle 服務器將執行下列操作:
- 它從 USER_VIEWS 數據字典表中檢索視圖定義。
- 它檢查視圖基表的訪問權限。
- 它將視圖查詢轉換成對基表的等同操作。也就是說,數據從基表中檢索,或對基表進行更新。
修改 視圖
使用 CREATE OR REPLACEVIEW子句修改 EMPVU 80 視圖。爲每個列名添加一個別名。
CREATE OR REPLACE VIEW empvu80
(id_number, name, sal, department_id)
AS SELECT employee_id, first_name || ' ' || last_name,
salary, department_id
FROM employees
WHERE department_id = 80;
創建 複雜 視圖
CREATE VIEW dept_sum_vu
(name, minsal, maxsal, avgsal)
AS SELECT d.department_name, MIN(e.salary),
MAX(e.salary),AVG(e.salary)
FROM employees e, departments d
WHERE e.department_id = d.department_id
GROUP BY d.department_name;
在 視圖 上執行 DML 操作的 規則
- 可以在簡單視圖上執行 DML 操作。
- 如果視圖包含以下內容,則不能刪除行:
- 分組函數
- GROUP BY 子句
- DISTINCT 關鍵字
- 僞列 ROWNUM 關鍵字
- 如果視圖包含以下內容,則不能在視圖中修改數據:
- 分組函數
- GROUP BY 子句
- DISTINCT 關鍵字
- 僞列 ROWNUM 關鍵字
- 由表達式定義的列
- 如果視圖包含以下內容,則不能通過視圖添加數據:
- 分組函數
- GROUP BY 子句
- DISTINCT 關鍵字
- 僞列 ROWNUM 關鍵字
- 由表達式定義的列
- 基表中未被視圖選中的 NOT NULL 列
使用 WITH CHECK OPTION 子句
使用 WITH CHECK OPTION 子句可以確保在視圖上執行的 DML 操作發生在視圖的範圍內。
CREATE OR REPLACE VIEW empvu20
AS SELECT *
FROM employees
WHERE department_id = 20
WITH CHECK OPTION CONSTRAINT empvu20_ck ;
拒絕 DML 操作
- 通過在視圖定義中添加 WITH READ ONLY 選項可以確保不能執行 DML 操作。
- 任何對視圖中的行執行 DML 的嘗試都會導致 Oracle 服務器錯誤。
CREATE OR REPLACE VIEW empvu10
(employee_number, employee_name, job_title)
AS SELECT employee_id, last_name, job_id
FROM employees
WHERE department_id = 10
WITH READ ONLY;
刪除 視圖
- 因爲視圖是基於數據庫中的基表,所以刪除視圖不會導致丟失數據。
DROP VIEW empvu80;
內聯 視圖
- 內聯視圖是帶有可以在 SQL 語句中使用的別名(或相關名稱)的子查詢。
- 主查詢 FROM 子句中的命名子查詢就是一個內聯視圖實例。
- 內聯視圖不是方案對象。
SELECT a.last_name, a.salary, a.department_id, b.maxsal
FROM employees a, (SELECT department_id, max(salary) maxsal
FROM employees
GROUP BY department_id) b
WHERE a.department_id = b.department_id
AND a.salary < b.maxsal;
排序 Top-N 分析
- 排序 Top-N 查詢可以獲得某個列的 n 個最大或 n 個最小值。例如:
- 最暢銷的前 10 種產品是什麼?
- 最滯銷的前 10 種產品是什麼?
- 最大值和最小值的集都被稱爲排序 Top-N 查詢。
- 排序 Top-N 查詢使用一致的具有以下元素的嵌套查詢結構:
- 子查詢或內聯視圖,用於生成排序的數據列表。子查詢或內聯視圖包含 ORDER BY 子句,用以確保按照所需順序排列。對於檢索最大值的結果,需要使用 DESC 參數。
- 外部查詢,用於限制最終結果集的行數。外部查詢包括以下組成部分:
- ROWNUM 僞列,爲子查詢返回的每一行指定一個順序值,值從1開始。
- WHERE 子句,指定返回 n 行。外部 WHERE 子句必須使用<或<=運算符
SELECT ROWNUM as RANK, last_name, salary
FROM (SELECT last_name,salary FROM employees
ORDER BY salary DESC)
WHERE ROWNUM <= 3;
第12章:其他數據庫對象
- 序列具有以下特性:
- 自動生成唯一編號
- 是一個可共享的對象·通常用於創建主鍵值
- 替換應用程序代碼
- 如果將序列高速緩存到內存中,則可以提高訪問序列值的效率
CREATE SEQUENCE 語句
CREATE SEQUENCE sequence
[INCREMENT BY n]
[START WITH n]
[{MAXVALUE n | NOMAXVALUE}]
[{MINVALUE n | NOMINVALUE}]
[{CYCLE | NOCYCLE}]
[{CACHE n | NOCACHE}];
- sequence 是序列生成器的名稱
- INCREMENTBY n 指定序列號之間的間隔,其中 n 是一個整數(如果省略此子句,則序列每次遞增1)
- STARTWITH n 指定生成的第一個序列號(如果省略此子句,則序列從 1 開始)
- MAXVALUE n 指定序列可以生成的最大值
- NOMAXVALUE 指定 1027 作爲遞增序列的最大值,-1 作爲遞減序列的最大值(這是默認選項)
- MINVALUE n 指定序列的最小值
- NOMINVALUE 指定 1 作爲遞增序列的最小值,-1026 作爲遞減序列的最小值(這是默認選項)
- CYCLE | NOCYCLE 指定在達到最大值或最小值之後,序列是否繼續生成值(NOCYCLE是默認選項)
- CACHE n | NOCACHE 指定 Oracle 服務器預先分配並保留在內存中的值的數量(在默認情況下,Oracle 服務器高速緩存 20 個值)
創建一個名爲 DEPT_DEPTID_SEQ 的序列,將它用作表 DEPARTMENTS 的主鍵(不使用CYCLE選項)
CREATE SEQUENCE dept_deptid_seq
INCREMENT BY 10
START WITH 120
MAXVALUE 9999
NOCACHE
NOCYCLE;
在 USER_SEQUENCES 數據字典表中驗證序列值
SELECT sequence_name, min_value, max_value,
increment_by, last_number
FROM user_sequences;
LAST NUMBER 列將顯示下一個可用的序列號(如果指定了 NOCACHE )
NEXTVAL 和 CURRVAL 僞列
- NEXTVAL 會返回下一個可用的序列值。每次被引用時它都會返回一個唯一的值,即使對於不同的用戶也是這樣。
- CURRVAL 會獲得當前序列值。
- 必須對該序列發出 NEXTVAL,然後 CURRVAL 才能包含值。
- 您可以在以下上下文中使用 NEXTVAL 和 CURRVAL :
- 不屬於子查詢一部分的 SELECT 語句的 SELECT 列表
- INSERT 語句中的子查詢的 SELECT 列表
- INSERT 語句的 VALUES 子句
- UPDATE 語句的 SET 子句
- 您不能在以下上下文中使用 NEXTVAL 和 CURRVAL :
- 視圖的 SELECT 列表
- 帶有 DISTINCT 關鍵字的 SELECT 語句
- 帶有 GROUP BY、HAVING 或 ORDER BY 子句的 SELECT 語句
- SELECT、DELETE 或 UPDATE 語句中的子查詢
- CREATE TABLE 或 ALTER TABLE語句中的 DEFAULT 表達式
在地點標識 2500 中插入一個名爲 “Support” 的新部門
INSERT INTO departments(department_id,
department_name, location_id)
VALUES (dept_deptid_seq.NEXTVAL,
'Support', 2500);
查看 DEPT_DEPTID_SEQ 序列的當前值
SELECT dept_deptid_seq.CURRVAL
FROM dual;
- 在內存中高速緩存序列值可以更快地訪問那些值。
- 當發生以下情況時,序列值會出現間斷:
- 發生回退
- 系統崩潰
- 在其它表中使用了序列
- 如果創建序列時使用了 NOCACHE 選項,可以通過查詢 USER_SEQUENCES 表來查看下一個可用的值。
修改序列
- 更改增量值、最大值、最小值、循環選項或高速緩存選項
ALTER SEQUENCE dept_deptid_seq
INCREMENT BY 20
MAXVALUE 999999
NOCACHE
NOCYCLE;
- 您必須是序列的所有者或對該序列具有 ALTER 權限。
- 修改只會影響以後生成的序列號。
- 如果要從不同的序號處重新開始,則必須刪除原有的序列然後重新創建。
- 系統會執行一些驗證操作。
刪除序列
- 通過使用 DROP SEQUENCE 語句可以從數據字典中刪除序列。
- 序列一旦刪除,就不能再引用它。
DROP SEQUENCE dept_deptid_seq;
創建索引
- 索引具有以下特性:
- 它是一個方案對象
- Oracle 服務器使用它來加速用指針對行的檢索
- 可以通過使用快速路徑訪問方法來快速查找數據,從而減少磁盤 I/O 操作
- 與它索引的表無關
- 由 Oracle 服務器自動使用和維護
- 創建索引
- 自動創建:如果您在表定義中定義了 PRIMARY KEY 或 UWIQUE 約束,則系統會自動創建一個唯一索引。
- 手動創建:用戶可以在列上創建非唯一的索引,以加速對行的訪問。
- 提高對錶 EMPLOYEES 的 LAST_NAME 列的查詢訪問速度。
CREATE INDEX emp_last_name_idx
ON employees(last_name);
- 需要創建索引的情況
- 列包含較大範圍的值
- 列包含大量空值
- 在 WHERE 子句或聯結條件中頻繁使用一個或多個列
- 表相當大,但是預計多數的查詢檢索的行不到總行數的百分之二至百分之四
- 不用創建索引的情況
- 表比較小
- 在查詢中不經常使用列作爲條件
- 預計多數查詢檢索的行要超過表中總行數的百分之二至百分之四
- 表更新比較頻繁
- 被索引的列將作爲表達式的一部分進行引
- 確認索引
- USER INDEXES 數據字典視圖包含索引的名稱及其唯一性。
- USER_IND_COLUMNS 視圖包含索引名、表名和列名。
SELECT ic.index_name, ic.column_name,
ic.column_position col_pos,ix.uniqueness
FROM user_indexes ix, user_ind_columns ic
WHERE ic.index_name = ix.index_name
AND ic.table_name = 'EMPLOYEES';
基於函數的索引
- 基於函數的索引就是基於表達式的索引。
- 索引表達式是用表列、常數、SQL函數和自定義函數構建的。
CREATE INDEX upper_dept_name_idx
ON departments(UPPER(department_name));
SELECT *
FROM departments
WHERE UPPER(department_name) = 'SALES';
刪除索引
- 使用 DROP INDEX 命令可以從數據字典中刪除索引。
- 從數據字典中刪除 UPPER LAST NAME IDX 索引。
DROP INDEX upper_last_name_idx;
- 要刪除索引,您必須是該索引的所有者或者具有 DROP ANY INDEX 權限。
同義詞
- 通過創建同義詞(對象的另一個名稱)可以簡化對對象的訪問。使用同義詞具有以下優點:
- 易於引用其他用戶所擁有的表
- 縮短冗長的對象名
- 該對象不能包含在程序包中。
- 私用同義詞名必須與同一用戶擁有的所有其它對象都不同。
創建 和 刪除 同義詞
- 爲 DEPT_SUM_VU 視圖創建一個簡短的名稱
CREATE SYNONYM d_sum
FOR dept_sum_vu;
- 刪除同義詞
DROP SYNONYM d_sum;
第13章:控制用戶訪問
權限
- 數據庫安全性:
- 系統安全性-數據安全性
- 系統權限:獲得訪問數據庫的權限
- 對象權限:處理數據庫對象的內容
- 方案:對象的集合,例如表、視圖和序列的集合
系統權限
- 可用的系統權限超過100個。
- 系統管理員對於諸如以下的任務具有高級別的系統權限:
- 創建新用戶
- 刪除用戶
- 刪除表-備份表
常見的 DBA 權限
系統權限 | 授權的操作 |
---|---|
CREATE USER | 被授予者可以創建其他Oracle用戶(DBA角色所需的權限) |
DROP USER | 被授予者可以刪除另一位用戶。 |
DROP ANY TABLE | 被授予者可以從任何方案中刪除表。 |
BACKUP ANY TABLE | 被授予者可以用導出實用程序備份任何方案中的任何表。 |
SELECT ANY TABLE | 被授予者可以查詢任何方案中的表、視圖或快照。 |
CREATE ANY TABLE | 被授予者可以在任何方案中創建表。 |
創建用戶
- DBA 可以使用 CREATE USER 語句創建用戶。
CREATE USER user
IDENTIFIED BY password;
- user 是要創建的用戶名
- password 指定該用戶登錄所需的口令
CREATE USER scott
IDENTIFIED BY tiger;
用戶系統權限
- 一旦創建了用戶,DBA 就可以將特定的系統權限授予該用戶
系統權限 | 授權的操作 |
---|---|
CREATE SESSION | 連接到數據庫 |
CREATE TABLE | 在用戶方案中創建表 |
CREATE SEQUENCE | 在用戶方案中創建序列 |
CREATE VIEW | 在用戶方案中創建視圖 |
CREATE PROCEDURE | 在用戶方案中創建存儲過程、函數或程序包 |
- DBA 可以將特定的系統權限授予用戶
示例中,DBA 將創建會話、表、序列和視圖的權限授予用戶 Scott
GRANT create session, create table,
create sequence, create view
TO scott;
創建角色
- 角色是可以授予用戶的相關權限的指定組
- 此方法使得撤消和維護權限變得更容易
- 一個用戶可以訪問幾個角色,而同一角色也可以分配給幾個用戶。
- 角色通常是爲數據庫應用程序創建的
- 首先,DBA 必須創建角色。
- 然後,DBA 可以將權限分配給角色,再將用戶分配給角色。
語法:
CREATE ROLE role;
role 爲要創建的角色
創建角色
CREATE ROLE manager;
將權限授予角色
GRANT create table, create view
TO manager;
將角色授予用戶
GRANT manager TO DEHAAN, KOCHHAR;
更改口令
- DBA 會創建您的用戶帳戶,併爲您初始設置一個口令
- 您可以使用 ALTER USER 語句來更改口令
語法:
ALTER USER user IDENTIFIED BY password;
user 是用戶名
password 指定新口令
改 scott 用戶的口令爲 lion
ALTER USER scott
IDENTIFIED BY lion;
對象權限
對象權限 | 表 | 視圖 | 序列 | 過程 |
---|---|---|---|---|
ALTER | √ | √ | ||
DELETE | √ | √ | ||
EXECUTE | √ | |||
INDEX | √ | |||
INSERT | √ | √ | ||
REFERENCES | √ | √ | ||
SELECT | √ | √ | √ | |
UPDATE | √ | √ |
- 對象權限會根據對象的不同而變化
- 對象的所有者對其具有全部權限
- 所有者可以將屬於他的對象的權限授予其他用戶
語法:
GRANT object_priv [(columns)]
ON object
TO {user|role|PUBLIC}
[WITH GRANT OPTION];
object_priv 是要授予的對象權限
ALL 指定所有的對象權限
columns 指定授予權限的表或視圖中的列
ON object 是授予權限的對象
TO 說明權限授給誰
PUBLIC 將對象權限授予所有用戶
WITH GRANT OPTION 允許被授予者將對象權限授予其他用戶和角色
授予對 EMPLOYEES 表的查詢權限
GRANT select
ON employees
TO sue, rich;
將更新特定列的權限授予用戶和角色
GRANT update (department_name, location_id)
ON departments
TO scott, manager;
- 要授予對某個對象的權限,則該對象必須在您自己的方案中,或者您必須被授予了 WITH GRANT OPTION 對象權限。
- 對象所有者可以將對該對象的任何對象權限授予數據庫的任何其他用戶或角色。
- 對象所有者會自動獲得對該對象的所有對象權限。
使用 WITH GRANT OPTION 和 PUBLIC 關鍵字
- 使用 WITH GRANT OPTION 子句授予的權限可以由被授予者授予其他用戶和角色。如果撤消了授予者的權限,則使用 WITH GRANT OPTION 子句授予的對象權限也將被撤消。
- 表的所有者可以使用 PUBLIC 關鍵字將訪問權限授予所有用戶
示例授予了用戶 Scott 對您的 DEPARTMENTS 表進行查詢和向表中添加行的權限。該示例還允許 Scott 將這些權限授予其他用戶。
GRANT select, insert
ON departments
TO scott
WITH GRANT OPTION;
示例允許系統上的所有用戶查詢 Alice 的 DEPARTMEINTS 表中的數據
GRANT select
ON alice.departments
TO PUBLIC;
確認授予的權限
- 如果您試圖執行未授權的操作,例如在對某個表沒有 DELETE 權限的情況下,要從該表中刪除一行,那麼 Oracle 服務器將禁止執行此操作。
- 如果您收到 Oracle 服務器返回的
“table or view does not exist”
錯誤消息,則表明您執行了以下操作之一:- 指定了不存在的表或視圖
- 嘗試對您不具有相應權限的表或視圖執行某個操作
- 您可以訪問數據字典來查看您具有的權限。
數據字典視圖
數據字典視圖 | 說明 |
---|---|
ROLE_SYS_PRIVS | 授予角色的系統權限 |
ROLE_TAB_PRIVS | 授予角色的表權限 |
USER_ROLE_PRIVS | 用戶可以訪問的角色 |
USER_TAB_PRIVS_MADE | 授予的對用戶對象的對象權限 |
USER_TAB_PRIVS_RECD | 授予用戶的對象權限 |
USER_ COL_PRIVS_MADE | 授予的對用戶對象的列的對象權限 |
USER_COL_PRIVS_RECD | 授予用戶的對特定列的對象權限 |
USER_SYS_PRIVS | 列出授予用戶的系統權限 |
撤消對象權限
- 使用 REVOKE 語句可以撤消授予其他用戶的權限。
- 通過 WITH GRANT OPTION 子句授予其他用戶的權限也會被撤消。
語法:
REVOKE {privilege [, privilege...]|ALL}
ON object
FROM {user[, user...]|role|PUBLIC}
[CASCADE CONSTRAINTS];
CASCADE 如果要刪除通過 REFERENCES 權限對該對象實行的
CONSTRAINTS 任何引用完整性約束,則此選項是必需的
作爲用戶 Alice,撤消授予用戶 Scott 對 DEPARTMENTS 表的 SELECT 和 INSERT 權限
REVOKE select, insert
ON departments
FROM scott;
數據庫鏈接
- 一旦創建了數據庫鏈接,您就可以編寫針對遠程站點上的數據的SQL語句。
如果設置了同義詞,則可以使用該同義詞編寫SOL語句。 - 您不能授予其他用戶對遠程對象的權限
創建數據庫鏈接,USING 子句標識遠程數據庫的服務名稱
CREATE PUBLIC DATABASE LINK hq.acme.com
USING 'sales';
編寫使用數據庫鏈接的SQL語句
SELECT *
FROM emp@HQ.ACME.COM;