第9章數(shù)據(jù)庫(kù)語(yǔ)言_第1頁(yè)
第9章數(shù)據(jù)庫(kù)語(yǔ)言_第2頁(yè)
第9章數(shù)據(jù)庫(kù)語(yǔ)言_第3頁(yè)
第9章數(shù)據(jù)庫(kù)語(yǔ)言_第4頁(yè)
第9章數(shù)據(jù)庫(kù)語(yǔ)言_第5頁(yè)
已閱讀5頁(yè),還剩147頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

數(shù)據(jù)庫(kù)基礎(chǔ)SQL數(shù)據(jù)定義第9章數(shù)據(jù)庫(kù)語(yǔ)言SQLSQL特點(diǎn)129.2.1SQL模式的創(chuàng)建和撤銷9.2.2SQL的基本數(shù)據(jù)類型9.2.3基本的表的創(chuàng)建和撤銷9.2.4索引的創(chuàng)建和撤銷3SQL數(shù)據(jù)查詢39.3.1SELECT基本句型9.3.2SELECT語(yǔ)句的使用技術(shù)9.3.3SELECT語(yǔ)句完整的結(jié)構(gòu)9.3.4數(shù)據(jù)查詢的改進(jìn)寫(xiě)法9.3.5嵌套查詢的改進(jìn)寫(xiě)法9.3.6基本表的連接操作9.4.1數(shù)據(jù)插入

9.4.2數(shù)據(jù)刪除9.4.3數(shù)據(jù)修改SQL數(shù)據(jù)更新44嵌入式SQL6視圖的定義及操作59.5.1視圖的創(chuàng)建和撤銷9.5.2對(duì)視圖的操作9.6.1嵌入式SQL的實(shí)現(xiàn)方式9.6.2嵌入式SQL的使用規(guī)定9.6.3SQL的集合處理方式的主語(yǔ)言

單記錄處理方式之間的協(xié)調(diào)9.6.4嵌入式SQL的使用技術(shù)第9章數(shù)據(jù)庫(kù)語(yǔ)言SQLSQL(StructuredQueryLanguage)是一種結(jié)構(gòu)化查詢語(yǔ)言。59.1SQL特點(diǎn)通常核心SQL主要有四個(gè)部分:(1)數(shù)據(jù)定義語(yǔ)言,即SQLDDL,用于定義SQL模式、基本表、視圖、索引等結(jié)構(gòu);(2)數(shù)據(jù)操縱語(yǔ)言,即SQLDML,數(shù)據(jù)操縱分成數(shù)據(jù)查詢和數(shù)據(jù)更新兩類,而數(shù)據(jù)更新又分為插入、刪除和修改三種操作;(3)嵌入式SQL語(yǔ)言的使用規(guī)定,這一部分內(nèi)容涉及到SQL語(yǔ)句嵌入在主語(yǔ)言程序中的規(guī)則;(4)數(shù)據(jù)庫(kù)控制語(yǔ)言,即SQLDCL,這一部分包括對(duì)基本表和視圖的授權(quán)、完整性規(guī)則的描述、事務(wù)控制等內(nèi)容。6SQL具有如下特點(diǎn):(1)SQL具有十分靈活和強(qiáng)大的查詢功能,其SELECT語(yǔ)句能完成相當(dāng)復(fù)雜的查詢操作,包括各種關(guān)系代數(shù)操作、統(tǒng)計(jì)、排序等操作;(2)SQL不是一個(gè)應(yīng)用開(kāi)發(fā)語(yǔ)言,它只提供對(duì)數(shù)據(jù)庫(kù)的操作功能,不能完成屏幕控制、菜單管理、報(bào)表生成等功能,但SQL既可作為交互式語(yǔ)言獨(dú)立使用,也可作為子語(yǔ)言嵌入在主語(yǔ)言中使用,成為應(yīng)用開(kāi)發(fā)語(yǔ)言的一部分;(3)SQL是國(guó)際標(biāo)準(zhǔn)語(yǔ)言,有利于各種數(shù)據(jù)庫(kù)之間交換數(shù)據(jù),有利于程序的移植,有利于實(shí)現(xiàn)高度的數(shù)據(jù)獨(dú)立性,有利于實(shí)現(xiàn)標(biāo)準(zhǔn)化;(4)SQL的詞匯不多,完成核心功能只用了9個(gè)英語(yǔ)動(dòng)詞,它的語(yǔ)法結(jié)構(gòu)接近英語(yǔ),因此容易學(xué)習(xí)和使用。79.2SQL數(shù)據(jù)定義本節(jié)介紹對(duì)SQL模式、基本表和索引的創(chuàng)建和撤銷等操作。89.2.1SQL模式的創(chuàng)建和撤銷SQL模式的創(chuàng)建在SQL中,一個(gè)SQL模式定義為基本表的集合。一個(gè)SQL模式由模式名和模式擁有者的用戶名或賬號(hào)來(lái)確定,并包含模式中每一個(gè)元素(基本表、視圖、索引等)的定義。創(chuàng)建SQL模式,就是定義了一個(gè)存儲(chǔ)空間。9SQL模式的創(chuàng)建可用CREATESCHEMA語(yǔ)句定義,其基本語(yǔ)法如下:CREATESCHEMA<模式名>AUTHORIZATION<用戶名>例如,下面語(yǔ)句定義了教學(xué)數(shù)據(jù)庫(kù)的SQL模式:CREATESCHEMAST_COAUTHORIZATIONLISMITH;該模式名為ST_CO,擁有者為L(zhǎng)ISMITH。10SQL模式的撤銷當(dāng)一個(gè)SQL模式及其所屬的基本表、視圖等元素都不需要時(shí),可以用DROP語(yǔ)句撤銷這個(gè)SQL模式。DROP語(yǔ)句的語(yǔ)法如下:DROPSCHEMA<模式名>[ CASCADE|RESTRICT]其方式有兩種:CASCADE(級(jí)聯(lián)式)方式:執(zhí)行DROP語(yǔ)句時(shí),把SQL模式及其下屬的基本表、視圖、索引等所有元素全部撤銷。11RESTRICT(約束式)方式:執(zhí)行DROP語(yǔ)句時(shí),只有當(dāng)SQL模式中沒(méi)有任何下屬元素時(shí),才能撤銷SQL模式,否則拒絕執(zhí)行DROP語(yǔ)句。例如,要撤銷SQL模式ST_CO及其下屬所有的元素時(shí),可用下列語(yǔ)句實(shí)現(xiàn):DROPSCHEMAST_COCASCADE;由于“SQL模式”這個(gè)名詞學(xué)術(shù)味太重,因此大多數(shù)DBMS中不愿采用這個(gè)名詞,而是采用“數(shù)據(jù)庫(kù)”(DATABASE)這個(gè)名詞。也就是大多數(shù)系統(tǒng)中把“創(chuàng)建SQL模式”按慣例稱為“創(chuàng)建數(shù)據(jù)庫(kù)”,語(yǔ)句采用“CREATEDATABASE…”和“DROPDATABASE”等字樣。129.2.2SQL的基本數(shù)據(jù)類型SQL提供的主要數(shù)據(jù)類型(也稱為“域類型”)有:1.數(shù)值型INTEGER 長(zhǎng)整數(shù)(也可寫(xiě)成INT)SMALLINT 短整數(shù)REAL 浮點(diǎn)數(shù)DOUBLEPRECISION 雙精度浮點(diǎn)數(shù)FLOAT(n) 浮點(diǎn)數(shù),精度至少為n為數(shù)字NUMERIC(p,d) 定點(diǎn)數(shù),有p位數(shù)字(不包括符號(hào)、小數(shù)點(diǎn))組成,小數(shù)點(diǎn)后面有d位數(shù)字(也可寫(xiě)成DECIMAL(p,d)或DEC(p,d))132.字符串型CHAR(n) 長(zhǎng)度為n的定長(zhǎng)字符串VARCHAR(n) 具有最大長(zhǎng)度為n的變長(zhǎng)字符串3.位串型BIT(n) 長(zhǎng)度為n的二進(jìn)制位串BITVARYING(n) 最大長(zhǎng)度為n的變長(zhǎng)二進(jìn)制位串4.時(shí)間型DATE 日期,包含年、月、日,形為YYYY-MM-DDTIME 時(shí)間,包含一日的時(shí)、分、秒,形為HH:MM:SS14SQL允許在上面列出的類型的值上進(jìn)行比較操作,但算術(shù)操作只限于數(shù)值類型。SQL還提供一種時(shí)間間隔(INTERVAL)的數(shù)據(jù)類型,例如兩個(gè)日期類型值的差,就是一個(gè)間隔類型的值。如果一個(gè)日期類型值加上一個(gè)間隔型的值,或減去一個(gè)間隔型的值,就可得到另外一個(gè)日期。SQL允許用戶使用“CREATEDOMAIN”語(yǔ)句定義新的域,例如定義一個(gè)新的域PERSON_NAME:CREATEDOMAINPERSON_NAMECHAR(8);這樣我們就可以像使用基本類型一樣,用域名PERSON_NAME來(lái)定性屬性的類型。159.2.3基本表的創(chuàng)建和撤銷如果在系統(tǒng)中創(chuàng)建了一個(gè)數(shù)據(jù)庫(kù),那么就可以在數(shù)據(jù)庫(kù)中定義基本表。對(duì)基本表結(jié)構(gòu)的操作有創(chuàng)建、修改和撤銷三種操作。1.基本表的創(chuàng)建創(chuàng)建基本表,可用CREATETABLE語(yǔ)句實(shí)現(xiàn):CREATETABLE<基本表名>(<列名

類型>,……<完整性約束>,……)16表中每個(gè)列的類型可以是基本數(shù)據(jù)類型,也可以是用戶預(yù)先定義好的域名。完整性約束主要有三種子句:主鍵子句(PRIMARYKEY)、外鍵子句(FOREIGNKEY)和檢查子句(CHECK)。每個(gè)基本表的創(chuàng)建定義中包含了若干列的定義和若干個(gè)完整性約束。下面舉例說(shuō)明。例9.1:對(duì)于教學(xué)數(shù)據(jù)庫(kù)中的四個(gè)關(guān)系:教師信息表(工號(hào),姓名,性別,職稱,所屬院系,郵箱,參加工作年月,基本工資,崗位津貼,照片)選課表(課程代碼,課程名稱,開(kāi)課院系,學(xué)分,工號(hào),時(shí)間,教室,課程類型)學(xué)生信息表(學(xué)號(hào),姓名,性別,院系,出生年月,戶籍地,是否黨員,當(dāng)前績(jī)點(diǎn)(GPA),備注)成績(jī)表(學(xué)號(hào),課程代碼,成績(jī))17基本表教師信息表可用下列語(yǔ)句創(chuàng)建:CREATETABLE教師信息表(工號(hào) CHAR(4) NOTNULL,姓名 CHAR(10) NOTNULL,性別 CHAR(2),職稱 CHAR(6),所屬院系 CHAR(20),郵箱 CHAR(36),參加工作年月DATE,基本工資 REAL,崗位津貼 REAL,照片 CHAR(255),PRIMARYKEY(工號(hào)));18SQL允許列值是空值,但當(dāng)要求某一列的值不允許空值時(shí)就應(yīng)在定義該列時(shí)寫(xiě)上“NOTNULL”,就像這里的工號(hào)和姓名后有“NOTNULL”字樣。但在此處,由于主鍵子句(PRIMARYKEY)已定義工號(hào)是主鍵,因此列工號(hào)的定義中“NOTNULL”是冗余的,可以不寫(xiě)。但為了提高可讀性,寫(xiě)上也不妨。19對(duì)于基本表選課表、學(xué)生信息表和成績(jī)表可以用下列語(yǔ)句創(chuàng)建:CREATETABLE選課表(課程代碼 CHAR(12) NOTNULL,課程名稱 CHAR(10) NOTNULL,開(kāi)課院系 CHAR(20),學(xué)分 SMALLINT工號(hào) CHAR(4),時(shí)間 DATE,教室 CHAR(12),課程類型 CHAR(10),PRIMARYKEY(課程代碼),FOREIGNKEY(工號(hào))REFERENCES教師信息表(工號(hào)));20在基本表“選課表”的定義中說(shuō)明了主鍵是課程代碼,外鍵是工號(hào),并指出外鍵工號(hào)和基本表“教師信息表”中工號(hào)列對(duì)應(yīng),此處對(duì)應(yīng)的列名恰好同名,實(shí)際上也可以不同名,只要指出其對(duì)應(yīng)性即可。外鍵體現(xiàn)了關(guān)系數(shù)據(jù)庫(kù)的參照完整性。21CREATETABLE學(xué)生信息表(學(xué)號(hào) CHAR(5) NOTNULL,姓名 CHAR(10) NOTNULL,性別 CHAR(2),院系 CHAR(20),出生年月 DATE,戶籍地 CHAR(10),是否黨員 CHAR(2)當(dāng)前績(jī)點(diǎn)(GPA)REAL,備注 CHAR(255),PRIMARYKEY(學(xué)號(hào)));22CREATETABLE成績(jī)表(學(xué)號(hào) CHAR(5),課程代碼 CHAR(12),成績(jī) REAL,PRIMARYKEY(學(xué)號(hào),課程代碼),FOREIGNKEY(學(xué)號(hào))REFERENCES學(xué)生信息表(學(xué)號(hào)),FOREIGNKEY(課程代碼)REFERENCES選課表(課程代碼));23在基本表成績(jī)表的定義中說(shuō)明了主鍵是(學(xué)號(hào),課程代碼),還定義了兩個(gè)外鍵,并指出外鍵學(xué)號(hào)和學(xué)生信息表中學(xué)號(hào)列對(duì)應(yīng),外鍵課程代碼和選課表中的課程代碼列相對(duì)應(yīng)。在上例中,每個(gè)語(yǔ)句結(jié)束時(shí)加了分號(hào)“;”。但讀者應(yīng)注意,在SQL標(biāo)準(zhǔn)中,分號(hào)不是語(yǔ)句的組成部分。在具體DBMS中,有的系統(tǒng)規(guī)定必須加分號(hào),表示語(yǔ)句結(jié)束,有的系統(tǒng)規(guī)定不加。本書(shū)為了醒目,特在每個(gè)語(yǔ)句結(jié)束后加分號(hào)。在用CREATE語(yǔ)句創(chuàng)建基本表中,最初只是一個(gè)空的框架,接下來(lái),用戶可使用INSERT命令把數(shù)據(jù)插入基本表中。關(guān)系數(shù)據(jù)庫(kù)產(chǎn)品都有數(shù)據(jù)裝載程序,可以把大量原始數(shù)據(jù)載入基本表。242.基本表結(jié)構(gòu)的修改在基本表建立并使用一段時(shí)期后,可以根據(jù)實(shí)際需要對(duì)基本表的結(jié)構(gòu)進(jìn)行修改,即增加新的列、刪除原有的列或修改數(shù)據(jù)類型、寬度等。(1)增加新的列用“ALTER…ADD…”語(yǔ)句,其語(yǔ)法如下:ALTERTABLE<基本表名>ADD<列名><類型>25例9.2:在基本表學(xué)生信息表中增加一個(gè)地址(ADDRESS)列,可用下列語(yǔ)句:ALTERTABLE學(xué)生信息表ADDADDRESSVARCHAR(30);應(yīng)注意,新增加的列不能定義為“NOTNULL”?;颈碓谠黾右涣泻?,原有元組在新增加的列上的值都被定義為空值(NULL)。(2)刪除原有的列用“ALTER…DROP…”語(yǔ)句,其句法如下:ALTERTABLE<基本表名>DROP<列名>[CASCADE|RESTRICT]此處CASCADE方式表示:在基本表中刪除某列時(shí),所有引用到該列的視圖和約束也要一起自動(dòng)地被刪除。而RESTRICT方式表示在沒(méi)有視圖或約束引用該屬性時(shí),才能在基本表中刪除該列,否則拒絕刪除操作。26例9.3:在基本表學(xué)生信息表中刪除備注列,并且把引用該列的所有視圖和約束一起刪除,可用下列語(yǔ)句:ALTERTABLE學(xué)生信息表DROP備注CASCADE;(3)修改原有列的類型、寬度用“ALTER…MODIFY…”語(yǔ)句,其句法如下:ALTERTABLE<基本表名>MODIFY<列名><類型>例9.4:在基本表學(xué)生信息表中學(xué)號(hào)的長(zhǎng)度修改為6,可用下列語(yǔ)句:ALTERTABLE學(xué)生信息表MODIFY學(xué)號(hào)CHAR(6);273.基本表的撤銷

在基本表不需要時(shí),可以用“DROPTABLE”語(yǔ)句撤銷。在一個(gè)基本表撤銷后,其所有數(shù)據(jù)也就丟失了。撤銷語(yǔ)句的句法如下:DROPTABLE<基本表名>[CASCADE|RESTRICT]此處的CASCADE、RESTRICT的語(yǔ)義同前面句法中的語(yǔ)義一樣。例9.5:需要撤銷基本表學(xué)生信息表。但只有在沒(méi)有視圖或約束引用學(xué)生信息表中的列時(shí)才能撤銷,否則拒絕撤銷??捎孟铝姓Z(yǔ)句實(shí)現(xiàn):DROPTABLE學(xué)生信息表RESTRICT;289.2.4索引的創(chuàng)建和撤銷在SQL86和SQL89標(biāo)準(zhǔn)中,基本表沒(méi)有關(guān)鍵碼概念,用索引機(jī)制彌補(bǔ)。索引屬于物理存儲(chǔ)的路徑概念,而不是邏輯的概念。在定義基本表時(shí),還要定義索引,就把數(shù)據(jù)庫(kù)的物理結(jié)構(gòu)和邏輯結(jié)構(gòu)混在一起了。因此在SQL2中引入了主鍵概念,用戶在創(chuàng)建基本表時(shí)用主鍵子句直接定義主鍵。291.索引的創(chuàng)建創(chuàng)建索引可用“CREATEINDEX”語(yǔ)句實(shí)現(xiàn)。其方法如下:CREATE[UNIQUE]INDEX<索引名>ON<基本表名>(<列名序列>)30例9.6:如果創(chuàng)建學(xué)生基本表時(shí),未使用主鍵子句,那么可用建索引的方法來(lái)起到主鍵的作用:CREATEUNIQUEINDEXS#_INDEXON學(xué)生信息表(學(xué)號(hào));此處關(guān)鍵字UNIQUE表示每個(gè)索引項(xiàng)對(duì)應(yīng)唯一的數(shù)據(jù)記錄。SQL中的索引是非顯式索引,也就是在索引創(chuàng)建以后,用戶在索引撤銷前不會(huì)再用到該索引鍵的名,但是索引在用戶查詢時(shí)會(huì)自動(dòng)起作用。一個(gè)索引鍵也可以對(duì)應(yīng)多個(gè)列。索引排列時(shí)可以升序,也可以降序,升序排列用ASC表示,降序排列用DESC表示,默認(rèn)時(shí)表示升序排序。譬如,可以對(duì)基本表成績(jī)表中的(學(xué)號(hào),課程代碼)建立索引:CREATEUNIQUEINDEXSC_INDEXON成績(jī)表(學(xué)號(hào)ASC,課程代碼DESC)。312.索引的撤銷當(dāng)索引不需要時(shí),可以用“DROPINDEX”語(yǔ)句撤銷,其句法如下:DROPINDEX<索引名>32例9.7:撤銷索引S#_INDEX和SC_INDEX,可用下列語(yǔ)句:DROPINDEXS#_INDEX,SC_INDEX;339.3.1SELECT基本句型SQL的SELECT-FROM-WHERE句型:SELECTA1,…,AnFROMR1,…,RmWHEREF34在WHERE子句的條件表達(dá)式F中可使用下列運(yùn)算符:算術(shù)比較運(yùn)算符:<,<=,>,>=,=,<>或!=。邏輯運(yùn)算符:AND,OR,NOT。集合成員資格運(yùn)算符:IN,NOTIN。謂詞:EXISTS(存在量詞),ALL,SOME,UNIQUE。集合函數(shù):AVG(平均值),MIN(最小值),MAX(最大值),SUM(和),COUNT(計(jì)數(shù))。F中運(yùn)算對(duì)象還可以是另一個(gè)SELECT語(yǔ)句,即SELECT語(yǔ)句可以嵌套。另外,SELECT語(yǔ)句的查詢結(jié)果之間還可以進(jìn)行集合的并、交、差操作,其運(yùn)算符是集合運(yùn)算符:UNION(并),INTERSECT(交),EXCEPT(差)。359.3.2SELECT語(yǔ)句的使用技術(shù)SELECT語(yǔ)句使用時(shí)有三種寫(xiě)法:連接查詢嵌套查詢帶存在量詞的嵌套查詢。36例9.8:對(duì)于教學(xué)數(shù)據(jù)庫(kù)中的四個(gè)關(guān)系:教師信息表(工號(hào),姓名,性別,職稱,所屬院系,郵箱,參加工作年月,基本工資,崗位津貼,照片)選課表(課程代碼,課程名稱,開(kāi)課院系,學(xué)分,工號(hào),時(shí)間,教室,課程類型)學(xué)生信息表(學(xué)號(hào),姓名,性別,院系,出生年月,戶籍地,是否黨員,當(dāng)前績(jī)點(diǎn)(GPA),備注)成績(jī)表(學(xué)號(hào),課程代碼,成績(jī))用戶有一個(gè)查詢語(yǔ)句:檢索教學(xué)高等數(shù)學(xué)的教師工號(hào)和姓名。這個(gè)查詢要從基本表“教師信息表”和“選課表”中檢索數(shù)據(jù),因此可以有下面三種寫(xiě)法。37(1)第一種寫(xiě)法(連接查詢):SELECT教師信息表.工號(hào),姓名FROM教師信息表,選課表WHERE教師信息表.工號(hào)=選課表.工號(hào)AND課程名稱=’高等數(shù)學(xué)’;這個(gè)語(yǔ)句執(zhí)行時(shí),要先對(duì)FROM后的基本表“教師信息表”和“選課表”做笛卡爾積操作,然后再做等值連接(教師信息表.工號(hào)=選課表.工號(hào))、選擇(課程名稱=’高等數(shù)學(xué)’)和投影等操作。由于工號(hào)在“教師信息表”和“選課表”中都出現(xiàn),因此引用時(shí)需注上基本表名,如教師信息表.工號(hào)、選課表.工號(hào)等。382)第二種寫(xiě)法(嵌套查詢):SELECT工號(hào),姓名FROM教師信息表WHERE工號(hào)IN(SELECT工號(hào)FROM選課表WHERE課程名稱=’高等數(shù)學(xué)’);這里外層WHERE子句中嵌有一個(gè)SELECT語(yǔ)句,SQL允許多層嵌套。這里嵌套的子查詢?cè)谕鈱硬樵兲幚碇皥?zhí)行。即先在基本表“選課表”中求出教高等數(shù)學(xué)的工號(hào)值,然后再在表“教師信息表”中據(jù)工號(hào)值求姓名值。39由此可見(jiàn),查詢涉及到多個(gè)基本表時(shí)用嵌套結(jié)構(gòu)逐次求解層次分明,具有結(jié)構(gòu)程序設(shè)計(jì)特點(diǎn)。并且嵌套查詢的執(zhí)行效率也比連接查詢的笛卡爾積效率高。在嵌套查詢中,IN是常用到的謂詞,其結(jié)構(gòu)為“元組IN(集合)”,表示元組在集合內(nèi)。40這個(gè)查詢的嵌套寫(xiě)法還可以有另外一種:SELECT工號(hào),姓名FROM教師信息表WHERE’高等數(shù)學(xué)’IN(SELECT課程名稱FROM選課表WHERE選課表.工號(hào)=教師信息表.工號(hào));此處內(nèi)層查詢稱為“相關(guān)子查詢”,子查詢中查詢條件依賴于外層查詢中的某個(gè)值,所以子查詢的處理不止一次,要反復(fù)求值,以供外層查詢使用。41(3)第三種寫(xiě)法(使用存在量詞的嵌套查詢)SELECT工號(hào),姓名FROM教師信息表WHEREEXISTS(SELECT*FROM選課表WHERE選課表.工號(hào)=教師信息表.工號(hào)AND課程名稱=’高等數(shù)學(xué)’);此處”SELECT*”表示從表中取出所有列。謂詞EXISTS表示存在量詞符號(hào)?,其語(yǔ)義是內(nèi)層查詢的結(jié)果應(yīng)該為非空(即至少存在一個(gè)元組)。42例9.9:對(duì)于教學(xué)數(shù)據(jù)庫(kù)中四個(gè)基本表教師信息表、選課表、學(xué)生信息表、成績(jī)表,下面用SELECT語(yǔ)句表達(dá)下面各個(gè)查詢語(yǔ)句。(1)檢索學(xué)習(xí)課程代碼為ENGL11004.01的學(xué)生學(xué)號(hào)與成績(jī)SELECT學(xué)號(hào),成績(jī)FROM成績(jī)表WHERE課程代碼=‘ENGL11004.01’;43(2)檢索至少選修劉老師所授課程中一門課程的學(xué)生學(xué)號(hào)與姓名。SELECT學(xué)生信息表.學(xué)號(hào),姓名FROM成績(jī)表,學(xué)生信息表,選課表,教師信息表WHERE成績(jī)表.學(xué)號(hào)=學(xué)生信息表.學(xué)號(hào)AND成績(jī)表.課程代碼=選課表.課程代碼AND教師信息表.工號(hào)=選課表.工號(hào)AND教師信息表.姓名=‘劉’;44(3)檢索學(xué)習(xí)課程代碼為ENGL11004.01或PEDU11009.01的學(xué)生學(xué)號(hào)。SELECT學(xué)號(hào)FROM成績(jī)表WHERE課程代碼=‘ENGL11004.01’OR課程代碼=‘PEDU11009.01’;45(4)檢索至少選修課程號(hào)為ENGL11004.01和PEDU11009.01的學(xué)生學(xué)號(hào)。SELECTX.學(xué)號(hào)FROM成績(jī)表ASX,成績(jī)表ASYWHEREX.學(xué)號(hào)=Y.學(xué)號(hào)ANDX.課程代碼=‘ENGL11004.01’ANDY.課程代碼=‘PEDU11009.01’;同一個(gè)基本表成績(jī)表在一層中出現(xiàn)了兩次,為加以區(qū)別,引入別名X和Y。在語(yǔ)句中應(yīng)用表名對(duì)列名加以限定,譬如X.學(xué)號(hào)、Y.學(xué)號(hào)等。書(shū)寫(xiě)時(shí),保留字AS在語(yǔ)句中可省略,可直接寫(xiě)成“成績(jī)表X,成績(jī)表Y”。46(5)檢索不學(xué)PEDU11009.01課程的學(xué)生姓名與院系。SELECT姓名,院系FROM學(xué)生信息表WHERE學(xué)號(hào)NOTIN(SELECT學(xué)號(hào)FROM成績(jī)表WHERE課程代碼=‘PEDU11009.01’);或者:SELECT姓名,院系FROM學(xué)生信息表WHERENOTEXISTS(SELECT*FROM成績(jī)表WHERE成績(jī)表.學(xué)號(hào)=學(xué)生信息表.學(xué)號(hào)AND課程代碼=‘PEDU11009.01’);這個(gè)查詢不能使用連接查詢寫(xiě)法。47(6)檢索學(xué)習(xí)全部課程的學(xué)生姓名。在表學(xué)生信息表中找學(xué)生,要求這個(gè)學(xué)生學(xué)了全部課程。換言之,在表學(xué)生信息表中找學(xué)生,在選課表中不存在一門課程,這個(gè)學(xué)生沒(méi)有學(xué)。按照此語(yǔ)義,就可寫(xiě)出查詢語(yǔ)句的SELECT表達(dá)方式:SELECT姓名FROM學(xué)生信息表WHERENOTEXISTS(SELECT*FROM選課表WHERENOTEXISTS(SELECT*FROM成績(jī)表WHERE成績(jī)表.課程代碼=選課表.課程代碼AND學(xué)生信息表.學(xué)號(hào)=成績(jī)表.學(xué)號(hào)));48(7)檢索所學(xué)課程包含學(xué)號(hào)為00001學(xué)生所學(xué)課程的學(xué)生學(xué)號(hào)。這一查詢的寫(xiě)法類似于(6)的寫(xiě)法,其思路如下:在學(xué)生信息表中找一個(gè)學(xué)生(學(xué)號(hào)),/*在學(xué)生信息表中找*/對(duì)于00001學(xué)的每一門課(課程代碼), /*在成績(jī)表中找*/該學(xué)生都學(xué)了。 /*在成績(jī)表中存在一個(gè)元組*/然后,改成雙重否定形式在學(xué)生信息表中找一個(gè)學(xué)生(學(xué)號(hào)),不存在00001學(xué)的一門課(課程代碼),該學(xué)生沒(méi)有學(xué)。這樣就很容易的寫(xiě)出SELECT語(yǔ)句:49SELECT學(xué)號(hào)FROM學(xué)生信息表WHERENOTEXISTS /*不存在00001學(xué)的一門課*/(SELECT*FROM成績(jī)表ASXWHEREX.學(xué)號(hào)=‘00001’ANDNOTEXISTS /*該學(xué)生沒(méi)有學(xué)*/(SELECT*FROM成績(jī)表ASYWHEREY.學(xué)號(hào)=學(xué)生信息表.學(xué)號(hào)ANDY.課程代碼=X.課程代碼));509.3.3SELECT語(yǔ)句完整的結(jié)構(gòu)1.聚合函數(shù)SQL提供了下列聚合函數(shù):COUNT(*) 計(jì)算元組的個(gè)數(shù)COUNT(<列名>) 對(duì)一列中的值計(jì)算個(gè)數(shù)SUM(<列名>) 求某一列值的綜合(此列的值必須是數(shù)值型)AVG(<列名>) 求某一列值的平均值(此列的值必須是數(shù)值型)MAX(<列名>) 求某一列值的最大值MIN(<列名>) 求某一列值的最小值51例9.10:對(duì)教學(xué)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行查詢和計(jì)算。(1)求男學(xué)生的總?cè)藬?shù)和平均績(jī)點(diǎn)。SELECTCOUNT(*),AVG(當(dāng)前績(jī)點(diǎn)(GPA))FROM學(xué)生信息表WHERE性別=‘男’;52(2)統(tǒng)計(jì)選修了課程的學(xué)生人數(shù)SELECTCOUNT(DISTINCT學(xué)號(hào))FROM成績(jī)表;這里如果不加保留字DISTINCT,那么統(tǒng)計(jì)出表的值是選修課程的學(xué)生人次數(shù)。由于有的學(xué)生選修了多門課,在統(tǒng)計(jì)時(shí)只能計(jì)作一人,因此在COUNT函數(shù)的列名前面要加DISTINCT,統(tǒng)計(jì)出來(lái)的值才是學(xué)生人數(shù)。532.SELECT語(yǔ)句完整地句法SELECT語(yǔ)句完整地句法如下:SELECT<目標(biāo)表的列名或列表達(dá)式序列>FROM<基本表名和(或)視圖序列>[WHERE<行條件表達(dá)式>][GROUPBY<列名序列>] [HAVING<組條件表達(dá)式>]][ORDERBY[列名ASC|DESC],…]句法中[]表示該成分可有也可無(wú)。54整個(gè)語(yǔ)句的執(zhí)行過(guò)程如下:讀取FROM子句中基本表、視圖的數(shù)據(jù),執(zhí)行笛卡爾積操作。選取滿足WHERE子句中給出的條件表達(dá)式的元組。按GROUP子句中指定列的值分組,同時(shí)提取滿足HAVING子句中組條件表達(dá)式的那些組。按SELECT子句中給出的列名或列表達(dá)式求值輸出。ORDER子句對(duì)輸出的目標(biāo)表進(jìn)行排序,按附加說(shuō)明ASC升序排列,或按DESC降序排列。55SELECT語(yǔ)句中,WHERE子句稱為“行條件子句”,GROUP子句稱為“分組子句”,HAVING子句稱為“組條件子句”,ORDER子句稱為“排序子句”。下面舉例說(shuō)明分組子句和排序子句的用法。56例9.11:對(duì)教學(xué)數(shù)據(jù)庫(kù)中四個(gè)基本表教師信息表、選課表、學(xué)生信息表、成績(jī)表中數(shù)據(jù)進(jìn)行查詢和計(jì)算。(1)統(tǒng)計(jì)每門課程的學(xué)生選修人數(shù)SELECT選課表.課程代碼,課程名稱,COUNT(學(xué)號(hào))FROM選課表,成績(jī)表WHERE選課表.課程代碼=成績(jī)表.課程代碼GROUPBY選課表.課程代碼;57由于要統(tǒng)計(jì)每一門課程的學(xué)生人數(shù),因此要把滿足WHERE子句種條件的查詢結(jié)果按課程代碼分組,在每一組中的課程代碼相同。此時(shí)的SELECT子句應(yīng)對(duì)每一分組進(jìn)行操作,在每一組中,選課表.課程代碼只有一個(gè)值,統(tǒng)計(jì)出的學(xué)號(hào)值個(gè)數(shù)就是這一組中的學(xué)生人數(shù)。58(2)求每一教師每一課程的學(xué)生選修人數(shù)(超過(guò)50人),要求顯示教師工號(hào)、課程代碼和學(xué)生人數(shù)。顯示時(shí),查詢結(jié)果按人數(shù)升序排序,人數(shù)相同按工號(hào)升序、課程代碼降序排序。SELECT工號(hào),課程信息表.課程代碼,COUNT(學(xué)號(hào))FROM選課表,成績(jī)表WHERE選課表.課程代碼=成績(jī)表.課程代碼GROUPBY工號(hào),選課表.課程代碼HAVINGCOUNT(*)>50ORDERBY3,工號(hào),選課表.課程代碼DESC;59該語(yǔ)句先求出選課表和成績(jī)表中學(xué)生選修教師課程的那些元組,然后根據(jù)教師工號(hào)和課程代碼分組,去掉小于等于50人的組,對(duì)余下的組統(tǒng)計(jì)元組個(gè)數(shù),再顯示余下組的教師工號(hào)、課程代碼和人數(shù)。ORDERBY子句中數(shù)字3表示對(duì)SELECT子句中第3個(gè)列值(學(xué)生人數(shù))進(jìn)行升序排列,若人數(shù)相同,則按工號(hào)升序、課程號(hào)降序排列。60在Access2010數(shù)據(jù)庫(kù)中,使用SQL查詢功能的過(guò)程如圖9.1所示。(1)啟動(dòng)數(shù)據(jù)庫(kù):?jiǎn)?dòng)Access2010,創(chuàng)建一個(gè)空的數(shù)據(jù)庫(kù),或者啟動(dòng)一個(gè)已經(jīng)既存的數(shù)據(jù)庫(kù);(2)創(chuàng)建查詢:在“創(chuàng)建”選項(xiàng)卡中,單擊“查詢”組的“查詢?cè)O(shè)計(jì)”按鈕

;(3)創(chuàng)建SQL查詢:在彈出的“顯示表”對(duì)話框中,單擊“關(guān)閉”按鈕

,這時(shí)在“設(shè)計(jì)”選項(xiàng)卡中,出現(xiàn)“SQL視圖”等選項(xiàng),單擊“SQL視圖”按鈕

,就可以在SQL的輸入?yún)^(qū)域中輸入SQL語(yǔ)句;(4)運(yùn)行SQL:在輸入?yún)^(qū)域中輸入正確的SQL語(yǔ)句后,單擊“運(yùn)行”按鈕

,就執(zhí)行所寫(xiě)的SQL語(yǔ)句。61629.3.4數(shù)據(jù)查詢中的限制和規(guī)定在SELECT語(yǔ)句具體使用時(shí),還有許多限制和規(guī)定,下面分別敘述。1.SELECT子句的規(guī)定SELECT子句用于描述查詢輸出的表格結(jié)構(gòu),即輸出值的列名或表達(dá)式。其形式如下:SELECT[ALL|DISTINCT]<列名或列表達(dá)式序列>|*63DISTINCT選項(xiàng)保證重復(fù)的行將從結(jié)果中去除;而ALL選項(xiàng)是默認(rèn)的,將保證重復(fù)的行留在結(jié)果中,一般就不必寫(xiě)出。(1)星號(hào)*是對(duì)于在FROM子句中命名表的所有列的簡(jiǎn)寫(xiě)。(2)列表達(dá)式是對(duì)于一個(gè)單列求聚合值的表達(dá)式。(3)允許表達(dá)式中出現(xiàn)包含+、-、*和/以及列名、常數(shù)的算式術(shù)表達(dá)式。64例9.12:對(duì)基本表教師信息表、選課表、學(xué)生信息表、成績(jī)表進(jìn)行查詢。(1)在基本表成績(jī)表中檢索男同學(xué)選修的課程的課程代碼SELECTDISTINCT課程代碼FROM學(xué)生信息表,成績(jī)表WHERE學(xué)生信息表.學(xué)號(hào)=成績(jī)表.學(xué)號(hào)AND性別=‘男’;由于一門課程可以有許多男同學(xué)選修,因此為避免輸出重復(fù)的課程代碼,需在SELECT后面加上DISTINCT。65(2)檢索每個(gè)教師的總工資SELECT工號(hào),姓名,基本工資+崗位津貼FROM教師信息表;這里“基本工資+崗位津貼”不是列名,而是一個(gè)表達(dá)式。662.列和基本表的改名操作有時(shí),一個(gè)基本表在SELECT語(yǔ)句中多次出現(xiàn),即這個(gè)表被多次調(diào)用。為區(qū)別不同的引用,應(yīng)給每次的引用標(biāo)上不同的名字。有時(shí),用戶也可以要求輸出的列名和基本表的列名不一致,可在SELECT子句用“舊名AS新名”形式改名,下例說(shuō)明了這點(diǎn)。67例9.13:在基本表學(xué)生信息表中檢索每個(gè)學(xué)生的姓名和出生年月,輸出的列名為STUDENT_NAME和BIRTH_DAY。SELECT姓名ASSTUDENT_NAME,出生年月ASBIRTH_DAYFROM學(xué)生信息表;在實(shí)際應(yīng)用時(shí),AS字樣可省略。683.集合的并、交、差操作當(dāng)兩個(gè)子查詢結(jié)果的結(jié)構(gòu)完全一致時(shí),可以讓這兩個(gè)子查詢執(zhí)行并、交、差操作。并、交、差的運(yùn)算符為UNION、INTERSECT和EXCEPT。(SELECT查詢語(yǔ)句1)UNION[ALL](SELECT查詢語(yǔ)句2)69(SELECT查詢語(yǔ)句1)INTERSECT[ALL](SELECT查詢語(yǔ)句2)

(SELECT查詢語(yǔ)句1)EXCEPT[ALL](SELECT查詢語(yǔ)句2)

上述操作中不帶關(guān)鍵字ALL時(shí),返回結(jié)果消除了重復(fù)元組;而帶ALL時(shí),返回結(jié)果中未消除重復(fù)元組。704.條件表達(dá)式中的比較操作條件表達(dá)式可以用各種運(yùn)算符組合而成,常用的比較運(yùn)算符見(jiàn)表9.1.下面分別介紹。(1)算術(shù)比較操作條件表達(dá)式中可出現(xiàn)算術(shù)比較運(yùn)算符(<、<=、>、>=、=、!=),也可以用“BETWEEN…AND…”比較運(yùn)算符限定一個(gè)范圍。71例9.14:在基本表學(xué)生信息表中檢索1990年到1995年出生的學(xué)生姓名,可用下列語(yǔ)句實(shí)現(xiàn):SELECT姓名FROM學(xué)生信息表WHERE出生年月>=’1990-1-1’AND出生年月<=‘1995-12-31’;若使用“BETWEEN…AND…”,就更容易理解了72SELECT姓名FROM學(xué)生信息表WHERE出生年月BETWEEN’1990-1-1’AND‘1995-12-31’;類似的,不在某個(gè)范圍內(nèi)可用“NOTBETWEEN…AND…”比較運(yùn)算符。73運(yùn)算符名稱符號(hào)及格式說(shuō)明算術(shù)比較判斷<表達(dá)式1>θ<表達(dá)式2>θ為算術(shù)比較運(yùn)算符比較兩個(gè)表達(dá)式的值之間判斷<表達(dá)式1>[NOT]BETWEEN<表達(dá)式2>AND<表達(dá)式3>搜索(不)在給定范圍內(nèi)的數(shù)據(jù)相同判斷<字符串>[NOT]LIKE<匹配模式>查找(不)包含給定模式的值空值判斷<表達(dá)式>IS[NOT]NULL判斷某值是否為空值之內(nèi)判斷<元組>[NOT]IN(<集合>)判斷某元組是否在某集合內(nèi)限定比較判斷<元組>θALL|SOME|ANY(<集合>)元組與集合中每(某)一個(gè)元組滿足θ比較存在判斷[NOT]EXISTS(<集合>)判斷集合是否至少存在一個(gè)元組唯一判斷[NOT]UNIQUE(<集合>)判斷集合是否沒(méi)有重復(fù)元組74字符串的匹配操作條件表達(dá)式中字符串匹配操作符是“LIKE”。在表達(dá)式中可使用兩個(gè)通配符:百分號(hào)(%):與零個(gè)或多個(gè)字符組成的字符串匹配。下劃線(_):與單個(gè)字符匹配。例9.15:在基本表學(xué)生信息表中檢索姓名以‘張’打頭的學(xué)生姓名。SELECT姓名FROM學(xué)生信息表WHERE姓名LIKE‘張%’;在需要時(shí),也可使用“NOTLIKE”比較運(yùn)算符。75為了使字符串中包含特殊字符(即%和_),SQL允許定義轉(zhuǎn)義字符。轉(zhuǎn)義字符緊靠特殊字符并放在它前面,表示該特殊字符將被當(dāng)成普通字符。在LIKE比較中使用ESCAPE保留字來(lái)定義轉(zhuǎn)義字符。如果使用反斜線(\)作為轉(zhuǎn)義字符,那么:LIKE‘a(chǎn)b\%cd%‘ESCAPE’\’匹配所有以“ab%cd”開(kāi)頭的字符串。LIKE‘a(chǎn)b\\cd%‘ESCAPE’\’匹配所有以“ab\cd”開(kāi)頭的字符串。SQL允許使用NOTLIKE比較運(yùn)算符搜尋不匹配項(xiàng)。SQL還允許在字符上使用多種函數(shù),例如連接(“||”)、提取子串、計(jì)算字符串長(zhǎng)度、大小寫(xiě)轉(zhuǎn)換操作。76(3)空值的比較操作SQL中允許列值為空,空值用保留字NULL表示。例9.16:在基本表學(xué)生信息表中搜索出生年月為空值的學(xué)生姓名。SELECT姓名FROM學(xué)生信息表WHERE出生年月ISNULL;77這里“ISNULL”測(cè)試列值是否為空。如果要測(cè)試非空值,可用短語(yǔ)“ISNOTNULL”??罩档拇嬖谠黾恿怂阈g(shù)操作和比較操作的復(fù)雜性。SQL中規(guī)定,涉及到+、-、*、/的算術(shù)表達(dá)式中有一個(gè)值是空值時(shí),表達(dá)式的值也是空值。涉及到空值的比較操作的結(jié)果認(rèn)為是“false”。在聚合函數(shù)中遇到空值,除了COUNT(*)外,都跳過(guò)空值而去處理非空值。78(4)集合成員資格的比較SQL提供SELECT語(yǔ)句的嵌套子查詢機(jī)制。子查詢是嵌套在另一個(gè)查詢中的SELECT語(yǔ)句。判斷元組是否在子查詢的結(jié)果(即集合)中的操作,稱為“集合成員資格比較”。其形式如下:<元組>[NOT]IN(<集合>)這里的集合可以是一個(gè)SELECT查詢語(yǔ)句,或者是元組的集合,但其結(jié)構(gòu)應(yīng)與前面元組的結(jié)構(gòu)相同。IN操作符表示:如果元組在集合內(nèi),那么其邏輯值為true,否則為false。79例9.17:在基本表學(xué)生信息表和成績(jī)表中檢索至少不學(xué)PEDU11009.01和COMP11003.02兩門課程的學(xué)生學(xué)號(hào),可用下列形式表示:SELECT學(xué)號(hào)FROM學(xué)生信息表WHERE學(xué)號(hào)NOTIN(SELECT學(xué)號(hào)FROM成績(jī)表WHERE課程代碼IN(‘PEDU11009.01’,’COMP11003.02’))上式中子查詢表示選修PEDU11009.01和COMP11003.02課程的學(xué)生學(xué)號(hào)。這個(gè)查詢的否定是表示至少不學(xué)PEDU11009.01和COMP11003.02兩門課程的學(xué)生學(xué)號(hào),就是外層查詢的形式。80(5)集合成員的算數(shù)比較其形式如下<元組>θALL|SOME|ANY(<集合>)這里要求“元組”與集合中“元組”的結(jié)構(gòu)一致。θ是算數(shù)比較運(yùn)算符,“θALL”操作表示左邊那個(gè)元組與右邊集合中每一個(gè)元組滿足θ運(yùn)算,“θSOME”操作表示左邊那個(gè)元組與右邊集合中至少一個(gè)元組滿足θ運(yùn)算。ANY和SOME是同義詞,早期的SQL標(biāo)準(zhǔn)用ANY,為避免與英語(yǔ)中ANY意思混淆,后來(lái)的標(biāo)準(zhǔn)都改為SOME。這里應(yīng)該注意,元組比較操作與字符串比較類似。例如(a1,a2)<=(b1,b2),其意義與a1<b1OR((a1=b1)AND(a2<=b2))等價(jià)。兩個(gè)元組相等,則要求其對(duì)應(yīng)的列值都相等。81例9.18:對(duì)基本表教師信息表、選課表、學(xué)生信息表、成績(jī)表進(jìn)行檢索。(1)檢索學(xué)習(xí)課程代碼為COMP11003.02課程的學(xué)生學(xué)號(hào)和姓名。此查詢?cè)诶?.8中用IN表達(dá)。實(shí)際上IN可用“=SOME”代替:SELECT學(xué)號(hào),姓名FROM學(xué)生信息表WHERE學(xué)號(hào)=SOME(SELECT學(xué)號(hào)FROM成績(jī)表WHERE課程代碼=‘COMP11003.02’);82(2)檢索至少有一門成績(jī)超過(guò)學(xué)生00006一門成績(jī)的學(xué)生學(xué)號(hào)。SELECTDISTINCT學(xué)號(hào)FROM成績(jī)表WHERE成績(jī)>=SOME(SELECT成績(jī)FROM成績(jī)表WHERE學(xué)號(hào)=‘00006’);83(3)索不學(xué)COMP11003.02課程的學(xué)生姓名和出生年月。SELECT學(xué)生姓名,出生年月FROM學(xué)生信息表WHERE學(xué)號(hào)<>ALL(SELECT學(xué)號(hào)FROM成績(jī)表WHERE課程代碼=‘COMP11003.02’);84(4)檢索平均成績(jī)最高的學(xué)生學(xué)號(hào)SELECT學(xué)號(hào)FROM成績(jī)表GROUPBY學(xué)號(hào)HAVINGAVG(成績(jī))>=ALL(SELECTAVG(成績(jī))FROM成績(jī)表GROUPBY學(xué)號(hào));在SQL中,不允許對(duì)聚合函數(shù)進(jìn)行復(fù)合運(yùn)算,因此不能寫(xiě)成“SELECTMAX(AVG(成績(jī)))”形式。85(6)集合空否的測(cè)試可以用謂詞EXISTS來(lái)測(cè)試一個(gè)集合是否為非空,或空。其形式如下:[NOT]EXISTS(<集合>)不帶NOT的操作,當(dāng)集合非空時(shí)(即至少存在一個(gè)元組),其邏輯值為true,否則為false。帶NOT的操作,當(dāng)集合為空時(shí),其值為true,否則為false。86(7)集合中重復(fù)元組存在與否的測(cè)試可以用謂詞UNIQUE來(lái)測(cè)試一個(gè)集合里是否有重復(fù)元組存在。形式如下:[NOT]UNIQUE(<集合>)不帶NOT的操作,當(dāng)集合中不存在重復(fù)元組時(shí),其邏輯值為true,否則為false。帶NOT的操作,當(dāng)集合中存在重復(fù)元組時(shí),其邏輯值為true,否則為false。87例9.19:在基本表教師信息表和選課表中檢索只開(kāi)設(shè)了一門課程的教師工號(hào)和姓名。SELECT教師工號(hào),姓名FROM教師信息表WHEREUNIQUE(SELECT工號(hào)FROM選課表WHERE選課表.工號(hào)=教師信息表.工號(hào));889.3.5嵌套查詢的改進(jìn)寫(xiě)法由于SELECT語(yǔ)句中可以嵌套,使得查詢非常復(fù)雜,并且難于理解。為降低復(fù)雜度,SQL標(biāo)準(zhǔn)提供了兩個(gè)方法來(lái)改進(jìn):導(dǎo)出表和臨時(shí)視圖。這兩種數(shù)據(jù)結(jié)構(gòu)只在自身的語(yǔ)句中有效。891.導(dǎo)出表的使用SQL2允許在FROM子句中使用子查詢。如果在FROM子句中使用了子查詢,那么要給子查詢的結(jié)果起個(gè)表名和相應(yīng)的列名。90例9.20:在基本表成績(jī)表中檢索平均成績(jī)最高的學(xué)生學(xué)號(hào)。這個(gè)查詢?cè)诶?.18(4)中使用嵌套的方法書(shū)寫(xiě)?,F(xiàn)在可以把子查詢定義為導(dǎo)出表(命名為RESULT),移到外層查詢的FROM子句,得到如下形式:SELECT成績(jī)表.學(xué)號(hào)FROM成績(jī)表,(SELECTAVG(成績(jī))FROM成績(jī)表GROUPBY學(xué)號(hào))ASRESULT(AVG_SCORE)GROUPBY成績(jī)表.學(xué)號(hào)HAVINGAVG(成績(jī))>=ALL(RESULT.AVG_SCORE);912.WITH子句和臨時(shí)視圖SQL3允許用戶用WITH子句定義一個(gè)臨時(shí)視圖(即子查詢),置于SELECT語(yǔ)句的開(kāi)始處。而臨時(shí)視圖本身是用SELECT語(yǔ)句定義的。92例9.21:例9.20的SELECT語(yǔ)句還可以改寫(xiě)成使用WITH子句的形式。也就是把子查詢定義成臨時(shí)視圖(RESULT),置于SELECT語(yǔ)句的開(kāi)始處,得到如下形式:WITHRESULT(AVG_SCORE)ASSELECTAVG(成績(jī))FROM成績(jī)表GROUPBY學(xué)號(hào)SELECT學(xué)號(hào)FROM成績(jī)表,RESULTGROUPBY學(xué)號(hào)HAVINGAVG(成績(jī))>=ALL(RESULT.AVG_SCORE);用FROM子句或WHERE子句中的嵌套子查詢,在閱讀時(shí)有些難懂。把子查詢組織成WITH子句可以使查詢?cè)谶壿嬌细忧逦?39.3.6基本表的連接操作現(xiàn)在的SQL標(biāo)準(zhǔn)可以用較為直接的形式表示各式各樣的連接操作(包括自然連接操作),這些操作可在FROM子句中以直接的形式指出。在書(shū)寫(xiě)兩個(gè)關(guān)系的連接操作時(shí),SQL2把連接操作符分成連接類型和連接條件兩部分(如表9.2)。連接類型決定了如何處理連接條件中不匹配的元組。連接條件決定了兩個(gè)關(guān)系中哪些元組應(yīng)該匹配,以及連接結(jié)果中出現(xiàn)哪些屬性。94連接類型INNERJOIN(內(nèi)連接)LEFTOUTERJOIN(左外連接)RIGHTOUTERJOIN(右外連接)FULLOUTERJOIN(完全外連接)95連接條件NATURAL(應(yīng)寫(xiě)在連接類型的左邊)ON等值連接條件(應(yīng)寫(xiě)在連接類型的右邊)USING(A1,A2,…An)(應(yīng)寫(xiě)在連接類型的右邊)表9.2連接類型和連接條件

下面是與連接操作有關(guān)的解釋和說(shuō)明:連接類型分成內(nèi)連接和外連接兩種。內(nèi)連接是等值連接,外連接又分成左、右、完全外連接三種。連接類型中INNER、OUTER字樣可不寫(xiě)。連接條件分成三種:(1)NATURAL:表示兩個(gè)關(guān)系執(zhí)行自然連接操作,即在兩個(gè)關(guān)系的公共屬性上作等值連接,運(yùn)算結(jié)果中公共屬性只出現(xiàn)一次。(2)ON等值連接條件:具體列出兩個(gè)關(guān)系在哪些相應(yīng)屬性上做等值連接。(3)USING(A1,A2,…An):類似于NATURAL形式,這里A1,A2,…An是兩個(gè)關(guān)系上的公共屬性,但可以不是全部公共屬性。在連接的結(jié)果中,公共屬性A1,A2,…An只出現(xiàn)一次。96若連接操作是“INNERJOIN”,未提及連接條件,那么這個(gè)操作等價(jià)于笛卡兒積,SQL2把此操作定義為“CROSSJOIN”操作。若連接操作是“FULLOUTERJOINONfalse”,這里連接的條件總是false,操作結(jié)果要把兩個(gè)關(guān)系的屬性全部包括進(jìn)去。SQL2把此操作定義為“UNIONJOIN”操作。97例9.22:設(shè)有關(guān)系R和S(表9.3的(a)和(b))。表9.3的(c),(d),(e)分別表示下面三個(gè)連接操作的結(jié)果:E1:RNATURALLEFTOUTERJOINSE2:RLEFTOUTERJOINSONR.B=S.BANDR.C=S.CE3:RLEFTOUTERJOINSUSING(B)98999.4SQL數(shù)據(jù)更新SQL的數(shù)據(jù)更新包括數(shù)據(jù)插入、刪除和修改等三種操作,下面分別介紹。1009.4.1數(shù)據(jù)插入往SQL基本表中插入數(shù)據(jù)的語(yǔ)句是INSERT語(yǔ)句。在SQL3中,有以下四種方式:(1)單元組的插入INSERTINTO<基本表名>[(<列名序列>)]VALUES(<元組值>)(2)多元組的插入INSERTINTO<基本表名>[(<列名序列>)]VALUES(<元組值>),(<元組值>),…,(<元組值>)101(3)查詢結(jié)果的插入INSERTINTO<基本表名>[(<列名序列>)]<SELECT查詢語(yǔ)句>這個(gè)語(yǔ)句可把一個(gè)SELECT語(yǔ)句的查詢結(jié)果插到某個(gè)基本表中。102(4)表的插入INSERTINTO<基本表名1>[(<列名序列>)]TABLE<基本表名2>這個(gè)語(yǔ)句可把基本表2的值插入到基本表1中。在上述各種插入語(yǔ)句中,如果插入的值在屬性個(gè)數(shù)、順序與基本表的結(jié)構(gòu)完全一致,那么基本表后的(<列名序列>)可省略,否則必須詳細(xì)列出。103例9.23:下面是往教學(xué)數(shù)據(jù)庫(kù)的基本表中插入元組的若干例子。(1)往基本表學(xué)生信息表中插入一個(gè)元組(‘00001’,’秦書(shū)琴’,’女’,’中文學(xué)院’,’1991-4-7)INSERTINTO學(xué)生信息表(學(xué)號(hào),姓名,性別,院系,出生年月)VALUES(‘00001’,’秦書(shū)琴’,’女’,’中文學(xué)院’,’1991-4-7’);104(2)往基本表成績(jī)表中插入一個(gè)選課元組(‘00001’,’PEDU11009.01’),此處成績(jī)值為空值,可用下列語(yǔ)句實(shí)現(xiàn):INSERTINTO成績(jī)表(學(xué)號(hào),課程代碼)VALUES(‘00001’,’PEDU11009.01’)105(3)往成績(jī)表連續(xù)插三個(gè)元組,可用下列語(yǔ)句實(shí)現(xiàn):INSERTINTO成績(jī)表VALUES(‘00001’,’PEDU11009.01’,75),(‘00002’,’COMP11003.02’,90),(‘00003’,’ENGL11004.01’,86);106(4)在基本表成績(jī)表中,把平均成績(jī)大于80分的男學(xué)生的學(xué)號(hào)和平均成績(jī)存入另一個(gè)已存在的基本表優(yōu)秀成績(jī)表(學(xué)號(hào),平均成績(jī))中,可用下列語(yǔ)句實(shí)現(xiàn):INSERTINTO優(yōu)秀成績(jī)表(學(xué)號(hào),平均成績(jī))SELECT學(xué)號(hào),AVG(成績(jī))FROM成績(jī)表WHERE學(xué)號(hào)IN(SELECT學(xué)號(hào)FROM學(xué)生信息表WHERE性別=‘男’)GROUPBY學(xué)號(hào)HAVINGAVG(成績(jī))>80;107(5)某一個(gè)班級(jí)的選課情況已在基本表班級(jí)選課表(學(xué)號(hào),課程代碼)中,把班級(jí)選課表的數(shù)據(jù)插入到成績(jī)表中,可用下列語(yǔ)句:INSERTINTO成績(jī)表(學(xué)號(hào),課程代碼)TABLE班級(jí)選課表;1089.4.2數(shù)據(jù)刪除SQL的刪除操作是指從基本表中刪除元組,其句法如下:DELETEFROM<基本表名>[WHERE<條件表達(dá)式>]該語(yǔ)句與SELECT查詢語(yǔ)句非常類似。刪除語(yǔ)句實(shí)際上是“SELECT*FROM<基本表名>109[WHERE<條件表達(dá)式>]”操作和DELETE操作的結(jié)合,執(zhí)行時(shí)首先從基本表中找出所有滿足條件的元組,然后把他們從基本表中刪去。應(yīng)該注意,DELETE語(yǔ)句只能從一個(gè)基本表中刪除元組。如果想從多個(gè)基本表中刪除元組,則必須為每一個(gè)基本表寫(xiě)一條DELETE語(yǔ)句。WHERE子句中的條件可以和SELECT語(yǔ)句的WHERE子句中條件一樣復(fù)雜,可以嵌套,也可以是來(lái)自幾個(gè)基本表的復(fù)合條件。如果省略WHERE子句,則基本表中所有元組被刪除,用戶使用起來(lái)要慎重,現(xiàn)在大多數(shù)系統(tǒng)在此時(shí)還要用戶再次確認(rèn)后才執(zhí)行。110例9.24:(1)把課程代碼為ENGL11004.01的成績(jī)從基本表成績(jī)表中刪除,DELETEFROM成績(jī)表WHERE課程代碼=‘ENGL11004.01’);111(2)把ENGL11004.01課程中小于該課程平均成績(jī)的成績(jī)?cè)M從基本表成績(jī)表中刪除。DELETEFROM成績(jī)表WHERE課程代碼=ENGL11004.01AND成績(jī)<(SELECTAVG(成績(jī))FROM成績(jī)表WHERE課程代碼=’ENGL11004.01’);這里,在WHERE子句中又引用了一次DELETE子句中出現(xiàn)的基本表成績(jī)表,但這兩次引用是不相關(guān)的。也就是說(shuō),刪除語(yǔ)句執(zhí)行時(shí),先執(zhí)行WHERE子句中子查詢,然后再對(duì)查找到的元組執(zhí)行刪除操作。這樣的刪除操作在語(yǔ)義上是不會(huì)出問(wèn)題的。1129.4.3數(shù)據(jù)修改當(dāng)需要修改基本表中元組的某些列值時(shí),可以用UPDATE語(yǔ)句實(shí)現(xiàn),其句法如下:UPDATE<基本表名>SET<列名>=<值表達(dá)式>[,<列名>=<值表達(dá)式>…]|ROW=(<元組>)[WHERE<條件表達(dá)式>]其語(yǔ)義是:修改基本表中滿足條件表達(dá)式的那些元組中的列值,需修改的列值在SET子句中指出。SET子句中第一種格式是對(duì)符合條件元組中的列值進(jìn)行修改,第二種格式是可對(duì)符合條件的元組中每個(gè)列值進(jìn)行修改。113例9.25:對(duì)基本表成績(jī)表和選課表中的值進(jìn)行修改。(1)把ENGL11004.01課程的課程名稱改為DB。UPDATE選課表SET課程名稱=‘DB’WHERE課程代碼=‘ENGL11004.01’;114(2)把女同學(xué)的成績(jī)提高10%。UPDATE成績(jī)表SET成績(jī)=成績(jī)*1.1WHERE學(xué)號(hào)IN(SELECT學(xué)號(hào)FROM學(xué)生信息表WHERE性別=‘女’);115(3)當(dāng)ENGL11004.01的課程成績(jī)低于該門課程平均成績(jī)時(shí),將成績(jī)提高5%。UPDATE成績(jī)表SET成績(jī)=成績(jī)*1.05WHERE課程代碼=‘ENGL11004.01’AND成績(jī)<(SELECTAVG(成績(jī))FROM成績(jī)表WHERE課程代碼=‘ENGL11004.01’);此處兩次引用成績(jī)表是不相關(guān)的。也就是說(shuō),內(nèi)層SELECT語(yǔ)句在初始時(shí)做了一次,隨后對(duì)成績(jī)的修改都以初始平均成績(jī)?yōu)橐罁?jù)。116(4)在成績(jī)表中,把課程代碼為ENGL11004.01,學(xué)號(hào)為00096的元組修改為(‘ENGL11004.01’,‘00006’,95):UPDATE成績(jī)表SETROW=(‘ENGL11004.01’,‘00006’,95)WHERE課程代碼=‘ENGL11004.01’AND學(xué)號(hào)=’00096’;1179.5.1視圖的創(chuàng)建和撤銷在SQL中,外模式這級(jí)的數(shù)據(jù)結(jié)構(gòu)的基本單位是視圖(view),視圖是從若干基本表和(或)其他視圖構(gòu)造出來(lái)的表。這種構(gòu)造方法采用SELECT語(yǔ)句實(shí)現(xiàn)。在我們創(chuàng)建一個(gè)視圖時(shí),只是把其視圖的定義存放在數(shù)據(jù)字典中,而不存儲(chǔ)視圖對(duì)應(yīng)的數(shù)據(jù),在用戶使用視圖時(shí)才去求對(duì)應(yīng)的數(shù)據(jù)。因此,視圖被稱為“虛表”,基本表就稱為“實(shí)表”。1181.視圖的創(chuàng)建創(chuàng)建視圖可用“CREATEVIEW”語(yǔ)句實(shí)現(xiàn)。其句法如下:CREATEVIEW<視圖名>(<列表序列>)AS<SELECT查詢語(yǔ)句>119例9.26:對(duì)于教學(xué)數(shù)據(jù)庫(kù)中四個(gè)基本表教師信息表、選課表、學(xué)生信息表、成績(jī)表,用戶經(jīng)常要用到學(xué)號(hào)、姓名、課程名稱、成績(jī)等列的數(shù)據(jù),那么可用下列語(yǔ)句建立視圖:CREATEVIEWSTUDENT_SCORE(學(xué)號(hào),姓名,課程名稱,成績(jī))ASSELECT學(xué)生信息表.學(xué)號(hào),姓名,課程名稱,成績(jī)FROM學(xué)生信息表,成績(jī)表,選課表WHERE學(xué)生信息表.學(xué)號(hào)=成績(jī)表.學(xué)號(hào)AND成績(jī)表.課程代碼=選課表.課程代碼;此處,視圖中列名、順序與SELECT子句中的列名、順序一致,因此視圖名STUDENT_SCORE后的列名可省略。1202.視圖的撤銷在視圖不需要時(shí),可以用“DROPVIEW”語(yǔ)句把其從系統(tǒng)中撤銷,其句法如下:DROPVIEW<視圖名>121例9.27:撤銷STUDENT_SCORE視圖,可用下列語(yǔ)句實(shí)現(xiàn):DROPVIEWSTUDENT_SCORE;1229.5.2對(duì)視圖的操作在視圖定義以后,對(duì)于視圖的查詢(SELECT)操作,與基本表一樣,沒(méi)有什么區(qū)別。但對(duì)于視圖中元組的更新操作就不一樣了。由于視圖并不像基本表那樣實(shí)際存在,因此如何將對(duì)視圖的更新轉(zhuǎn)換成對(duì)基本表的更新,是系統(tǒng)應(yīng)該解決的問(wèn)題。為簡(jiǎn)單起見(jiàn)現(xiàn)在一般只對(duì)“行列子集視圖”才能更新。123定義9.1如果視圖是從單個(gè)基本表只使用選擇、投影操作導(dǎo)出的,并且包含了基本表的主鍵,那么這樣的視圖稱為“行列子集視圖”,并且可以被執(zhí)行更新操作。允許用戶更新的視圖在定義時(shí)必須加上“WITHCHECKOPTION”短語(yǔ)。據(jù)上述定義可知,定義在多個(gè)基本表上的視圖,或者使用聚合操作的視圖,或者不包含基本表主鍵的視圖都是不允許更新的。124例9.28:如果定義了一個(gè)有關(guān)男學(xué)生的視圖:CREATEVIEWS_MALEASSELECT學(xué)號(hào),姓名,出生年月FROM學(xué)生信息表WHERE性別=’男’WITHCHECKOPTION;125由于這個(gè)視圖是從單個(gè)關(guān)系只使用選擇和投影導(dǎo)出的,并且包含主鍵學(xué)號(hào),因此是行列子集視圖,是可更新的。此時(shí),定義中又加上“WITHCHECKOPTION”短語(yǔ),就能允許用戶對(duì)視圖進(jìn)行插入、刪除和修改操作。譬如,執(zhí)行插入操作:INSERTINTOS_MALEVALUES(‘00001’,’秦書(shū)琴’,’1991-4-7’);系統(tǒng)自動(dòng)會(huì)把它轉(zhuǎn)變成下列語(yǔ)句:INSERTINTOS_MALEVALUES(‘00001’,’秦書(shū)琴’,’1991-4-7’,’男’);1269.6嵌入式SQLSQL是一種強(qiáng)有力的說(shuō)明性查詢語(yǔ)言。實(shí)現(xiàn)同樣的查詢用SQL書(shū)寫(xiě)比單純用通用編程語(yǔ)言(如C)編碼要簡(jiǎn)單得多。然而,使用通用編程語(yǔ)言訪問(wèn)數(shù)據(jù)庫(kù)仍是必要的。SQL不能提供屏幕控制、菜單管理、圖像管理、報(bào)表生成等動(dòng)作。而這些功能要靠C、COBOL、PASCAL、Java、PL/I、FORTRAN等語(yǔ)言實(shí)現(xiàn)。這些語(yǔ)言稱為主語(yǔ)言。在主語(yǔ)言中使用的SQL結(jié)構(gòu)稱為嵌入式SQL。1279.6.1嵌入式SQL的實(shí)現(xiàn)方式SQL語(yǔ)言有兩種使用方式:一種是在終端交互方式下使用,稱為交互式SQL;另一種是嵌入在主語(yǔ)言的程序中使用,稱為嵌入式SQL。嵌入式SQL的實(shí)現(xiàn),有兩種處理方式:一種是擴(kuò)充主語(yǔ)言的編譯程序,使之能處理SQL語(yǔ)句;另一種是采用預(yù)處理方式。目前多數(shù)系統(tǒng)采用后一種方式。128129預(yù)處理方式是先用預(yù)處理程序?qū)υ闯绦蜻M(jìn)行掃描,識(shí)別出SQL語(yǔ)句,并處理成主語(yǔ)言的函數(shù)調(diào)用形式;然后再用主語(yǔ)言的編譯程序編譯成目標(biāo)程序。通常DBMS制造商提供一個(gè)SQL函數(shù)定義庫(kù),共編譯時(shí)使用。源程序的預(yù)處理和編譯的具體過(guò)程如圖9.2所示。存儲(chǔ)設(shè)備上的數(shù)據(jù)庫(kù)是用SQL語(yǔ)句存放的,數(shù)據(jù)庫(kù)和主語(yǔ)言程序間信息的傳遞是通過(guò)共享變量實(shí)現(xiàn)的。這些共享變量要用SQL的DECLARE語(yǔ)句說(shuō)明,隨后SQL語(yǔ)句就可引用這些變量。共享變量也就成了SQL和主語(yǔ)言的接口。130SQL2規(guī)定,SQL_STATE是一個(gè)特殊的共享變量,起著解釋SQL語(yǔ)句執(zhí)行狀況的作用,它是一個(gè)由5個(gè)字符組成的字符數(shù)組。當(dāng)一個(gè)SQL語(yǔ)句執(zhí)行成功時(shí),系統(tǒng)自動(dòng)給,SQL_STATE附上全零值(即“00000”),表示未發(fā)生錯(cuò)誤;否則其值為非全零,表示執(zhí)行SQL語(yǔ)句時(shí)發(fā)生的各種錯(cuò)誤情況。譬如“02000”用來(lái)表示未找到元組。在執(zhí)行一個(gè)SQL語(yǔ)句后,程序可根據(jù)SQL_STATE的值轉(zhuǎn)向不同的分支,以控制程序的流向。1319.6.2嵌入式SQL的使用規(guī)定在主語(yǔ)言的程序中使用SQL語(yǔ)句有以下規(guī)定:1.在程序中要區(qū)分SQL語(yǔ)句與主語(yǔ)言語(yǔ)句所有SQL語(yǔ)句前必須加上前綴標(biāo)識(shí)“EXECSQL”,并以“END_EXEC”作為語(yǔ)句結(jié)束標(biāo)志。嵌入的SQL語(yǔ)句的格式如下:EXECSQL<SQL語(yǔ)句>END_EXEC結(jié)束標(biāo)志在不同的主語(yǔ)言中是不同的,在C和PASCAL語(yǔ)言程序中規(guī)定結(jié)束標(biāo)志不用END_EXEC,而使用分號(hào)“;”。1322.允許嵌入的SQL語(yǔ)句引用主語(yǔ)言的程序變量(稱為共享變量)允許嵌入的SQL語(yǔ)句引用主語(yǔ)句的程序變量。但有兩條規(guī)定:(1)引用時(shí),這些變量前必須加冒號(hào)“:”作為前綴標(biāo)識(shí),以示與數(shù)據(jù)庫(kù)中變量(如屬性名)有區(qū)別。(2)這些變量要用SQL的DECLARE語(yǔ)句說(shuō)明。例如,在C語(yǔ)言程序中可用下列形式說(shuō)明共享變量:133EXECSQLBEGINDECLARESECTION;charsno[5],name[9];charSQL_STATE[6];EXECSQLENDDECLARESECTION;上面四行語(yǔ)句組成一個(gè)說(shuō)明節(jié),第二行和第三行說(shuō)明了三個(gè)共享變量。其中,共享變量SQL_STATE的長(zhǎng)度為6,而不是5,這是由于C語(yǔ)言中規(guī)定變量值在作字符串使用時(shí)應(yīng)有結(jié)束符”\0”引起的。1349.6.3SQL的集合處理方式與主語(yǔ)言單記錄處理方式之間的協(xié)調(diào)由于SQL語(yǔ)句處理的是記錄集合,而主語(yǔ)言語(yǔ)句一次只能處理一個(gè)記錄,因此需要用游標(biāo)(cursor)機(jī)制,把集合操作轉(zhuǎn)換成單記錄處理方式。與游標(biāo)有關(guān)的SQL語(yǔ)句有下列四個(gè):135(1)游標(biāo)定義語(yǔ)句(DECLARE)。游標(biāo)是與某一查詢結(jié)果相聯(lián)系的符號(hào)名,游標(biāo)用SQL的DECLARE語(yǔ)句定義,句法如下:EXECSQLBEGINDECLARE<游標(biāo)名>CURSORFOR<SELECT語(yǔ)句>END_EXEC游標(biāo)定義語(yǔ)句是一個(gè)說(shuō)明語(yǔ)句,定義中的SELECT語(yǔ)句并不立即執(zhí)行。136(2)游標(biāo)打開(kāi)語(yǔ)句(OPEN)。該語(yǔ)句執(zhí)行游標(biāo)定義中的SELECT語(yǔ)句,

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論