主要內容
數據更新
數據操縱包括數據查詢和數據更新,數據更新又分爲三類:插入、修改和刪除。
1. 插入數據
SQL的數據插入語句INSERT通常有兩種形式,一種是插入單個元組,另一種是插入子查詢結果(即元組的集合)。
(1)插入單個元組
//將一個新學生元組(學號:20170330,姓名:圈毛,性別:男,年齡:未婚)插入Student表中:
INSERT
INTO Student(Sno,Sname,Ssex,Sage) /*INSERT INTO表示插入到...表*/
VALUES ('20170330','圈毛','男','未婚'); /*VALUES表示賦值,這SQL語言真是良心到髮指*/
<分析>
1)INTO子句中將Student表中的所有屬性列寫出,這樣相當於 INTO Student
2)若將INTO子句中的屬性列打亂,只要VALUE子句中的賦值一一對應,就不會出錯
3)例子中出現了一個賦值問題,Sage是整型數值,VALUE子句卻賦了字符型數據,這是會出錯的
4)還有一個注意點,我們沒有在INTO子句中寫出Sdept屬性列,也沒有給它賦值,這樣系統會自動取NULL。如果沒有寫出任何屬性列,我們需要在賦值時明確地給出NULL。
(2)插入子查詢結果
將子查詢嵌套在INSERT語句中。
//對每一個系的學生就平均年齡,並把結果存入數據庫:
首先建一個新表,用於存放每一個系的平均年齡:(可回顧“基本表的定義”)
CREAT TABLE Dept_avgage
(Sdept CHAR(20) PRIMARY KEY,
Avg_age SMALLINT);
接着將數據插入新表:
INSERT
INTO Dept_avgage
SELECT Sdept,AVG(Sage) /*整個子查詢結果*/
FROM Student
GROUP BY Sdept
2. 修改數據
修改指定表中滿足WHERE子句的選擇條件的元組。
(1)修改單個元組
//將學號爲20170330的學生年齡改爲20:
UPDATE Student /*選擇要更新的表*/
SET Sage = '20' /*設置新數據*/
WHERE Sno = '20170303' /*選擇條件確定修改的元組*/
(2)修改多個元組
//將所有學生年齡+1歲:
UPDATE Student
SET Sage = Sage+1; /*沒有WHERE子句就表示全員修改*/
(3)帶子查詢的修改
//將所有計算機科學系的學生成績歸零:
<分析> 成績信息在SC表,學生院系信息在Student表,可以用子查詢連接兩個表
UPDATE SC
SET Grade = 0
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Sdept = 'CS');
3. 刪除數據
刪除語句的語法和修改語句類似。但是要注意的是,刪除語句只刪除表中的數據,不可能刪除表在數據字典中的定義。
(1)刪除單個元組
//刪除學號爲20170330的學生的學生記錄:
DELETE
FROM Student
WHERE Sno = '20170330';
(2)刪除多個元組:
//刪除所有學生選課記錄:
DELETE
FROM SC
(3)帶子查詢的刪除
//刪除所有計算機科學系學生的選課記錄
DELETE
FROM SC
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Sdept = 'CS');
*對某個基本表的增、刪、改操作都有可能破壞參照完整性,這部分內容會在之後的篇章做介紹。
視圖
視圖可以從一個或幾個基本表(或視圖)中導出,而且與基本表不同,它是一個虛表。
數據庫中只存放視圖的定義,而不存放它的數據。準確地說,它沒有數據。
視圖相當於一個窗口,我們可以透過它看到基本表(或另一個視圖)中的數據。一旦基本表中的數據發生改變,從視圖中查詢到的數據也會發生變化。
1. 定義視圖
(1)基於單個基本表定義視圖
//建立信息系學生的視圖:
CREATE VIEW IS_Student /*省略了視圖IS_Student的列名,隱含着視圖的屬性列由SELECT子句確定*/
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept = 'IS'
WITH CHECK OPTION;
<分析>
1)關係數據庫管理系統執行CREATE VIE語句的結果只是把視圖的定義存入數據字典,只有在查詢視圖時纔會執行代碼中的SELECT語句。
2)加上WITH CHECK OPTION子句後,若對該視圖進行插入、修改和刪除操作,關係數據庫管理系統會自動加上Sdept = 'IS'的條件。
(2)基於多個基本表定義視圖
//建立信息系選修了1號課程的學生的視圖。
CREATE VIEW IS_S1(Sno,Sname,Sage) /*視圖的屬性列要麼全部寫上,要麼全部省略,不然會和SELECT語句產生矛盾*/
AS /*這裏由於Student表和SC表出現同名屬性列Sno,所以必須寫上*/
SELECT Student.Sno,Sname,Sage
FROM Student,SC
WHERE Sdept = 'IS' AND
Student.Sno = SC.Sno AND
SC.Cno = '1';
(3)定義功能性視圖
定義基本表時,爲了減少數據庫中的冗餘數據,表中只存放基本數據,由基本數據派生的數據一般是不存儲的。這時候視圖就發揮它的作用了,我們雖然不存儲,但是可以在顯示數據的時候把派生數據計算出來鴨_(:з」∠)_
//將學生的學號及平均成績定義爲一個視圖:
CREAT VIEW S_avg(Sno,Savg)
AS
SELECT Sno,AVG(Grade) /*除了用聚集函數,這裏還可以寫算術表達式*/
FROM SC
GROUP BY Sno
2. 刪除視圖
刪除視圖後,視圖的定義會從數據字典抹去,但如果視圖導出了其他視圖,系統將會拒絕執行刪除操作。要成功刪除視圖,需要加上CASCADE關鍵字,連同其他被導出的視圖一起刪除。
基本表被刪除後,由它導出的所有視圖都會失效,但視圖的定義不會自動被刪除,我們還需要手動刪除。
//刪除視圖S_avg:
DROP VIEW S_avg CASCADE;
3. 查詢視圖
查詢視圖時,關係數據庫管理系統會先檢查視圖是否存在,若存在,則從數據字典中將視圖的定義取出,進而找到最原始的基本表,再進行數據查詢。這個過程稱爲視圖消解。
查詢視圖與查詢基本表的語法基本相同,本篇不再贅述。
*需要注意的是,並不是所有視圖都能被查詢出結果。例如上面的功能性視圖S_avg,如果查詢視圖中平均成績超過90分的學生學號,它在關係數據庫管理系統中經過轉化後會得到查詢語句:
SELECT Sno
FROM SC
WHERE AVG(Grade) >= 90;
GROUP BY Sno;
然而這樣的轉化是錯誤的,因爲WHERE子句中不能使用聚集函數(可回顧“聚集函數”)。所以視圖S_avg中的平均成績我們只能看,而不能通過SQL語句去查,想要查也只能在SC表上老實地寫一個查詢語句了。
目前只有行列子集視圖能正確地轉換。行列子集視圖是指僅從單個基本表中導出,且所有屬性列來自基本表的視圖。
4. 更新視圖
更新視圖除了語法與查詢視圖不同,道理一樣。
5. 視圖的作用
1)簡化用戶的操作。
2)使用戶能以多種角度看待同一數據。
3)對重構數據庫提供了一定程度的邏輯獨立性。
4)能夠對機密數據提供安全保護。
5)用視圖輔助基本表查詢。
路過的圈毛君:“SQL分爲數據定義、數據查詢、數據更新和數據控制四個部分,到現在前三部分已經介紹完了,之後將會介紹數據控制。”