數據庫的查詢與視圖


第4章 數據庫的查詢和視圖

4.1.1 選擇列

通過SELECT語句的<select_list>項組成結果表的列。

<select_list>::=

SELECT [ ALL |DISTINCT ] [ TOP n [ PERCENT ] [ WITH TIES ] ]

{ * /*選擇當前表或視圖的所有列*/

| { table_name |view_name | table_alias } .* /*選擇指定的表或視圖的所有列*/

| { colume_name |expression | IDENTITYCOL | ROWGUIDCOL }

[ [ AS ]column_alias ] /*選擇指定的列*/

| column_alias =expression /*選擇指定列並更改列標題*/

} [ , … n ]


1. 選擇一個表中指定的列

一般情況下,希望包含在結果表中的列表清單在SELECT關鍵字之后,就像前面用到的那樣,當在SELECT關鍵字后面指定*時,就表示全部列都包含在結果表中。不指定*,可以列出一個表中的某些列,各列名之間要以逗號分隔。

 

4.1.1 選擇列

【例4.1】查詢XSCJ數據庫的XS表中各個同學的姓名、專業名和總學分。

USE XSCJ

SELECT 姓名,專業名,總學分

FROM XS

 

4.1.1 選擇列

【例4.2】查詢XS表中計算機專業同學的學號、姓名和總學分。查詢XS表中的所有列。

SELECT 學號,姓名,總學分

FROM XS

WHERE 專業名= ‘計算機’

GO

SELECT *

FROM XS

GO

當在SELECT語句指定列的位置上使用*號時,表示選擇表的所有列。

執行后將列出XS表中的所有數據,如圖4.2所示:

 

4.1.1 選擇列

2. 修改查詢結果中的列標題

當希望查詢結果中的某些列或所有列顯示時使用自己選擇的列標題時,可以在列名之后使用AS子句來更改查詢結果的列標題名。其中column_alias是指定的列標題。

【例4.3】查詢XS表中計算機系同學的學號、姓名和總學分,結果中各列的標題 分別指定為number、name和mark。

SELECT 學號 AS number, 姓名 AS name,總學分 AS mark

FROM XS

WHERE 專業名= ‘計算機’

該語句的執行結果如圖4.3所示。

更改查詢結果中的列標題也可以使用column_alias=expression的形式。例如:

SELECT number = 學號, name = 姓名, mark = 總學分

FROM XS

WHERE 專業名= ’計算機’

該語句的執行結果與上例的結果完全相同。

 

4.1.1 選擇列


注意,當自定義的列標題中含有空格時,必須使用引號將標題括起來。例如:

SELECT ‘Student number’ = 學號,姓名 AS ‘Student name’, mark = 總學分

FROM XS

WHERE 專業名= ‘計算機’

 

4.1.1 選擇列

3. 替換查詢結果中的數據

在對表進行查詢時,有時對所查詢的某些列希望得到的是一種概念而不是具體的數據。例如查詢XS表的總學分,所希望知道的是學習的總體情況,這時,就可以用等級來替換總學分的具體數字。

要替換查詢結果中的數據,則要使用查詢中的CASE表達式,格式為:

CASE

WHEN 條件1 THEN 表達式1

WHEN 條件2 THEN 表達式2

……

ELSE 表達式

END

SQL Server按照順序計算每一個條件,如果找到條件為真的語句,SQL Server就執行TEHN關鍵字后的表達式;否則執行可選的ELSE關鍵字后的語句。若沒有為真的條件,也沒有關鍵字,則CASE表達式返回值為空。

 

4.1.1 選擇列

【例4.4】查詢XS表中計算機系各同學的學號、姓名和總學分,對其總學分按以下規則進行替換:若總學分為空值,替換為“尚未選課”;若總學分小於50,替換為“不及格”;若總學分在50與52之間,替換為“合格”;若總學分大於52,替換為“優秀”。列標題更改為“等級”。

SELECT 學號, 姓名,

等級=

CASE

WHEN 總學分 IS NULL THEN ‘尚未選課’

WHEN 總學分 < 50 THEN ‘不及格’

WHEN 總學分 >=50 and 總學分<=52THEN ‘合格’

ELSE ‘優秀’

END

FROM XS

WHERE 專業名=’計算機’


 

4.1.1 選擇列

4. 計算列值

使用SELECT對列進行查詢時,在結果中可以輸出對列值計算后的值,即SELECT子句可使用表達式作為結果,格式為:

SELECT expression[ , expression ]

【例4.5】按120分計算成績顯示。

SELECT 學號, 課程號,

成績120=成績*1.20

FROM XS_KC


4.1.1 選擇列

計算列值使用算術運算符:+(加)、-(減)、*(乘)、/(除)和%(取余),其中5種算術運算符(+、-、*、/)可以用於任何數字類型的列,包括:int、smallint、tinyint、decimal、numeric、float、real、money和smallmoney;%可以用於上述除money和smallmoney以外的數字類型。

5. 消除結果集中的重復行

對表只選擇其某些列時,可能會出現重復行。例如,若對XSCJ數據庫的XS表只選擇專業名和總學分,則出現多行重復的情況。可以使用DISTINCT關鍵字消除結果集中的重復行,其格式是:

SELECT DISTINCTcolumn_name [ , column_name…]

關鍵字DISTINCT的含義是對結果集中的重復行只選擇一個,保證行的唯一性。

【例4.6】對XSCJ數據庫的XS表只選擇專業名和總學分,消除結果集中的重復行。

SELECT DISTINCT 專業名, 總學分

FROM XS


圖4.6消除重復行

與DISTINCT相反,當使用關鍵字ALL時,將保留結果集的所有行。當SELECT語句中缺省ALL與DISTINCT時,默認值為ALL。

6. 限制結果集返回行數

如果SELECT語句返回的結果集的行數非常多,可以使用TOP選項限制其返回的行數。TOP選項的基本格式為:

TOP n [ PERCENT ]

其中n是一個正整數,表示返回查詢結果集的前n行。若帶PERCENT關鍵字,則表示返回結果集的前n%行。

 

4.1.1 選擇列

【例4.7】對XSCJ數據庫的XS表選擇姓名、專業名和總學分,只返回結果集的前6行。

SELECT TOP 6 姓名,專業名,總學分

FROM XS



 

4.1.2 選擇行

在SQL Server中,選擇行是通過在SELECT語句中WHERE子句指定選擇的條件來實現的。這一節將詳細討論WHERE子句中查詢條件的構成。WHERE子句必須緊跟FROM子句之后,其基本格式為:

在SQL中,返回邏輯值(TRUE或FALSE)的運算符或關鍵字都可稱為謂詞。

1. 表達式比較

比較運算符用於比較兩個表達式值,共有9個,分別是: =(等於)、<(小於)、<=(小於等於)、>(大於)、>=(大於等於)、<>(不等於)、!=(不等於)、!<(不小於)、!>(不大於)。比較運算的格式為:

expression { = |< | <= | > | >= | <> | != | !< | !> } expression

其中expression是除text、ntext和image外類型的表達式。

當兩個表達式值均不為空值(NULL)時,比較運算返回邏輯值TRUE(真)或FALSE(假);而當兩個表達式值中有一個為空值或都為空值時,比較運算將返回UNKNOWN。

【例4.8】查詢XSCJ數據庫XS表中通信工程專業總學分大於等於42的同學的情況。

SELECT *

FROM XS

WHERE專業名 = ‘通信工程’ and 總學分 >=42

 

4.1.2 選擇行

2. 模式匹配

LIKE謂詞用於指出一個字符串是否與指定的字符串相匹配,其運算對象可以是char、varchar、text、ntext、datetime和smalldatetime類型的數據,返回邏輯值TRUE或FALSE。LIKE謂詞表達式的格式為:

string_expression[ NOT ] LIKE string_expression [ ESCAPE ‘escape_character’ ]

【例4.9】查詢XSCJ數據庫XS表中計算機系的學生情況。查詢XSCJ數據庫XS表中姓“王”且單名的學生情況。

SELECT *

FROM XS

WHERE 專業名 LIKE ‘計算機’

GO

SELECT *

FROM XS

WHERE 姓名 LIKE ‘王_’

GO

 

4.1.2 選擇行

使用LIKE進行模式匹配時,常使用通配符,即可進行模糊查詢。有關通配符的格式和含義請見附錄中介紹T-SQL語言的相關說明。

執行結果如圖4.8所示。


若要匹配的內容為通配符的字符(包括%、_、[] 、^),可使用關鍵字ESCAPE。以告訴系統其后的每個字符均作為實際匹配的字符,而不再作為通配符。

3. 范圍比較

用於范圍比較的關鍵字有兩個:BETWEEN和IN。

當要查詢的條件是某個值的范圍時,可以使用BETWEEN關鍵字。BETWEEN關鍵字指出查詢范圍,格式為:

expression [ NOT ]BETWEEN expression1 AND expression2

 

4.1.2 選擇行

當不使用NOT時,若表達式expression的值在表達式expression1與expression2之間(包括這兩個值),則返回TRUE,否則返回FALSE;使用NOT時,返回值剛好相反。

注意:expression1的值不能大於expression2的值。

使用IN關鍵字可以指定一個值表,值表中列出所有可能的值,當與值表中的任一個匹配時,即返回TRUE,否則返回FALSE。使用IN關鍵字指定值表的格式為:

expression IN (expression [,…n])

【例4.10】查詢XSCJ數據庫XS表中不在1989年出生的學生情況。查詢XSCJ數據庫XS表中專業名為“計算機”或“通信工程”或“無線電”的學生的情況。

SELECT *

FROM XS

WHERE 出生時間 NOT BETWEEN ‘1989-1-1’ and ‘1989-12-31’

GO

SELECT *

FROM XS

WHERE 專業名 IN (’計算機’, ’通信工程’, ’無線電’)

GO

 

4.1.2 選擇行

該語句與下列語句等價:

SELECT *

FROM XS

WHERE 專業名 = ’計算機’ or 專業名 = ’通信工程’ or 專業名 = ’無線電’

說明:IN關鍵字最主要的作用是表達子查詢。

4. 空值比較

如果兩個值當中有一個或者都為空,則對這兩個值的比較結果是未知的。NULL謂詞提供了一種方法,用來測試值為空或者非空。格式為:

expression IS [NOT ] NULL

當不使用NOT時,若表達式expression的值為空值,返回TRUE,否則返回FALSE;當使用NOT時,結果剛好相反。

【例4.11】查詢XSCJ數據庫中總學分尚不定的學生情況。

SELECT *

FROM XS

WHERE 總學分 IS NULL

 

4.1.2 選擇行

5. CONTAINS謂詞

若需要在表中搜索指定的單詞、短語或近義詞等,可以使用CONTAINS謂詞。CONTAINS謂詞用於在表中搜索指定的字符串,可以是精確匹配,也可以是模糊匹配,還可以是加權匹配。要使用CONTAINS謂詞,必須在操作的表上事先建立全文索引。

CONTAINS ( {column | * } , ‘<contains_search_condition>’)

上式中,column表示在指定的列中搜索,*表示在所有列中搜索; <contains_search_condition>為搜索的限定或說明。

<contains_search_condition>::=

{<simple_term> | <prefix_term> | <generation_term> |<proximity_term> | <weighted_term> }

| {(<contains_search_condition> ) { AND | AND NOT | OR }<contains_search_condition> […n] }

說明:

simple_term:用於說明搜索的是單詞還是短語,格式為:word | “phrase”,word為單詞,即不含空格和標點符號的字符串;短語是含一個或多個空格的字符串。如果搜索的是短語,則需要用雙引號將其括起來。

 

4.1.2 選擇行

prefix_term:給出了要搜索的單詞或短語必須匹配的前綴,格式為:

{ “word*” |“phase*”}

其中word為單詞,phase為短語,當查詢的串是是短語時,需用雙引號定界。

generation_term:說明搜索包含原詞的派生詞,所謂派生詞是指原詞的名詞單、復數形式或動詞的各種時態等。格式為:

FORMSOF (INFLECTIONAL , <simple_term> [,…n])

proximity_term:表示搜索包含NEAR或~運算符左右兩邊的詞或短語,格式為: { <simple_term> | <prefix_term> } { { NEAR | ~ } {<simple_term> | <prefix_term> }[…n]

weight_term:指明本語句是加權搜索,即查詢的數據與給定的權重進行加權匹配,格式為:

ISABOUT ( { {<simple_term> | <prefix_term> | <generation_term> |<proximity_term> } [ WEUGHT (weight_value) ] } [,…n] )

其中weight_value是一個0~1之間的數,表示權重。

6. FREETEXT謂詞

與CONTAINS謂詞類似,FREETEXT謂詞也用於在一個表中搜索單詞或短語,並要求表已建全文索引。格式為:

FREETEXT ( {column | * }, ‘freetext_string’ )

其中freetext_string是要搜索的字符串。

FREETEXT的查詢精度沒有CONTAINS高,他並不要求對它們進行嚴格的模式匹配。 FREETEXT對所查詢的串也沒有寫法要求,因此FREETEXT也稱為自由式查詢。

 

4.1.2 選擇行

7. 子查詢

子查詢通常與IN、EXIST謂詞及比較運算符結合使用。

(1)IN子查詢

IN子查詢用於進行一個給定值是否在子查詢結果集中的判斷,格式為:

expression [ NOT ]IN ( subquery )

其中subquery是子查詢。當表達式expression與子查詢subquery的結果表中的某個值相等時,IN謂詞返回TRUE,否則返回FALSE;若使用了NOT,則返回的值剛好相反。

【例4.12】在XSCJ數據庫中有描述課程情況的表KC和描述學生成績表的表XS_KC,表的結構和樣本數據見附錄A。要查找選修了課程號為101的課程的學生的情況:

SELECT *

FROM XS

WHERE 學號 IN

( SELECT 學號 FROM XS_KC WHERE 課程號 = ‘101’ )

 

4.1.2 選擇行

在執行包含子查詢的SELECT語句時,系統先執行子查詢,產生一個結果表,再執行查詢。本例中,先執行子查詢:

SELECT 學號

FROM XS_KC

WHERE 課程名 = ‘101’


SELECT *

FROM XS

WHERE 學號 NOT IN

( SELECT 學號

FROM XS_KC

WHERE 課程號 IN

( SELECT 課程號

FROM KC

WHERE 課程名 = '離散數學'

)

)

 

 

4.1.2 選擇行

(2)比較子查詢

這種子查詢可以認為是IN子查詢的擴展,它使表達式的值與子查詢的結果進行比較運算,格式為:

expression { <| <= | = | > | >= | != | <> | !< | !> } { ALL | SOME | ANY} ( subquery )

其中expression為要進行比較的表達式,subquery是子查詢。ALL、SOME和ANY說明對比較運算的限制。

ALL指定表達式要與子查詢結果集中的每個值都進行比較,當表達式與每個值都滿足比較的關系時,才返回TRUE,否則返回FALSE;

SOME或ANY表示表達式只要與子查詢結果集中的某個值滿足比較的關系時,就返回 TRUE,否則返回FALSE。

【例4.14】查找比所有計算機系的學生年齡都大的學生。

SELECT *

FROM XS

WHERE 出生時間 <ALL

( SELECT 出生時間

FROM XS

WHERE 專業名 = '計算機'

)

 

【例4.15】查找課程號206的成績不低於課程號101的最低成績的學生的學號。

SELECT 學號

FROM XS_KC

WHERE 課程號 = '206' AND 成績 !< ANY

( SELECT 成績

FROM XS_KC

WHERE 課程號 = '101'

)

 

4.1.2 選擇行

(3)EXISTS子查詢

EXISTS謂詞用於測試子查詢的結果是否為空表,若子查詢的結果集不為空,則EXISTS返回TRUE,否則返回FALSE。EXISTS還可與NOT結合使用,即NOT EXISTS,其返回值與EXIST剛好相反。格式為:

[ NOT ] EXISTS (subquery )

【例4.16】查找選修206號課程的學生姓名。

SELECT 姓名

FROM XS

WHERE EXISTS

( SELECT *

FROM XS_KC

WHERE 學號 = XS.學號 AND 課程號 = ‘206’

)

分析:

① 本例在子查詢的條件中使用了限定形式的列名引用XS.學號,表示這里的學號列出自表XS。

 

4.1.2 選擇行

② 本例與前面的子查詢例子不同點是,前面的例子中,內層查詢只處理一次,得到一個結果集,再依次處理外層查詢;而本例的內層查詢要處理多次,因為內層查詢與XS.學號有關,外層查詢中XS表的不同行有不同的學號值。這類子查詢稱為相關子查詢,因為子查詢的條件依賴與外層查詢中的某些值。

【例4.17】查找選修了全部課程的同學的姓名。

SELECT 姓名

FROM XS

WHERE NOT EXISTS

(SELECT *

FROM KC

WHERE NOT EXISTS

( SELECT *

FROM XS_KC

WHERE 學號=XS.學號 AND 課程號=KC.課程號

)

)

 

4.1.3 FROM子句

SELECT的查詢對象由FROM子句指定,其格式為:

[ FROM{<table_source>} [,…n] ]

其中table_source指出了要查詢的表或視圖。

<table_source>::=

table_name [ [ AS] table_alias ] [ WITH ( <table_hint>[,…] ) ]

/*查詢表,可以指定別名*/

| view_name [ [ AS] table_alias ] /*查詢視圖*/

| rowset_function[ [AS ] table_alias ] /*行集函數*/

| OPENXML /*XML文檔*/

| derived_table [AS ] table_alias [ ( column_alias [,…n] ) ] /*子查詢*/

|<joined_table> /*連接表*/

 

1. table_name

table_name指定SELECT語句要查詢的表,從前面的例子中已經了解了其作用。可以使用AS選項為表指定別名,AS也可以省略,直接給出別名即可。別名主要用在相關子查詢及連接查詢中。

【例4.18】查找選修了學號為081102同學所選修的全部課程的同學的學號。

分析:本例即要查找這樣的學號y,對所有的課程號x,若081102號同學選修了該課,那么y也選修了該課。

SELECT DISTINCT 學號

FROM XS_KC AS CJ1

WHERE NOT EXISTS

( SELECT *

FROM XS_KC AS CJ2

WHERE CJ2.學號 = ‘081102’ AND NOT EXISTS

( SELECT *

FROM XS_KC AS CJ3

WHERE CJ3.學號= CJ1.學號 AND CJ3.課程號 = CJ2.課程號

)

)

4.1.3 FROM子句

 

4.1.3 FROM子句

2. view_name

view_name為視圖名,也可以為其指定別名。有關視圖的介紹請見4.3節。

3. rowset_function

rowset_function是一個行集函數,行集函數通常返回一個表或視圖。主要的行集函數有CONTAINSTABLE、FREETEXTTABLE、OPENDATASOURCE、OPENQUERY、OPENROWSET和OPENXML。

(1) CONTAINSTABLE函數

該函數與CONTAINS謂詞相對應,用於對表進行全文查詢,並且要求所查詢的表上建立了全文索引。CONTAINSTABLE函數的語法格式為:

CONTAINSTABLE (table , { column | * } , ‘<contains_search_condition>’ [ , top_n_by_rank] )

其中table是進行全文查詢的表,column指定被查詢的列,*指對所有列進行查詢。 contains_search_condition與CONTAINS謂詞中的搜索條件完全相同。

CONTAINSTABLE函數返回包含滿足匹配條件的行,共有兩列:KEY和RANK,其中KEY是包含被檢索的字符串的行的主鍵值,RANK是一個等級值,指明行與字符串匹配的情況。可選項top_n_by_rank,說明只返回按RANK降序排列的結果表的前n行,其中n是正整數。

 

4.1.3 FROM子句

CONTAINSTABLE函數常與INNER JOIN結合使用。

(2) FREETEXTTABLE函數

FREETEXTTABLE函數與FREETEXT謂詞相對應,它的使用與CONTAINSTABLE函數類似,格式為:

FREETEXTTABLE (table , { column | * } , ‘freetext_string’ [ , top_n_by_rank ] )

該函數使用與FREETEXT謂詞相同的搜索條件。

(3) OPENDATASOURCE函數

該函數使用戶連接到服務器。格式為:

OPENDATASOURCE (provider_name , init_string )

其中provider_name是注冊為用於訪問數據源的OLE DB 提供程序的 PROGID 的名稱,init_string是連接字符串,這些字符串將要傳遞給目標提供程序的 IDataInitialize 接口。

例如:

SELECT *

FROMOPENDATASOURCE

( 'SQLOLEDB','Data Source=ServerName;UserID=MyUID;Password=MyPass'

).Northwind.dbo.Categories

 

4.1.3 FROM子句

(4) OPENQUERY函數

該函數在給定的鏈接服務器(一個 OLE DB 數據源)上執行指定的直接傳遞查詢,返回查詢的結果集。格式為:

OPENQUERY (linked_server , ‘query’ )

其中linked_server為連接的服務器名,query是查詢命令串。

例如:

EXECsp_addlinkedserver 'OSvr', 'Oracle 7.3',

'MSDAORA',

'ORCLDB'

GO

SELECT *

FROMOPENQUERY(OSvr, 'SELECT title, id FROM al.book')

GO

該例使用為Oracle提供的OLE DB對Oracle數據庫創建了一個名為Osvr的連接服務器,然后對該其進行檢索。

(5) OPENROWSET函數

該函數與OPENQUERY函數功能相同。

(6) OPENXML函數

OPENXML 通過XML文檔提供行集視圖。

 

4.1.3 FROM子句

4. derived_table

derived_table是由SELECT查詢語句的執行而返回的表,必須使用為其指定一個別名,也可以為列指定別名。

【例4.19】在XS表中查找1990年1月1日以前出生的學生的姓名和專業名,分別使用別名stu_name和speciality表示。

SELECTm.stu_name,m.speciality

FROM ( SELECT *FROM XS WHERE 出生時間<'19900101' ) AS m

(num,stu_name,speciality,sex,birthday,score,mem ,photo )

注意,若要為列指定別名,則必須為所有列指定別名。

執行結果如圖4.11所示。

5. joined_table

joined_table為連接表,將在下一小節介紹。


 

4.1.4 連接

連接是兩元運算,可以兩個或多個表進行查詢,結果通常是含有參加連接運算的兩個表(或多個表)的指定列的表。例如在XSCJ數據庫中需要查找選修了離散數學課程的學生的姓名和成績,就需要將XS、KC和XS_KC三個表進行連接,才能查找到結果。

在T-SQL中,連接查詢有兩大類表示形式,一是符合SQL標准連接謂詞表示形式,一是T-SQL擴展的使用關鍵字JOIN的表示形式。

1. 連接謂詞

可以在SELECT語句的WHERE子句中使用比較運算符給出連接條件對表進行連接,將這種表示形式稱為連接謂詞表示形式。

【例4.20】查找XSCJ數據庫每個學生的情況以及選修的課程情況。

SELECT XS.* ,XS_KC.*

FROM XS , XS_KC

WHERE XS.學號 = XS_KC.學號

 



 

4.1.4 連接

【例4.21】自然連接查詢

SELECT XS.* ,XS_KC.課程號, XS_KC.成績

FROM XS , XS_KC

WHERE XS.學號= XS_KC.學號

本例所得的結果表包含以下字段:學號、姓名、專業名、性別、出生時間、總學分、備注、課程號、成績。

若選擇的字段名在各個表中是唯一的,則可以省略字段名前的表名。如本例的 SELECT子句也可寫為:

SELECT XS.* , 課程號, 成績

FROM XS , XS_KC

WHERE XS.學號 = XS_KC.學號

【例4.22】查找選修了206課程且成績在80分以上的學生姓名及成績。

SELECT 姓名 , 成績

FROM XS , XS_KC

WHERE XS.學號 = XS_KC.學號 AND 課程號 = ‘206’ AND 成績 >= 80


 

4.1.4 連接


【例4.23】查找選修了“計算機基礎”課程且成績在80分以上的學生學號、姓名、課程名及成績。

SELECT XS.學號, 姓名, 課程名, 成績

FROM XS , KC ,XS_KC

WHERE XS.學號 = XS_KC.學號 AND KC.課程號 = XS_KC.課程號

AND 課程名 = ‘計算機基礎’ AND 成績 >= 80


 

4.1.4 連接


2. 以JOIN關鍵字指定的連接

對兩個表之間的簡單內部連接(不匹配的行將從結果中刪除),通過在FROM字句中列出多個,並在WHERE子句中加上連接條件即可完成這個功能。而對更復診的外部連接(不匹配的行需要保留),或者多一個一個連接的查詢中用到的表多於兩個,那么在FORM子句中需要明確的連接句法。T-SQL擴展了以JOIN關鍵字指定連接的表示方式,使表的連接運算能力有了增強。FROM子句的joined_table表示將多個表連接起來。

 

4.1.4 連接

<joined_table>::=

<table_source><join_type> <table_source> ON <search_condition>

|<table_source> CROSS JOIN <table_source>

|<joined_table>

其中table_source為指定要在Transact-SQL語句中使用的表或視圖(帶或不帶別名均可),join_type表示連接類型,ON用於指定連接條件。join_type的格式為:

[ INNER | { LEFT |RIGHT | FULL } [ OUTER ] [ <join_hint> ] JOIN

其中INNER表示內連接,OUTER表示外連接,join_hint是連接提示。

CROSS JOIN表示交叉連接。因此,以JOIN關鍵字指定的連接有三種類型:

(1) 內連接

內連接按照ON所指定的連接條件合並兩個表,返回滿足條件的行。

【例4.24】查找XSCJ數據庫每個學生的情況以及選修的課程情況。

SELECT *

FROM XS INNER JOINXS_KC

ON XS.學號 = XS_KC.學號

 

4.1.4 連接

結果表將包含XS表和XS_KC表的所有字段(不去除重復字段—學號)。若要去除重復的學號字段,可將SELECT子句改為:

SELECT XS.* , 課程號, 成績

內連接是系統默認的,可以省略INNER關鍵字。使用內連接后仍可使用WHERE子句指定條件。

【例4.25】用FROM的JOIN關鍵字表達下列查詢:查找選修了206課程且成績在80分以上的學生姓名及成績。

SELECT 姓名 , 成績

FROM XS JOIN XS_KCON XS.學號 = XS_KC.學號

WHERE 課程號 = '206' AND成績>=80

內連接還可以用於多個表的連接。

【例4.26】用FROM的JOIN關鍵字表達下列查詢:查找選修了“計算機基礎”課程且成績在80分以上的學生學號、姓名、課程名及成績。

SELECT XS.學號 , 姓名 , 課程名 , 成績

FROM XS JOIN XS_KCJOIN KC ON XS_KC.課程號 = KC.課程號

ON XS.學號 = XS_KC.學號

WHERE 課程名 = '計算機基礎' AND 成績>=80

作為一種特例,可以將一個表與它自身進行連接,稱為自連接。若要在一個表中查找具有相同列值的行,則可以使用自連接。使用自連接時需為表指定兩個別名,且對所有列的引用均要用別名限定。

 

4.1.4 連接

【例4.27】查找不同課程成績相同的學生的學號、課程號和成績。

SELECT a.學號,a.課程號,b.課程號,a.成績

FROM XS_KC a JOINXS_KC b

ON a.成績=b.成績 AND a.學號=b.學號 AND a.課程號!=b.課程號


圖4.15查找不同課程成績相同的學生的學號、課程號和成績

(2) 外連接

外連接的結果表不但包含滿足連接條件的行,還包括相應表中的所有行。外連接包括三種:

● 左外連接(LEFT OUTER JOIN):結果表中除了包括滿足連接條件的行外,還包括左表的所有行;

● 右外連接(RIGHT OUTER JOIN):結果表中除了包括滿足連接條件的行外,還包括右表的所有行;

 

4.1.4 連接

● 完全外連接(FULL OUTER JOIN):結果表中除了包括滿足連接條件的行外,還包括兩個表的所有行。

其中的OUTER關鍵字均可省略。

【例4.28】查找所有學生情況,及他們選修的課程號,若學生未選修任何課,也要包括其情況。

SELECT XS.* , 課程號

FROM XS LEFT OUTERJOIN XS_KC ON XS.學號 = XS_KC.學號

本例執行時,若有學生未選任何課程,則結果表中相應行的課程號字段值為NULL。

【例4.29】查找被選修了的課程的選修情況和所有開設的課程名。

SELECT XS_KC.* , 課程名

FROM XS_KC RIGHTJOIN KC ON XS_KC.課程號= KC.課程號

本例執行時,若某課程未被選修,則結果表中相應行的學號、課程號和成績字段值均為NULL。

注意外連接只能對兩個表進行。

(3) 交叉連接

交叉連接實際上是將兩個表進行笛卡爾積運算,結果表是由第一個表的每行與第二個表的每一行拼接后形成的表,因此結果表的行數等於兩個表行數之積。

【例4.30】列出學生所有可能的選課情況。

SELECT 學號,姓名,課程號,課程名

FROM XS CROSS JOINKC

注意: 交叉連接不能有條件,且不能帶WHERE子句。

 

4.1.5 數據匯總

對表數據進行檢索時,經常需要對結果進行匯總或計算,例如在學生成績數據庫中求某門功課的總成績、統計各分數段的人數等。本小節將討論SELECT語句中用於數據統計的子句及函數。

1. 聚合函數

聚合函數用於計算表中的數據,返回單個計算結果。SQL Server 2000所提供的聚合函數列於表4.10中。

 

4.1.5 數據匯總

表4.10 聚合函數表

函數名

說明

AVG

求組中值的平均值。

BINARY_CHECKSUM

返回對表中的行或表達式列表計算的二進制校驗值,可用於檢測表中行的更改。

CHECKSUM

返回在表的行上或在表達式列表上計算的校驗值,用於生成哈希索引。

CHECKSUM_AGG

返回組中值的校驗值。

COUNT

求組中項數,返回int類型整數。

COUNT_BIG

求組中項數,返回bigint類型整數。

GROUPING

產生一個附加的列。

MAX

求最大值。

MIN

求最小值。

SUM

返回表達式中所有值的和。

STDEV

返回給定表達式中所有值的統計標准偏差。

STDEVP

返回給定表達式中所有值的填充統計標准偏差。

VAR

返回給定表達式中所有值的統計方差。

VARP

返回給定表達式中所有值的填充的統計方差。

 

4.1.5 數據匯總

下面對常用的幾個聚合函數加以介紹。

(1)SUM和AVG

SUM和AVG分別用於求表達式中所有值項的總和與平均值,語法格式為:

SUM / AVG ( [ ALL| DISTINCT ] expression )

其中expression是常量、列、函數或表達式,其數據類型只能是:int、smallint、tinyint、bigint、decimal、numeric、float、real、money和smallmoney。ALL表示對所有值進行運算,DISTINCT表示去除重復值,缺省為ALL。SUM / AVG忽略NULL值。

【例4.31】求選修101課程的學生的平均成績。

SELECT AVG(成績) AS '課程101平均成績'

FROM XS_KC

WHERE 課程號 = '101'

執行結果為:

課程101平均成績

78

使用聚合函數作為SELECT的選擇列時,若不為其指定列標題,則系統將對該列輸出標題“(無列名)”。

(2)MAX和MIN

MAX和MIN分別用於求表達式中所有值項的最大值與最小值,語法格式為:

MAX / MIN ( [ ALL| DISTINCT ] expression )

 

4.1.5 數據匯總

其中expression是常量、列、函數或表達式,其數據類型可以是數字、字符和時間日期類型。ALL、DISTINCT的含義及缺省值與SUM/AVG函數相同。MAX/MIN忽略NULL值。

【例4.32】求選修101課程的學生的最高分和最低分。

SELECT MAX(成績) AS '課程101的最高分' ,MIN(成績) AS '課程101的最低分'

FROM XS_KC

WHERE 課程號 = '101'

執行結果為:

課程101的最高分 課程101的最低分

95 62

(3)COUNT

COUNT用於統計組中滿足條件的行數或總行數,格式為:

COUNT ( { [ ALL |DISTINCT ] expression } | * )

其中expression是一個表達式,其數據類型是除uniqueidentifier、text、image或ntext之外的任何類型。ALL、DISTINCT的含義及缺省值與SUM/AVG函數相同。選擇*時將統計總行數。COUNT忽略NULL值。

【例4.33】求學生的總人數。

SELECT COUNT(*) AS'學生總數'

FROM XS

其中:COUNT(*) 不需要任何參數。

 

4.1.5 數據匯總

【例4.34】求選修了課程的學生總人數。

SELECTCOUNT(DISTINCT 學號)

FROM XS_KC

【例4.35】統計離散數學課程成績在85分以上的人數。

SELECT COUNT(成績) AS '離散數學85分以上的人數'

FROM XS_KC

WHERE 成績 >= 85 AND 課程號 IN

( SELECT 課程號

FROM KC

WHERE 課程名 = '離散數學'

)

執行結果為:

離散數學85分以上的人數

2

COUNT_BIG函數的格式、功能與COUNT函數都相同,區別僅在於COUNT_BIG返回bigint類型值。

 

4.1.5 數據匯總

(4)GROUPING

GROUPING函數為輸出的結果表產生一個附加列,該列的值為1或0,格式為:

GROUPING( column_name )

當用 CUBE 或 ROLLUP 運算符添加行時,附加的列輸出值為1,當所添加的行不 是由 CUBE 或 ROLLUP 產生時,附加列值為0。

該函數只能與帶有CUBE或ROLLUP運算符的GROUP BY子句一起使用。

2. GROUP BY子句

GROUP BY子句用於對表或視圖中的數據按字段分組,格式為:

[ GROUP BY [ ALL ]group_by_expression [,…n]

[ WITH { CUBE |ROLLUP } ] ]

說明:

group_by_expression:用於分組的表達式,其中通常包含字段名。指定ALL將顯示所有組。使用GROUPBY子句后,SELECT子句中的列表中只能包含在GROUPBY中指出的列或在聚合函數中指定的列。WITH指定CUBE或ROLLUP操作符,CUBE或 ROLLUP與聚合函數一起使用,在查詢結果中增加附加記錄。

【例4.36】將XSCJ數據庫中各專業名輸出。

SELECT 專業名

FROM XS

GROUP BY 專業名

 


【例4.37】求XSCJ數據庫中各專業的學生數。

SELECT 專業名,COUNT(*) AS '學生數'

FROM XS

GROUP BY 專業名


 

4.1.5 數據匯總

【例4.38】求被選修的各門課程的平均成績和選修該課程的人數。

SELECT 課程號, AVG(成績) AS '平均成績',COUNT(學號) AS '選修人數'

FROM XS_KC

GROUP BY 課程號

 

4.1.5 數據匯總

【例4.39】在XSCJ數據庫上產生一個結果集,包括每個專業的男生、女生人數、總人數及學生總人數。

SELECT 專業名, 性別 , COUNT(*) AS '人數'

FROM XS

GROUP BY 專業名,性別

WITH ROLLUP


4.1.5 數據匯總

【例4.39】在XSCJ數據庫上產生一個結果集,包括每個專業的男生、女生人數、總人數及學生總人數。

SELECT 專業名, 性別 , COUNT(*) AS '人數'

FROM XS

GROUP BY 專業名,性別

WITH ROLLUP


 


 

4.1.5 數據匯總


【例4.40】在XSCJ數據庫上產生一個結果集,包括各專業每門課程的平均成績、每門課程的總平均成績和所有課程的總平均成績。

SELECT 課程名, 專業名, AVG(成績) AS '平均成績'

FROM XS_KC,KC,XS

WHERE XS_KC.課程號 = KC.課程號 AND XS_KC.學號 = XS.學號

GROUP BY 課程名, 專業名

WITH ROLLUP

 

4.1.5 數據匯總

【例4.41】在XSCJ數據庫上產生一個結果集,包括每個專業的男生、女生人數、總人數及男生總數、女生總數、學生總人數。

SELECT 專業名, 性別 , COUNT(*) AS '人數'

FROM XS

GROUP BY 專業名,性別

WITH CUBE

 

4.1.5 數據匯總

執行結果如圖4.22所示。

4.1.5 數據匯總

執行結果如圖4.22所示。

圖4.22 查詢結果

分析:本例中用於分組的列(即GROUP BY子句中的列)為專業名和性別,在XS表中,專業名有兩個不同的值(計算機、通信工程),性別也有兩個不同的值(0、1),再加上NULL值,因此它們可能的組合有5種,因此生成5個匯總行。

 

4.1.5 數據匯總

【例4.42】在XSCJ數據庫上產生一個結果集,包括各專業每門課程的平均成績、每門課程的總平均成績、每個專業的總平均成績和所有課程的總平均成績。

SELECT 課程名,專業名, AVG(成績) AS '平均成績'

FROM XS_KC, KC, XS

WHERE XS_KC.課程號 = KC.課程號 AND XS_KC.學號 = XS.學號

GROUP BY 課程名,專業名


 

4.1.5 數據匯總

【例4.43】統計各專業男生、女生人數及學生總人數,標志匯總行。

SELECT 專業名, 性別 , COUNT(*) AS '人數', GROUPING(專業名) AS'spec', GROUPING(性別) AS 'sx'

FROM XS

GROUP BY 專業名,性別

WITH CUBE

 

4.1.5 數據匯總

3. HAVING子句

使用GROUP BY子句和聚合函數對數據進行分組后,還可以使用HAVING子句對分組數據進行進一步的篩選。HAVING子句有一個與WHERE子句類似的形式。

例如查找XSCJ數據庫中平均成績在85分以上的學生,就是在XS_KC數據庫上按學號分組后篩選出符合平均成績大於等於85的學生。HAVING子句的格式為:

[ HAVING<search_condition> ]

其中search_condition為查詢條件,與WHERE子句的查詢條件類似,並且可以使用聚合函數。

【例4.44】查找XSCJ數據庫中平均成績在85分以上的學生的學號和平均成績。

SELECT 學號 , AVG(成績) AS '平均成績'

FROM XS_KC

GROUP BY 學號

HAVING AVG(成績) > =85


 

4.1.5 數據匯總

【例4.45】查找選修課程超過2門且成績都在80分以上的學生的學號。

SELECT 學號

FROM XS_KC

WHERE 成績 >= 80

GROUP BY 學號

HAVING COUNT(*)> 2

分析:本查詢將XS_KC表中成績大於80的記錄按學號分組,對每組記錄計數,選出記錄數大於2的各組的學號值形成結果表。

【例4.46】查找通信工程專業平均成績在85分以上的學生的學號和平均成績。

SELECT 學號,AVG(成績) AS '平均成績'

FROM XS_KC

WHERE 學號 IN

( SELECT 學號

FROM XS

WHERE 專業名 = '通信工程'

)

GROUP BY 學號

HAVING AVG(成績) > =85

 

4.1.5 數據匯總

分析:先執行WHERE查詢條件中的子查詢,得到通信工程專業所有學生的學號集;然后對XS_KC中的每條記錄,判斷其學號字段值是否在前面所求得的學號集中。若否,則跳過該記錄,繼續處理下一條記錄,若是則加入WHERE的結果集。對XS_KC均篩選完后,按學號進行分組,再在各分組記錄中選出平均成績值大於等於85的記錄形成最后的結果集。

4. COMPUTE子句

COMPUTE子句用於分類匯總。對於交互式的檢索,SQL提供了計算部分和的能力。用戶可以在包含幾個選擇表達式的SELECT語句后,帶有幾個使用合計函數的COMPUTE子句,計算不同層次的合計值。COMPUTE子句格式為:

[ COMPUTE { 聚合函數名(expression)} [ ,…n ] [ BY expression [ ,…n ] ] ]

其中聚合函數名見表4.10,expression是列名。

COMPUTE將產生額外的匯總行。

【例4.47】查找通信工程專業學生的學號、姓名、出生時間,並產生一個學生總人數行。

SELECT 學號,姓名, 出生時間

FROM XS

WHERE 專業名 = '通信工程'

COMPUTE COUNT(學號)

 

4.1.5 數據匯總

執行結果如圖4.26所示。從圖中可以看出,COMPUTE子句產生附加的匯總行,其列標題是系統自定的,對於COUNT函數為cnt,對於AVG函數為avg,對於SUM函數為sum,等等。

COMPUTE BY子句要與ORDER BY子句一起使用,將在下一小節介紹。


 

4.1.6 排序

在應用中經常要對查詢的結果排序輸出,例如學生成績由高到低排序。在SELECT語句中,使用ORDERBY子句對查詢結果進行排序。ORDER BY子句的格式為:

[ ORDER BY {order_by_expression [ ASC | DESC ] } [ ,…n ]

其中order_by_expression是排序表達式,可以是列名、表達式或一個正整數,當 expression是一個正整數時,表示按表中的該位置上列排序。

關鍵字ASC表示升序排列,DESC表示降序排列,系統默認值為ASC。

【例4.48】將通信工程專業的學生按出生時間先后排序。

SELECT *

FROM XS

WHERE 專業名 = '通信工程'

ORDER BY 出生時間

【例4.49】將計算機專業學生的“計算機基礎”課程成績按降序排列。

SELECT 姓名,課程名,成績

FROM XS,KC,XS_KC

WHERE XS.學號 = XS_KC.學號 ANDXS_KC.課程號 = KC.課程號

AND 課程名 = '計算機基礎' AND 專業名= '計算機'

ORDER BY 成績 DESC

 

4.1.6 排序

ORDER BY子句可以與COMPUTE BY子句一起使用,在對結果排序的同時還產生附加的匯總行。

【例4.50】將學生按專業名排序,並匯總各專業人數和平均學分。

SELECT 學號,姓名,出生時間,總學分

FROM XS

ORDER BY 專業名

COMPUTE COUNT(學號),

AVG(總學分) BY 專業名


 

4.2.1 視圖概念

視圖一經定義以后,就可以象表一樣被查詢、修改、刪除和更新。使用視圖有下列優點:

為用戶集中數據,簡化用戶的數據查詢和處理。有時用戶所需要的數據分散在多個表中,定義視圖可將它們集中在一起,從而方便用戶的數據查詢和處理。

屏蔽數據庫的復雜性。用戶不必了解復雜的數據庫中的表結構,並且數據庫表的更改也不影響用戶對數據庫的使用。

簡化用戶權限的管理。只需授予用戶使用視圖的權限,而不必指定用戶只能使用表的特定列,也增加了安全性。

便於數據共享。各用戶不必都定義和存儲自己所需的數據,可共享數據庫的數據,這樣同樣的數據只需存儲一次。

可以重新組織數據以便輸出到其它應用程序中。

使用視圖時,要注意下列事項:

(1) 只有在當前數據庫中才能創建視圖。視圖的命名必須遵循標識符命名規則,不能與表同名,且對每個用戶視圖名必須是唯一的,即對不同用戶,即使是定義相同的視圖,也必須使用不同的名字。

(2) 不能把規則、默認值或觸發器與視圖相關聯。

(3) 不能在視圖上建立任何索引,包括全文索引。

 

4.2.2 創建視圖

1. 在SQL Server Enterprise Manager中創建視圖

以在XSCJ數據庫中創建CS_XS(描述計算機專業學生情況)視圖說明在SQL Server Enterprise Manager中創建視圖的過程。

第1步 打開SQL Server Enterprise Manager,在數據庫XSCJ上單擊鼠標右鍵,在彈出的快捷菜單上選擇“新建”?“視圖..”,


 

4.2.2 創建視圖

第2步 在所出現的窗口的第一個子窗口中單擊鼠標右鍵,將彈出一個“增加表”快捷菜單,如圖4.29所示。

“增加表”快捷菜單

 

4.2.2 創建視圖

第3步 在“增加表”快捷菜單中選擇“添加表…”功能項,將出現如圖4.30所示的“添加表”對話框。

第4步 在圖4.30所示的“添加表”對話框中選擇與視圖相關聯的表、視圖或函數,可以使用Ctrl或Shift鍵進行多選,選擇完畢后,單擊“添加”按鈕。

添加表對話框

 

4.2.2 創建視圖

第5步 在圖4.29所示的窗口的第2個子窗口中選擇創建視圖所需的字段,可以指定列的別名、排序方式和規則(本例指定“專業名”字段的規則為“計算機”)等,如圖4.31所示。注意當視圖中需要一個與原字段名不同的字段名、或視圖的源表中有同名的字段、或視圖中包含了計算列時,需要為視圖中的這樣的列重新指定名稱。

選擇列

 

4.2.2 創建視圖

第6步 上一步完成后,單擊保存按鈕,出現保存視圖對話框,在其中輸入視圖名“CS_XS”,並單擊“確定“按鈕,便完成了視圖的創建。

視圖一經創建成功,其中便包含了所選擇的列數據。例如,若創建了CS_XS視圖,則可查看其結構及內容:在CS_XS視圖上單擊鼠標右鍵,選擇“設計視圖”功能項可以查看並可修改視圖結構,選擇“打開視圖”?“返回所有行”將可查看視圖數據內容。

2. 通過視圖向導創建視圖

第1步 打開SQL Server Enterprise Manager,選擇“工具”菜單中的“向導”功能項,出現如圖4.32所示的選擇向導對話框。

 選擇向導對話框

 

4.2.2 創建視圖

第2步 在選擇向導對話框中展開“數據庫”,選擇“創建視圖向導”功能項,單擊“確定”,將出現歡迎使用向導界面。

第3步 在歡迎使用向導界面中單擊“下一步”,出現選擇數據庫對話框。選擇數據庫名“XSCJ”,單擊“下一步”,出現如圖4.33所示的選擇表對話框。

 選擇表

 

4.2.2 創建視圖

第4步 在選擇表對話框中選擇與視圖相關聯的表,單擊“下一步”,出現如圖4.34所示的選擇列對話框。

第5步 在選擇列對話框中選擇視圖所需要的列,單擊“下一步”,出現如圖4.35所示的視圖限制對話框。

第6步 在視圖限制對話框中輸入對視圖的限制條件,本例為:WHERE 專業名=‘計算機’,單擊“下一步”,出現輸入視圖名對話框。

第7步 在輸入視圖名對話框中輸入視圖名“XS_XS”,單擊“下一步”,出現如圖4.36所示的視圖創建完成對話框,單擊“完成”,則視圖即創建完畢。

選擇列                       輸入視圖限制

 

4.2.2 創建視圖

 視圖創建完成

3. 使用CREATE VIEW語句創建視圖

T-SQL中用於創建視圖的語句是CREATE VIEW語句,例如用該語句創建視圖CS_XS,其表示形式為:

USE XSCJ

GO

CREATE VIEW CS_XS

AS

SELECT *

FROM XS

WHERE 專業名 = '計算機'

GO

 

4.2.2 創建視圖

語法格式:

CREATE VIEW [<database_name>. ][ <owner>. ] view_name [ ( column_name [ ,…n ] )]

[ WITH <view_attribute>[,…n ] ]

ASselect_statement

[ WITH CHECKOPTION ]

說明:

database_name是數據庫名;owner是所有者名;view_name是視圖名。

column_name:列名,它是視圖中包含的列,可以有多個列名,最多可引用1024個列。 若使用與源表或視圖中相同的列名時,則不必給出column_name。

WITHview_attribute: 指出視圖的屬性,view_attribute可以取以下值:

(1) ENCRYPTION:說明在系統表syscomments中存儲CREATEVIEW語句時進行加密。

(2) SCHEMABINDING:說明將視圖與其所依賴的表或視圖結構相關聯。

(3) VIEW_METADATA:指定為引用視圖的查詢請求瀏覽模式的元數據時,向DBLIB、 ODBC或OLEDB API返回有關視圖的元數據信息,而不是返回給基表或其它表。

select_statement:用來創建視圖的SELECT語句,可在SELECT語句中查詢多個表或視圖,以表明新創建的視圖所參照的表或視圖。但對SELECT語句有以下的限制:

 

4.2.2 創建視圖

(1) 定義視圖的用戶必須對所參照的表或視圖有查詢(即可執行SELECT語句)權限;

(2) 不能使用COMPUTE或COMPUTE BY子句;

(3) 不能使用ORDER BY子句;

(4) 不能使用INTO子句;

(5) 不能在臨時表或表變量上創建視圖。

WITH CHECK OPTION:指出在視圖上所進行的修改都要符合select_statement所指定的限制條件,這樣可以確保數據修改后,仍可通過視圖看到修改的數據。例如對於CS_XS視圖,只能修改除“專業名”字段以外的字段值,而不能把專業名字段的值改為“計算機”以外的值,以保證仍可通過CS_XS查詢到修改后的數據。

注意:CREATE VIEW必須是批命令的第一條語句。

【例4.51】創建CS_KC視圖,包括計算機專業各學生的學號、其選修的課程號及成績。 要保證對該視圖的修改都要符合專業名為計算機這個條件。

CREATE VIEW CS_KCWITH ENCRYPTION

AS

SELECT XS.學號,課程號,成績

FROM XS,XS_KC

WHERE XS.學號 = XS_KC.學號 AND 專業名 = '計算機'

WITH CHECK OPTION

 

4.2.2 創建視圖

創建視圖時,源表可以是基本表,也可以是視圖。

【例4.52】創建計算機專業學生的平均成績視圖CS_KC_AVG,包括學號(在視圖中列名為num)和平均成績(在視圖中列名為score_avg)。

CREATE VIEWCS_KC_AVG(num,score_avg)

AS

SELECT 學號,AVG(成績)

FROM CS_KC

GROUP BY 學號

 

4.2.3 查詢視圖

再對XS_KC_AVG視圖進行查詢。

SELECT *

FROM XS_KC_AVG

WHEREscore_avg>=80


視圖定義后,就可以如同查詢基本表那樣對視圖進行查詢。

【例4.53】使用視圖CS_KC查找計算機專業的學生學號和選修的課程號。

SELECT 學號,課程號

FROM CS_KC

【例4.54】查找平均成績在80分以上的學生的學號和平均成績。

本例首先創建學生平均成績視圖XS_KC_AVG,包括學號(在視圖中列名為num)和平均成績(在視圖中列名為score_avg)。

CREATE VIEWXS_KC_AVG ( num,score_avg )

AS

SELECT 學號,AVG(成績)

FROM XS_KC

GROUP BY學號

 

4.2.3 查詢視圖

使用視圖查詢時,若其關聯的基本表中添加了新字段,則必須重新創建視圖才能查詢到新字段。例如,若XS表新增了“籍貫”字段,那么在其上創建的視圖CS_XS若不重建視圖,那么以下查詢:

SELECT * FROMCS_XS

結果將不包含“籍貫”字段。只有重建CS_XS視圖后再對它進行查詢,結果才會包含“籍貫”字段。

如果與視圖相關聯的表或視圖被刪除,則該視圖將不能再使用。

的視圖。

 

4.2.4 更新視圖

通過更新視圖(包括插入、修改和刪除)數據可以修改基本表數據。但並不是所有的視圖都可以更新,只有對滿足可更新條件的視圖,才能進行更新。

1. 可更新視圖

要通過視圖更新基本表數據,必須保證視圖是可更新視圖。一個可更新視圖可以是以下情形之一:

(1) 滿足以下條件的視圖:創建視圖的SELECT語句中沒有聚合函數,且沒有TOP、GROUP BY、UNION子句及DISTINCT關鍵字;創建視圖的SELECT語句中不包含從基本表 列通過計算所得的列;創建視圖的SELECT語句的FROM子句中至少要包含一個基本表。

(2) 可更新的分區視圖。

(3) 通過INSTEAD OF觸發器創建的可更新視圖。

前面創建的視圖CS_XS、CS_KC是可更新視圖,而CS_KC_AVG是不可更新

 

4.2.4 更新視圖

【例4.55】在XSCJ數據庫中使用以下的CREATE TABLE語句創建表XS1和XS2,它們在分區列(即鍵值)上的CHECK約束分別為BETWEEN‘084001’ AND ‘084050’和 BETWEEN '083001' AND '083050',兩個表在鍵值約束上是不重疊的。

CREATE TABLE XS1

(學號 char(6) PRIMARY KEY CHECK (學號 BETWEEN '084001' AND '084050'),

姓名 char(8) NOT NULL,

專業名 char(10) NULL,

性別 bit NOT NULL,

總學分 tinyint NULL

)

CREATE TABLE XS2

(學號 char(6) PRIMARY KEY CHECK (學號 BETWEEN '083001' AND '083050'),

姓名 char(8) NOT NULL,

專業名 char(10) NULL,

性別 bit NOT NULL,

總學分 tinyint NULL

)

 

4.2.4 更新視圖

並向XS1表中加入以下的數據行:

084001王進外語 140

084002郭明外語 138

向XS2表中加入以下的數據行:

083001李玉物理 038

083002劉明物理 138

使用以下的CREATE VIEW語句創建的視圖XS12_VIEW將是可更新的分區視圖:

CREATE VIEWXS12_VIEW

AS

SELECT *

FROM XS1

UNION ALL

SELECT *

FROM XS2

INSTEAD OF觸發器將在后面的章節介紹。

對視圖進行更新操作時,要注意基本表對數據的各種約束和規則要求。

 

4.2.4 更新視圖

2. 插入數據

使用INSERT語句通過視圖向基本表插入數據,有關INSERT語句的語法介紹見第3章。

【例4.56】向CS_XS視圖中插入一條記錄:

( ‘081115’ , ‘劉明儀’, ‘計算機’, 1,‘1989-3-2’, 50 ,NULL,NULL)

INSERT INTO CS_XS

VALUES('081115', '劉明儀','計算機',1,'1989-3-2',50,NULL,NULL)

使用SELECT語句查詢CS_XS依據的基本表XS:

SELECT * FROM XS

將會看到該表已添加了('081115', '劉明儀','計算機',1,'1989-3-2',50,NULL,NULL)行。

當視圖所依賴的基本表有多個時,不能向該視圖插入數據,因為這將會影響多個基表。例如不能向視圖CS_KC插入數據,因為CS_KC依賴兩個基本表:XS和XS_KC。

向可更新的分區視圖中插入數據時,系統會按照插入記錄的鍵值所屬的范圍,將數據插入到其鍵值所屬的基本表中。

【例4.57】向XS12_VIEW視圖中插入一條記錄:

( ‘084010’ , ‘藍圓圓’, ‘外語’, 0, 40 )

INSERT INTOXS12_VIEW

VALUES('084010','藍圓圓','外語',0,40)

 

4.2.4 更新視圖

由於插入記錄的鍵值為084010,因此該記錄實際上是插入到表XS1中,使用以下的SELECT查詢語句:

SELECT * FROM XS1


3. 修改數據

使用UPDATE語句可以通過視圖修改基本表的數據,有關UPDATE語句的語法介紹見第3章。

【例4.58】將CS_XS視圖中所有學生的總學分增加8。

UPDATE CS_XS

SET 總學分 = 總學分+ 8

 

4.2.4 更新視圖

該語句實際上是將CS_XS視圖所依賴的基本表XS中所有專業名為“計算機”的記錄的總學分字段值在原來基礎上增加8。

若一個視圖(非分區視圖)依賴於多個基本表,則一次修改該視圖只能變動一個基本表的數據。

【例4.59】將CS_KC視圖中學號為081101的學生的101課程成績改為90。

UPDATE CS_KC

SET 成績=90

WHERE 學號='081101' AND 課程號='101'

本例中,視圖CS_KC依賴於兩個基本表:XS和XS_KC,對CS_KC視圖的一次修改只能改變學號(源於XS表)或者課程號和成績(源於XS_KC表)。以下的修改是錯誤的:

UPDATE CS_KC

SET 學號=’081120’,課程號=’208’

WHERE 成績=90

對於可更新的分區視圖,則一次修改可以變動其依賴的多個基本表。

 

4.2.4 更新視圖

【例4.60】將XS12_VIEW視圖中的每個學生的總學分增加10。

UPDATE XS12_VIEW

SET 總學分 = 總學分+ 10

用SELECT語句分別查詢視圖XS12_VIEW所依賴的基本表XS1和XS2:

SELECT * FROM XS1


ELECT * FROM XS2

4.2.4 更新視圖

4. 刪除數據

【例4.61】刪除CS_XS中女同學的記錄。

DELETE FROM CS_XS

WHERE 性別 = 0

可以通過可更新的分區視圖刪除其所依賴的基本表數據。

【例4.62】刪除XS12_VIEW中學號為“084001”的學生記錄。

DELETE FROMXS12_VIEW

WHERE 學號 = '084001'

【例4.63】通過SQLServer Enterprise Manager的界面對視圖XS12_VIEW進行如下操作:

① 增加一條記錄(’084003’,’汪小波’,’外語’,1,50)。

② 將學號為083001的學生的總學分改為50。

③ 刪除學號為083002的學生記錄。

 

4.2.4 更新視圖

第1步 展開數據庫和視圖,在XS12_VIEW視圖上單擊鼠標右鍵,在彈出的快捷菜單上依次選擇“打開視圖”?“返回所有行”

 打開視圖

 

 更新視圖

第2步 添加記錄,在所出現的如圖4.42所示的表“XS12_VIEW”窗口中添加新記錄,輸入新記錄各字段的值。

第3步 修改記錄,定位到需修改的學號為“083001”行的總學分字段,刪除原值48,輸入新值50。

第4步 刪除記錄,如圖4.43所示,定位到需刪除的學號為“083002”的行,單擊鼠標右鍵,在彈出的快捷菜單上選擇“刪除”,將出現確認是否刪除的對話框,在其中單擊“確定”。

通過視圖插入數據

 

4.2.4 更新視圖

通過視圖刪除數據

 

4.2.5 修改視圖的定義

修改視圖定義可以通過SQL Server Enterprise Manager的界面進行,也可使用T-SQL的ALTER VIEW語句。

1. 通過SQL Server Enterprise Manager修改視圖

第1步 在SQL Server Enterprise Manager中展開數據庫和視圖,在需修改的視圖上單擊鼠標右鍵,在彈出的快捷菜單上選擇“設計視圖”,將出現如圖4.44所示的窗口。

第2步 在窗口中對視圖定義進行修改,修改完后單擊保存圖標按鈕即可。

注意:對加密存儲的視圖定義不能在SQL Server Enterprise Manager中通過界面修改,例如對視圖CS_KC不能用此法修改。

 修改視圖定義

 

4.2.5 修改視圖的定義

2. 使用ALTER VIEW語句修改視圖

語法格式:

ALTER VIEW [<database_name> . ][ <owner> . ] view_name [ ( column_name [ ,…n ]) ]

[ WITH<view_attribute>[,…n ] ]

ASselect_statement

[ WITH CHECKOPTION ]

其中view_attribute、select_statement等參數與CREATEVIEW語句中含義相同。

【例4.64】將CS_XS視圖修改為只包含計算機專業學生的學號、姓名和總學分。

USE XSCJ

GO

ALTER VIEW CS_XS

AS

SELECT 學號,姓名,總學分

FROM XS

WHERE 專業名 = '計算機'

GO

 

4.2.5 修改視圖的定義

注意:和CREATE VIEW一樣,ALTERVIEW也必須是批命令中的第一條語句。

使用ENCRYPTION屬性定義的視圖(即加密存儲視圖)可以使用ALTER VIEW語句修改。

【例4.65】視圖CS_KC是加密存儲視圖,修改其定義:包括學號、姓名、選修的課程號、課程名和成績。

ALTER VIEW CS_KCWITH ENCRYPTION

AS

SELECT XS.學號,XS.姓名,XS_KC.課程號,KC.課程名,成績

FROM XS,XS_KC,KC

WHERE XS.學號 = XS_KC.學號 ANDXS_KC.課程號 = KC.課程號

AND 專業名 = '計算機'

WITH CHECK OPTION

 

4.2.6 刪除視圖

刪除視圖同樣也可以通過企業管理器界面和T-SQL語句兩種方式來實現。

在企業管理器中刪除視圖的操作方法是:展開數據庫和視圖,在需刪除的視圖上單擊鼠標右鍵,在彈出的快捷菜單上選擇“刪除”,出現如圖4.45所示的對話框,在其中點擊“全部除去”按鈕即可刪除指定的視圖。

刪除視圖

語法格式:

DROP VIEW { view }[ , …n ]

其中view是視圖名,使用DROPVIEW一次可刪除多個視圖。例如:

DROP VIEW CS_KC

將刪除視圖CS_KC。

 

4.3.1 游標概念

在SQL Server中,有兩類游標可以用於應用程序中:前端(客戶端)游標和后端(服務器端)游標。服務器端游標是由數據庫服務器創建和管理的游標,而客戶端游標是由ODBC 和 DB-Library支持,在客戶端實現的游標。在客戶端游標中,所有的游標操作都在客戶端高速緩存中執行。最初實現 DB-Library 客戶端游標時 SQLServer 尚不支持服務器游標,而ODBC 客戶端游標,是為了用於僅支持游標特性默認設置的 ODBC 驅動程序。 由於 DB-Library 和 SQLServer ODBC 驅動程序完全支持通過服務器游標的游標操作,所以我們應盡量不使用客戶端游標。SQL Sever 2000中對客戶端游標的支持也主要是考慮向后兼容。本節除非特別指明,所說的游標均為服務器游標。

SQL Server對游標的使用要遵循聲明游標?打開游標?讀取數據?關閉游標?刪除游標。

 

4.3.2 聲明游標

T-SQL中聲明游標使用DECLARE CURSOR語句,該語句有兩種格式,分別支持SQL-92標准和T-SQL擴展的游標聲明。

1. SQL-92語法

語句格式:

DECLAREcursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR

FORselect_statement

[ FOR { READ ONLY| UPDATE [ OF column_name [ ,…n ] ] } ]

說明:

cursor_name:游標名,它是與某個查詢結果集相聯系的符號名,要符合SQL Server標識符命名規則。

INSENSITIVE:指定系統將創建供所定義的游標使用的數據的臨時復本,對游標的所有請求都從tempdb中的該臨時表中得到應答;因此,在對該游標進行提取操作時返回的數據中不反映對基表所做的修改,並且該游標不允許修改。如果省略 INSENSITIVE,則任何用戶對基表提交的刪除和更新都反映在后面的提取中。

SCROLL:說明所聲明的游標可以前滾、后滾,可使用所有的提取選項(FIRST、LAST、PRIOR、NEXT、RELATIVE、ABSOLUTE)。如果省略SCROLL,則只能使用NEXT提取選項。

 

4.3.2 聲明游標

select_statement:SELECT語句,由該查詢產生與所聲明的游標相關聯的結果集。該SELECT語句中不能出現COMPUTE、COMPUTE BY、INTO或FOR BROWSE關鍵字。

READ ONLY:說明所聲明的游標為只讀的。UPDATE指定游標中可以更新的列,若有參數OF column_name [ ,…n ],則只能修改給出的這些列,若在UPDATE中未指出列,則可以修改所有列。

以下是一個符合SQL-92標准的游標聲明:

DECLARE XS_CUR1CURSOR

FOR

SELECT 學號,姓名,性別,出生時間,總學分

FROM XS

WHERE 專業名 = '計算機'

FOR READ ONLY

該語句定義的游標與單個表的查詢結果集相關聯,是只讀的,游標只能從頭到尾順序提取數據,相當於下面所講的只進游標。

 

4.3.2 聲明游標

2. T-SQL擴展

語句格式:

DECLAREcursor_name CURSOR

[ LOCAL | GLOBAL ]/*游標作用域*/

[ FORWORD_ONLY |SCROLL ] /*游標移動方向*/

[ STATIC | KEYSET| DYNAMIC | FAST_FORWARD ] /*游標類型*/

[ READ_ONLY |SCROLL_LOCKS | OPTIMISTIC ] /*訪問屬性*/

[ TYPE_WARNING ]/*類型轉換警告信息*/

FOR select_statement/*SELECT查詢語句*/

[ FOR UPDATE [ OFcolumn_name [ ,…n ] ] ] /*可修改的列*/

說明:

cursor_name: 為游標名。

LOCAL與GLOBAL:說明游標的作用域。

 

4.3.2 聲明游標

FORWARD_ONLY和SCROLL:說明游標的移動方向。FORWARD_ONLY表示游標只能從第一行滾動到最后一行,即該游標只能支持FETCH的NEXT提取選項。SCROLL含義與SQL-92標准中相同。

STATIC | KEYSET |DYNAMIC | FAST_FORWARD:用於定義游標的類型,T-SQL擴展游標有四種類型:

(1) 靜態游標

關鍵字STATIC指定游標為靜態游標,它與SQL-92標准的INSENSITIVE關鍵字功能相同。靜態游標的完整結果集在游標打開時建立在tempdb中,一旦打開后,就不再變化。數據庫中所做的任何影響結果集成員的更改(包括增加、修改或刪除數據),都不會反映到游標中,新的數據值不會顯示在靜態游標中。靜態游標只能是只讀的。由於靜態游標的結果集存儲在tempdb的工作表中,所以結果集中的行大小不能超過 SQL Server 表的最大行大小。有時也將這類游標識別為快照游標,它完全不受其他用戶行為的影響。

(2) 動態游標

關鍵字DYNAMIC指定游標為動態游標。與靜態游標不同,動態游標能夠反映對結果集中所做的更改。結果集中的行數據值、順序和成員在每次提取時都會改變,所有用戶做的全部UPDATE、INSERT和DELETE語句均通過游標反映出來,並且如果使用API函數(如SQLSetPos)或Transact-SQL WHERE CURRENT OF 子句通過游標進行更新,則它們 也立即在游標中反映出來,而在游標外部所做的更新直到提交時才可見。動態游標不支持 ABSOLUTE 提取選項。

 

4.3.2 聲明游標

(3) 只進游標

關鍵字FAST_FORWARD定義一個快速只進游標,它是優化的只進游標。只進游標只支持游標從頭到尾順序提取數據。對所有由當前用戶發出或由其它用戶提交、並影響結果集中的行的INSERT、UPDATE和 DELETE語句對數據的修改在從游標中提取時可立即反映出來的。但因只進游標不能向后滾動,所以在行提取后對行所做的更改對游標是不可見的。

(4) 鍵集驅動游標

關鍵字KEYSET定義一個鍵集驅動游標。顧名思義,這種游標是由稱為鍵的列或列的組合控制的。打開鍵集驅動游標時,其中的成員和行順序是固定的。鍵集驅動游標中數據行的鍵值在游標打開時建立在 tempdb 中。可以通過鍵集驅動游標修改基本表中的非關鍵字列的值,但不可插入數據。

游標類型與移動方向之間的關系:

● FAST_FORWARD不能與SCROLL一起使用,且FAST_FORWARD與FORWARD_ONLY只能選用一個。

● 若指定了移動方向為FORWARD_ONLY,而沒有用STATIC、KETSET或DYNAMIC關鍵字指定游標類型,則默認所定義的游標為動態游標。

● 若移動方向FORWARD_ONLY和SCROLL都沒有指定,那么移動方向關鍵字的默認值由以下條件決定:① 若指定了游標類型為STATIC、KEYSET或DYNAMIC,則移動方向默認為SCROLL;②若沒有用STATIC、KETSET或DYNAMIC關鍵字指定游標類型,則移動方向默認值為FORWARD_ONLY。

 

4.3.2 聲明游標

READ_ONLY |SCROLL_LOCKS | OPTIMISTIC:說明游標或基表的訪問屬性。READ_ONLY說明所聲明的游標為只讀的,不能通過該游標更新數據。SCROLL_LOCKS關 鍵字說明通過游標完成的定位更新或定位刪除可以成功。如果聲明中已指定了關鍵字 FAST_FORWARD,則不能指定SCROLL_LOCKS。OPTIMISTIC關鍵字說明如果行自從被 讀入游標以來已得到更新,則通過游標進行的定位更新或定位刪除不成功。如果聲明中已 指定了關鍵字FAST_FORWARD,則不能指定OPTIMISTIC。

TYPE_WARNING:指定如果游標從所請求的類型隱性轉換為另一種類型,則給客戶端發送警告消息。

select_statement:SELECT查詢語句,由該查詢產生與所聲明的游標相關聯的結果集。 該SELECT語句中不能出現COMPUTE、COMPUTE BY、INTO或FOR BROWSE關鍵字。

FOR UPDATE:指出游標中可以更新的列,若有參數OF column_name [ ,…n ],則只能修改給出的這些列,若在UPDATE中未指出列,則可以修改所有列。

以下是一個T-SQL擴展游標聲明:

DECLARE XS_CUR2CURSOR

DYNAMIC

FOR

SELECT 學號,姓名,總學分

FROM XS

WHERE 專業名 = '計算機'

FOR UPDATE OF 總學分

該語句聲明一個名為XS_CUR2的動態游標,可前后滾動,可對總學分列進行修改。

 

4.3.3 打開游標

聲明游標后,要使用游標從中提取數據,就必須先打開游標。在T-SQL中,使用OPEN語句打開游標,其格式為:

OPEN { { [ GLOBAL] cursor_name } | cursor_variable_name }

其中cursor_name是要打開的游標名,cursor_variable_name是游標變量名,該名稱引用一個游標。GLOBAL說明打開的是全局游標,否則打開局部游標。

OPEN語句打開游標,然后通過執行在DECLARE CURSOR(或 SETcursor_variable)語 句中指定的T-SQL語句填充游標(即生成與游標相關聯的結果集)。

例如,語句:

OPEN XS_CUR1

打開游標XS_CUR1。該游標被打開后,就可以提取其中的數據。

如果所打開的是靜態游標(使用 INSENSITIVE 或 STATIC 關鍵字),那么OPEN將創建一個臨時表以保存結果集。如果所打開的是鍵集驅動游標(使用KEYSET關鍵字),那么OPEN將創建一個臨時表以保存鍵集。臨時表都存儲在tempdb中。

打開游標后,可以使用全局變量@@CURSOR_ROWS查看游標中數據行的數目。全局變量@@CURSOR_ROWS中保存着最后打開的游標中的數據行數。當其值為0時,表示沒有游標打開;當其值為-1時,表示游標為動態的;當其值為-m(m為正整數)時,游標采用異步方式填充,m為當前鍵集中已填充的行數;當其值為m(m為正整數)時,游標已被完全填充,m是游標中的數據行數。

 

4.3.3 打開游標

【例4.66】定義游標XS_CUR3,然后打開該游標,輸出其行數。

DECLARE XS_CUR3CURSOR

LOCAL SCROLLSCROLL_LOCKS

FOR

SELECT 學號,姓名,總學分

FROM XS

FOR UPDATE OF 總學分

OPEN XS_CUR3

SELECT '游標XS_CUR3數據行數' =@@CURSOR_ROWS

結果為:

游標XS_CUR3數據行數

19

說明:本例中的語句SELECT '游標XS_CUR3數據行數' = @@CURSOR_ROWS用於為變量賦值。

 

4.3.4 讀取數據

游標打開后,就可以使用FETCH語句從中讀取數據。

語法格式:

FETCH

[ [ NEXT | PRIOR |FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar} ]

FROM ]

{ { [ GLOBAL ]cursor_name } | @cursor_variable_name }

[ INTO@variable_name [ ,…n ] ]

 

4.3.4 讀取數據

說明:

cursor_name:要從中提取數據的游標名,@cursor_variable_name游標變量名,引用要進行提取操作的已打開的游標。

NEXT | PRIOR |FIRST | LAST | ABSOLUTE | RELATIVE:用於說明讀取數據的位置。NEXT說明讀取當前行的下一行,並且使其置為當前行。如果FETCH NEXT是對游標的第 一次提取操作,則讀取的是結果集第一行。NEXT為默認的游標提取選項。PRIOR說明讀取當前行的前一行,並且使其置為當前行。如果FETCH PRIOR是對游標的第一次提取操 作,則無值返回且游標置於第一行之前。FIRST讀取游標中的第一行並將其作為當前行。 LAST讀取游標中的最后一行並將其作為當前行。

ABSOLUTE { n |@nvar }和RALATIVE { n | @nvar }給出讀取數據的位置與游標頭或 當前位置的關系,其中n必須為整型常量,變量@nvar必須為 smallint、tinyint 或 int類型。

ABSOLUTE { n |@nvar }:若n或@nvar為正數,則讀取從游標頭開始的第n行並將讀 取的行變成新的當前行;若n或@nvar為負數,則讀取游標尾之前的第n行並將讀取的行變 成新的當前行;若n或@nvar 為 0,則沒有行返回。

RALATIVE { n |@nvar }:若n或@nvar為正數,則讀取當前行之后的第 n 行並將讀 取的行置新的當前行;若n或@nvar為負數,則讀取當前行之前的第n行並將讀取的行變成 新的當前行;如果n或@nvar為 0,則讀取當前行。如果對游標的第一次提取操作時將 FETCH RELATIVE中的n或@nvar指定為負數或0,則沒有行返回。

 

4.3.4 讀取數據

INTO:說明將讀取的游標數據存放到指定的變量中。

GLOBAL:全局游標。

【例4.67】從游標XS_CUR1中提取數據。設該游標已經打開。

FETCH NEXT FROMXS_CUR1

結果為:

學號 姓名 性別 出生時間 總學分

081101王林 11990-02-10 00:00:0058

分析:由於XS_CUR1是只進游標,所以只能使用NEXT提取數據。

【例4.68】從游標XS_CUR1中提取數據。設該游標已經打開。

FETCH FIRST FROMXS_CUR2

---讀取游標第一行(當前行為第一行),結果為:

學號 姓名 總學分

081101王林 58

FETCH NEXT FROMXS_CUR2

--讀取下一行(當前行為第二行),結果為:

學號 姓名 總學分

081102程明 58

 

4.3.4 讀取數據

FETCH PRIOR FROMXS_CUR2

--讀取上一行(當前行為第一行),結果為:

學號 姓名 總學分

081101王林 58

FETCH LAST FROMXS_CUR2

--讀取最后一行(當前行為最后一行),結果為:

學號 姓名 總學分

081115劉明儀 58

FETCH RELATIVE -2FROM XS_CUR2

--讀取當前行的上二行(當前行為倒數第三行),結果為:

學號 姓名 總學分

081108林一帆 60

分析:XS_CUR2是動態游標,可以前滾、后滾,可以使用FETCH語句中的除ABSOLUTE以外的提取選項。

FETCH語句的執行狀態保存在全局變量@@FETCH_STATUS中,其值為0,表示上一個FETCH執行成功;為-1,表示所要讀取的行不在結果集中;為-2,表示被提取的行已不存在(已被刪除)。可以測試@@FETCH_STATUS來控制循環。

 

4.3.4 讀取數據

例如接着上例繼續執行如下語句:

FETCH RELATIVE 3FROM XS_CUR2

SELECT 'FETCH執行情況' = @@FETCH_STATUS

結果為:

FETCH執行情況

-1

 

4.3.5 關閉游標

游標使用完以后,要及時關閉。關閉游標使用CLOSE語句,格式為:

CLOSE { { [ GLOBAL] cursor_name } | @cursor_variable_name }

語句參數的含義與OPEN語句中相同。例如:

CLOSE XS_CUR2

將關閉游標XS_CUR2。

 

4.3.6 刪除游標

游標關閉后,其定義仍在,需要時可用OPEN語句打開它再使用。若確認游標不再需要,就要釋放其定義占用的系統空間,即刪除游標。刪除游標使用DEALLOCATE語句,格式為:

DEALLOCATE { { [GLOBAL ] cursor_name } | @cursor_variable_name }

語句參數的含義與OPEN和CLOSE語句中相同。例如:

DEALLOCATE XS_CUR2

將刪除游標XS_CUR2。

 

習 題

1. 試說明SELECT語句的作用。說明SELECT語句的FROM、WHERE、GROUP及ORDER子句的作用。

2.查詢內容是多個字段的運算結果,是否可以查詢?

3.查詢結果顯示的列名是否可以與字段名不同?

4.查詢內容與多個表有關,表與表之間如何關聯?

5.經常需要查詢的內容是否可以用視圖完成?

6. 寫出T-SQL語句,對產品銷售數 據庫(CPXS)進行如下操作:

(1) 查詢單價在2000—2900元之間的商品名。

(2) 統計所有商品總數。

(3) 查詢2007年12月產品銷售總額。

(4) 查詢客戶名為“XXY”的客戶在2007年12月18日所購買的產品清單。

(5) 在產品銷售數據庫上創建冰箱產品表的視圖BXCP。

(6) 在BXCP視圖上查詢庫存量在100台以下的產品編號和庫存量。

7.什么時候需要使用游標?使用游標的步驟。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM