關係資料庫標準語言SQL(三)
主要內容
資料更新
資料操縱包括資料查詢和資料更新,資料更新又分為三類:插入、修改和刪除。
1. 插入資料
SQL的資料插入語句INSERT通常有兩種形式,一種是插入單個元組,另一種是插入子查詢結果(即元組的集合)。
(1)插入單個元組
//將一個新學生元組(學號:20170330,姓名:圈毛,性別:男,年齡:未婚)插入Student表中:
INSERT
INTO Student(Sno,Sname,Ssex,Sage) /*INSERT INTO表示插入到...表*/
VALUES ('20170330','圈毛','男','未婚
<分析>
1)INTO子句中將Student表中的所有屬性列寫出,這樣相當於 INTO Student
2)若將INTO子句中的屬性列打亂,只要VALUE子句中的賦值一一對應,就不會出錯
3)例子中出現了一個賦值問題,Sage是整型數值,VALUE子句卻賦了字元型資料,這是會出錯的
4)還有一個注意點,我們沒有在INTO子句中寫出Sdept屬性列,也沒有給它賦值,這樣系統會自動取NULL。如果沒有寫出任何屬性列,我們需要在賦值時明確地給出NULL。
(2)插入子查詢結果
將子查詢巢狀
//對每一個系的學生就平均年齡,並把結果存入資料庫:
首先建一個新表,用於存放每一個系的平均年齡:(可回顧“基本表的定義”)
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分為資料定義、資料查詢、資料更新和資料控制四個部分,到現在前三部分已經介紹完了,之後將會介紹資料控制。”