SQL 分類
資料定義語言(DDL):用於建立、修改和刪除資料庫物件。
DDL的核心指令是:
- CREATE:建立表或其他物件。
- ALTER:修改表或其他物件。
- DROP:刪除表或其他物件。
- TRUNCATE:刪除表資料,保留表結構
-- Create table
create table STUDENT
(
sid VARCHAR2(10),
sname VARCHAR2(10),
sage VARCHAR2(255),
ssex VARCHAR2(10)
)
tablespace DEMO
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
-- Add comments to the table
comment on table STUDENT
is '學生表';
-- Add comments to the columns
comment on column STUDENT.sid
is '學生編號';
comment on column STUDENT.sname
is '學生姓名';
comment on column STUDENT.sage
is '出生年月';
comment on column STUDENT.ssex
is '學生性別';
修改表名:
RENAME 原始表名 TO 新表名;
增加列:
ALTER TABLE STUDENT ADD(AAC058 VARCHAR2(10));
刪除列:
ALTER TABLE STUDENT DROP(AAC058);
刪除所有表資料,表結構保留:
TRUNCATE TABLE STUDENT;
刪除表:
DROP TABLE STUDENT;
資料操縱語言(DML):用於改變資料表中的資料,和事務相關。
DML的核心指令(即增刪改查)是:
-
INSERT:將資料插入資料表中
INSERT INTO STUDENT VALUES ('09', '張三', '1994-01-04', '男');
-
UPDATE:更新資料表中的資料
UPDATE STUDENT SET ssex='女' WHERE sid = '01';
-
DELETE:刪除表中的資料
DELETE FROM STUDENT WHERE sid = '01';
清空表中的資料:
TRUNCATE TABLE STUDENT;
-
SELECT:查詢表中的資料
SELECT * FROM STUDENT
-- 返回前 5 行 SELECT * FROM STUDENT LIMIT 5; SELECT * FROM STUDENT LIMIT 0, 5; -- 返回第 3 ~ 5 行 SELECT * FROM STUDENT LIMIT 2, 3;
SELECT DISTINCT SSEX FROM STUDENT;
事務控制語言(TCL):用於維護資料一致性
TCL的核心指令是:
- COMMIT:提交
- ROLLBACK:回滾
- SAVEPOINT:儲存點
資料控制語言(DCL):用於執行許可權的授予與回收工作
DCL:的核心指令是
- GRANT:授權
- REVOKE:回收使用者或角色許可權
SQL 子查詢
- 子查詢可以巢狀在SELECT,INSERT,UPDATE,DELETE*語句內或另一個子查詢中
- 子查詢通常會在另一個SELECT語句的WHERE子句中新增
- 可以使用比較運算子>,<,=。也可以是多行運算子IN,ANY,ALL
- 子查詢必須被圓括號()括起來
- 內部查詢首先在其父查詢之前執行,以便可以將內部查詢的結果傳遞給外部查詢
子查詢的子查詢
SELECT CUST_NAME, CUST_CONTACT
FROM CUSTOMERS
WHERE CUST_ID IN
(SELECT CUST_ID
FROM ORDERS
WHERE ORDER_NUM IN
(SELECT ORDER_NUM FROM ORDERITEMS WHERE PROD_ID = 'RGAN01'));
WHERE
- WHERE 子句用於過濾記錄
- WHERE 後跟一個返回true或false的條件
- WHERE 可以與SELECT、UPDATE、DELETE一起使用
- 可以在 WHERE 子句中使用操作符
運算子 | 描述 |
---|---|
= | 等於 |
<> | 不等於 |
> | 大於 |
< | 小於 |
>= | 大於等於 |
<= | 小於等於 |
BETWEEN | 在某個範圍內 |
LIKE | 搜尋某種模式 |
IN | 指定對某個列的多個可能值 |
IN ,NOT IN
-- IN:範圍內,NOT IN:不在這個範圍內
SELECT *
FROM SC
WHERE SCORE IN ('80', '90');
BETWEEN AND
SELECT *
FROM SC
WHERE score BETWEEN 60 AND 80;
AND、OR、NOT
- AND、OR、NOT 是用於對過濾條件的邏輯處理指令
- AND 優先順序高於 OR,為了明確處理順序,可以使用()
- AND 操作符表示左右條件都要滿足
- OR 操作符表示左右條件滿足任意一個
- NOR 操作符用於否定一個條件
ANY,ALL
需要判斷內容>、>=、<、<= 列表中的多個值,需要結合 ANY 或 ALL 來使用。
ANY(LIST):大於列表中其中之一即可,即大於最小的
ALL(LIST):大於列表中所有,即大於最大的
SELECT * FROM SC WHERE SCORE > ANY(SELECT SCORE FROM SC WHERE CID='01')
ORDER BY:按照指定的欄位的值進行升序或者降序進行排序。
- ASC:升序,預設升序
- DESC:降序
-- 學生成績降序
select t.*, t.rowid from SC t ORDER BY score DESC;
假如排序的欄位中有 NULL 值, NULL 會被視為最大值。當多個欄位進行排序時,每個欄位可以分別指定升降序,並且排序順序按照第一個欄位優先排序,以此類推。
聚合函式(分組函式、組函式):聚合函式是忽略 NULL 值的
-
MAX 和 MIN:獲取列或表示式的最大、最小值,可以統計任何資料型別。
-- 查詢最高成績和最低成績 SELECT MAX(score),MIN(score) FROM SC;
-
AVG 和 SUM:統計列或表示式的平均值和和值,只能運算元據型別,並且忽略 NULL 值。
-- 學生的平均成績和總成績 SELECT AVG(score) avg_score,SUM(score) sum_score from SC;
-
COUNT:統計表中的記錄條數,忽略 NULL 值。
SELECT COUNT(*) from SC;
分組
-
GROUP BY 子句:是為聚合函式服務的,可以統計資料時細化分組,允許將某個欄位值一樣的記錄看成一組,然後進行統計。
- group by 子句將記錄分組彙總行中
- group by 為每個組返回一個記錄
- group by 通常還涉及聚合:count、max、sum、avg等
- group by 可以按一列或多列進行分組
- group by 按分組欄位進行排序後,order by 可以彙總欄位來進行排序
SELECT cid FROM sc GROUP BY cid;
-
HAVING 字句:用於新增過濾條件,是在統計結果之後進行過濾,不能獨立出現,必須跟在 group by 子句後面
- having 用於對彙總的group by 結果進行過濾
- having 要求存在一個 group by 子句
- where 和 having 可以在相同的查詢中
SELECT score FROM sc GROUP BY score HAVING(score) > 80;
查詢語句的執行順序
- from 子句:從後往前、從左到右,資料量少的表儘量放在後面
- where 子句:自傷而下、從右到左。能過濾掉最大數量記錄的條件寫在where的最右
- group by:從左往右分組,最好在group by 前使用where將不需要的記錄在group by 之前過濾掉
- having 子句:消耗資源,儘量避免使用。會檢索出所有記錄之後才對結果集過濾,需要排序等操作
- select 子句:少用 * 號,儘量取欄位名。
- order by 子句:從左到右排序,消耗資源
SQL 關聯查詢
內連線 (INNER JOIN):也稱為等值連線,返回兩張表都滿足條件的部分
註釋:inner join 等於 join
innerjoin
SELECT * FROM student a INNER JOIN sc b ON a.sid=b.sid
外連線 (out join):不僅返回滿足連線條件的記錄,還將返回不滿足條件的記錄。
-
左外連線:取左邊的表全部,右邊的表按條件,符合的顯示,不符合則顯示 null
leftjoin
-
右外連線:取右邊的表全部,左邊的表按條件,符合的顯示,不符合則顯示 null
rightjoin
-
全外連線
註釋:left outer join 與left join 等價,一般寫成 left join
right outer join 與right join 等價,一般寫成right join
自連線
SELECT * FROM student a , student b WHERE a.sname = b.sname
自然連線
SELECT * FROM student a NATURAL JOIN sc
SQL 函式
ROW_NUMBER:生成組內連續且唯一的數字
RANK:生成不連續不唯一的數字排序欄位相同的記錄,得到的數字一樣後續內容會根據重複的行數自動跳號
DENSE_RANK():生成連續但不唯一的數字
UNION
- union 運算子將兩個或更多查詢的結果組合起來,並生成一個結果集
- union 規則
- 所有查詢的列數和列順序必須相同
- 每個查詢中涉及表的列的資料型別必須相同或相容
- 通常返回的列名取第一個查詢
- 預設會去除相同行,如果需要保留相同行,使用 union all
- 只能包含一個 order by 子句,並且必須位於語句的最後
SELECT * FROM student a
UNION
SELECT * FROM student_bak
UNION 和 UNION ALL:用來獲取兩個或兩個以上結果集的並集(結果集的列必須一一對應)
-
UNION 操作符會自動去掉合併後的重複記錄
-
UNION ALL 返回兩個結果集中的所有行,包括重複的行
-
UNION 操作符對查詢結果排序,UNION ALL 不排序
INTERSECT:獲得兩個結果集的交集,只有同時存在於兩個結果集中的資料才會被顯示輸出。INTERSECT操作符後的結果集會以第一列的資料做升序排序
MINUS:獲得兩個結果集的差集,只有在第一個結果集中存在,在第二個結果集中不存在的資料才能被顯示出來,就相當於結果集一減去結果集二的結果
SQL 檢視
檢視(VIEW)也被稱作虛表,即虛擬的表,是一組資料的邏輯表示,其本質是對應於一條SELECT語句,結果集被賦予一個名字,即檢視名字。檢視本身並不包含任何資料,它只包含對映到基表的一個查詢語句,當基表資料發生變化,檢視資料也隨之變化。
作用
- 簡化複雜的 SQL 操作,比如複雜的聯結;
- 只使用實際表的一部分資料;
- 通過只給使用者訪問檢視的許可權,保證資料的安全性;
- 更改資料格式和表示。
根據檢視所對應的子查詢種類分為幾種型別:
- SELECT語句是基於單表建立的,且不包含任何函式運算、表示式或分組函式,叫做簡單檢視,此時檢視是基表的子集;
- SELECT語句同樣是基於單表,但包含了單行函式、表示式、分組函式或GROUP BY子句,叫做複雜檢視;
- SELECT語句是基於多個表的,叫做連線檢視。
建立檢視
CREATE VIEW v_student
AS
SELECT SID,sname,sage,ssex
FROM student WHERE SID=01
修改檢視:由於檢視自身沒有結構,完全取決於對應的查詢語句,所以修改檢視就是替換對應的查詢語句。
CREATE OR REPLACE VIEW v_student
AS
SELECT SID,sname,sage,ssex
FROM student WHERE SID=02;
刪除檢視
DROP VIEW v_student
對檢視進行DML操作就是對檢視資料來源的基表進行操作。只能對簡單試圖進行DML操作,複雜檢視不允許DML操作,即檢視定義中包含了函式、表示式、分組語句、DISTINCT關鍵字或ROWNUM偽列,不允許執行DML操作。
-- 直接對檢視進行插入操作,查詢檢視是查詢不到插入的資料,查基表才能看到插入的資料
insert into v_student values(10,'薩達','1993-03-04','女');
建立具有 CHECK OPTION 約束的檢視
可以為檢視新增CHECK OPTION選項,這樣對檢視進行DML操作時,檢視會檢查操作完畢後對該記錄是否可見,可見不允許操作。
CREATE OR REPLACE VIEW v_student
AS
SELECT SID,sname,sage,ssex
FROM student
WHERE SID=02
WITH CHECK OPTION;
-- 建立完檢視後再插入資料
insert into v_student values(10,'薩達','1993-03-04','女');
-- 結果是報錯的:檢視WITH CHECK OPTION where 子句違規
建立具有 READ ONLY 約束的檢視
當檢視被設定為READ ONLY後,不允許對該檢視進行DML操作,其為只讀的。
CREATE OR REPLACE VIEW v_student
AS
SELECT SID,sname,sage,ssex
FROM student
WHERE SID=02
WITH READ ONLY;
-- 建立完檢視後再插入資料
insert into v_student values(10,'薩達','1993-03-04','女');
-- 結果:無法對只讀檢視執行 DML 操作
SQL 序列
序列是一個資料庫物件作用是根據指定的規則生成一組數字,每次返回一個數字。常用於為表中的主鍵提供值。
主鍵:通常每張表的第一個欄位就是主鍵,主鍵欄位的值要求在整張表中不能為空,且值不能重複。目的是用於唯一標識每一個記錄。
-- 建立起始資料是100,步進是1的序列
CREATE SEQUENCE student_seq
START WITH 100
INCREMENT BY 1;
序列的兩個偽列
- NEXTVAL:使序列生成一個數字,第一次使用時,返回的是START WITH指定的值。需要注意,序列不可逆,一旦獲取下一個數字後,就不能得到上一個數字了。
- CURRVAL:獲取序列最後一次生成的數字,可以呼叫多次,不會造成序列生成下一個數字。CURRVAL必須要在序列建立完畢後,至少呼叫過一側NEXTVAL輸出生成一個數字後才可以使用。
SQL 索引
索引也是資料庫物件,用來提高檢索效率,排序效率有效的使用可以帶來很好的效果。資料庫管理系統自行維護索引演算法。我們只需要指定何時為某表的某欄位新增即可。
注意:一個包含索引的表需要比更新一個沒有索引的表花費更多的時間,這是由於索引本身也需要更新。因此,理想的做法是僅僅在常常被搜尋的列(以及表)上面建立索引。
唯一索引:唯一索引表明此索引的每一個索引值只對應唯一的資料記錄。
建立索引
create index idx_student_id on student(SID);
建立唯一索引
CREATE UNIQUE INDEX idx_student_id
ON student (id);
複合索引
CREATE INDEX idx_student_id
ON student (id,sname);
刪除索引
DROP INDEX idx_student_id;
SQL 約束
- 如果存在違反約束的資料行為,行為會被約束終止。
- 約束可以在建立表時規定(通過 CREATE TABLE 語句),或者在表建立之後規定(通過 ALTER TABLE 語句)。
- 約束型別
- 非空約束(Not Null),簡稱NN,指示某列不能儲存 NULL 值。
- 唯一性約束(Unique),簡稱UK,保證某列的每行必須有唯一的值。
- 主鍵約束(Primary Key),簡稱PK, NOT NULL 和 UNIQUE 的結合。確保某列(或兩個列多個列的結合)有唯一標識,有助於更容易更快速地找到表中的一個特定的記錄。
- 外來鍵約束(Foreign Key),簡稱FK,保證一個表中的資料匹配另一個表中的值的參照完整性。
- 檢查約束(Check),簡稱CK,保證列中的值符合指定的條件。
SQL 事務
事務在資料庫中是工作的邏輯單元,單個事務是由一個或多個完成一組的相關行為的SQL語句組成,通過事務機制,可以確保這一組SQL語句所作的操作要麼都成功執行,完成整個工作單元操作,要麼一個也不執行。
事務的特性(ACID)
一組SQL語句操作要成為事務,資料庫管理系統必須保證這組操作的原子性(Atomicity)、一致性(consistency)、隔離性(Isolation)和永續性(Durability),這就是ACID特性。
- Atomicity (原子性):一個事務裡面所有包含的SQL語句都是一個整體,是不可分割的,要麼不做,要麼都做。
- Consistency (一致性):事務開始時,資料庫中的資料是一致的,事務結束時,資料庫的資料也應該是一致的。
- Isolation (隔離性):多個併發事務可以獨立執行,而不能相互干擾,一個事務修改資料未提交前,其他事務看不到它所做的更改。
- Durability (永續性):當事務結束後,它對資料庫中的影響是永久的,即便系統遇到故障的情況下,資料也不會丟失。
事務的相關語句
-- 設定事物屬性
Set transaction
-- 設定事物的約束模式:在事務中修改資料時,資料庫中的約束立即應用於資料,還是將約束推遲到當前事務結束後應用。
Set constrains
-- 在事務中建立一個儲存的點.當事務處理髮生異常而回滾事務時,可指定事務回滾到某儲存點.然後從該儲存點重新執行。
Savepoint
-- 刪除儲存點
Release savepoint
-- 取消對資料庫所作的任何操作
Rollback 回滾事務
-- 對資料庫的操作做持久的儲存。
Commit 提交事務
許可權控制
建立使用者
CREATE USER myuser IDENTIFIED BY 'mypassword';
修改使用者名稱
UPDATE user SET user='newuser' WHERE user='myuser';
FLUSH PRIVILEGES;
刪除使用者
DROP USER myuser;
檢視許可權
SHOW GRANTS FOR myuser;
授權
GRANT SELECT, INSERT ON *.* TO myuser;
刪除許可權
REVOKE SELECT, INSERT ON *.* FROM myuser;
更改密碼
SET PASSWORD FOR myuser = 'mypass';
儲存過程
- 儲存過程可以看成是對一系列sql操作的批處理
- 好處
- 程式碼封裝,保證一定的安全性
- 程式碼複用
- 因為是預先編譯,所以具有很高的效能
- 建立過程
- 命令列中建立儲存過程需要自定義分隔符,因為命令列是以
;
為結束符,而儲存過程中也包含了分號,因此會錯誤把這部分分號當成是結束符,造成語法錯誤。- 包含 in、out 和 inout 三種引數。
- 給變數賦值都需要用 select into 語句。
- 每次只能給一個變數賦值,不支援集合的操作。
遊標
- 遊標(cursor)是一個儲存在 DBMS 伺服器上的資料庫查詢,它不是一條 SELECT 語句,而是被該語句檢索出來的結果集。
- 在儲存過程中使用遊標可以對一個結果集進行移動遍歷。
- 遊標主要用於互動式應用,其中使用者需要對資料集中的任意行進行瀏覽和修改。
使用遊標的四個步驟:
- 宣告遊標,這個過程沒有實際檢索出資料;
- 開啟遊標;
- 取出資料;
- 關閉遊標;
觸發器(trigger)
觸發器是一種在事件發生時隱式地自動執行的PL/SQL塊,不能接受引數,不能被顯式呼叫
觸發器型別
-
DML 觸發器
對資料表進行DML語句操作(如insert、update、delete)時所觸發的觸發器
- 語句級觸發器或行級觸發器:行級觸發器會對資料庫表中的受影響的每一行觸發一次觸發器程式碼,語句級觸發器則只觸發一次,與語句所影響到的行數無關
- before觸發器或after觸發器:before觸發器在觸發事件發生之前執行觸發器程式碼,after觸發器則在觸發事件發生之後執行
-
替代觸發器(instead of 觸發器)
對檢視進行操作時定義的觸發器,替代觸發器只能定義在檢視上
-
系統事件觸發器
對資料庫例項或某個使用者模式進行操作時定義的觸發器
- 資料庫系統觸發器
- 使用者觸發器
觸發器語法
CREATE [OR REPLACE] TIGGER 觸發器名 觸發時間 觸發事件
ON 表名
[FOR EACH ROW]
BEGIN
pl/sql 語句
END
- 觸發器名:觸發器物件的名稱。
由於觸發器是資料庫自動執行的,因此該名稱只是一個名稱,沒有實質的用途。
- 觸發時間:指明觸發器何時執行,該值可取:
before---表示在資料庫動作之前觸發器執行;
after---表示在資料庫動作之後出發器執行。
- 觸發事件:指明哪些資料庫動作會觸發此觸發器:
insert:資料庫插入會觸發此觸發器;
update:資料庫修改會觸發此觸發器;
delete:資料庫刪除會觸發此觸發器。
表 名:資料庫觸發器所在的表。
for each row:對錶的每一行觸發器執行一次。如果沒有這一選項,則只對整個表執行一次。