官术网_书友最值得收藏!

第2篇 SQL Server基礎(chǔ)篇

第3章 管理SQL Server 2005的工具——SQL語(yǔ)言

經(jīng)過前面兩章的學(xué)習(xí),我們已經(jīng)對(duì)SQL Server 2005數(shù)據(jù)庫(kù)管理系統(tǒng)有了一個(gè)大致的概念,從這一章開始我們將對(duì)該數(shù)據(jù)庫(kù)管理系統(tǒng)的具體內(nèi)容展開全面的介紹,讓讀者通過自己的努力去揭開SQL Server 2005的神秘面紗,本章將從SQL語(yǔ)言講起,讓讀者對(duì)SQL語(yǔ)言的基本語(yǔ)法先有一個(gè)大致的了解,為以后的學(xué)習(xí)打下一個(gè)基礎(chǔ)。本章的主要內(nèi)容如下:

? SQL語(yǔ)言簡(jiǎn)介。

? SQL語(yǔ)言中的數(shù)據(jù)類型。

? SQL語(yǔ)言中的變量。

? SQL語(yǔ)言中的運(yùn)算符。

? SQL語(yǔ)言中的表達(dá)式。

3.1 SQL語(yǔ)言簡(jiǎn)介

SQL是Structured Query Language(機(jī)構(gòu)化查詢語(yǔ)言)的簡(jiǎn)寫,是高級(jí)的非過程化編程語(yǔ)言,允許用戶在高層數(shù)據(jù)結(jié)構(gòu)上工作。它不要求用戶指定對(duì)數(shù)據(jù)的存放方法,也不需要用戶了解具體的數(shù)據(jù)存放方式,所以具有完全不同底層結(jié)構(gòu)的、不同數(shù)據(jù)庫(kù)系統(tǒng)可以使用相同的SQL語(yǔ)言作為數(shù)據(jù)輸入與管理的接口。最早是IBM的圣約瑟研究實(shí)驗(yàn)室為其關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)SYSTEM R開發(fā)的一種查詢語(yǔ)言,它的前身是SQUARE語(yǔ)言。SQL語(yǔ)言結(jié)構(gòu)簡(jiǎn)潔,功能強(qiáng)大,簡(jiǎn)單易學(xué),所以自從IBM公司1981年推出以來(lái),SQL語(yǔ)言得到了廣泛的應(yīng)用。如今無(wú)論是Oracle、Sybase、Informix、SQL Server這些大型的數(shù)據(jù)庫(kù)管理系統(tǒng),還是Visual FoxPro、PowerBuilder這些在PC上常用的數(shù)據(jù)庫(kù)開發(fā)系統(tǒng),都支持SQL語(yǔ)言作為查詢語(yǔ)言。

3.1.1 SQL語(yǔ)言的主要特點(diǎn)

SQL是一種面向數(shù)據(jù)庫(kù)的通用數(shù)據(jù)處理語(yǔ)言規(guī)范,它具有非常強(qiáng)大的功能,主要包括以下幾類:

? 提取查詢數(shù)據(jù)。

? 插入、修改、刪除數(shù)據(jù)。

? 生成、修改、刪除數(shù)據(jù)庫(kù)對(duì)象。

? 數(shù)據(jù)庫(kù)安全控制。

? 數(shù)據(jù)庫(kù)完整性及數(shù)據(jù)保護(hù)控制。

SQL語(yǔ)言的這些強(qiáng)大功能充分體現(xiàn)了關(guān)系數(shù)據(jù)語(yǔ)言的特點(diǎn)和優(yōu)點(diǎn)。其主要的特點(diǎn)如下:

1.綜合統(tǒng)一

SQL語(yǔ)言集數(shù)據(jù)定義語(yǔ)言DDL、數(shù)據(jù)操縱語(yǔ)言DML、數(shù)據(jù)控制語(yǔ)言DCL的功能于一體,語(yǔ)言風(fēng)格統(tǒng)一,可以獨(dú)立完成數(shù)據(jù)庫(kù)生命周期中的全部活動(dòng),包括定義關(guān)系模式、錄入數(shù)據(jù)以建立數(shù)據(jù)庫(kù)、查詢、更新、維護(hù)、數(shù)據(jù)庫(kù)重構(gòu)、數(shù)據(jù)庫(kù)安全性控制等一系列操作要求,這就為數(shù)據(jù)庫(kù)應(yīng)用系統(tǒng)開發(fā)提供了良好的環(huán)境。例如,用戶在數(shù)據(jù)庫(kù)投入運(yùn)行后,還可根據(jù)需要隨時(shí)地、逐步地修改模式,并不影響數(shù)據(jù)庫(kù)的運(yùn)行,從而使系統(tǒng)具有良好的可擴(kuò)充性。

2.高度非過程化

非關(guān)系數(shù)據(jù)模型的數(shù)據(jù)操縱語(yǔ)言是面向過程的語(yǔ)言,用它完成某項(xiàng)請(qǐng)求,必須指定存取路徑。而用SQL語(yǔ)言進(jìn)行數(shù)據(jù)操作,用戶只需提出“做什么”,而不必指明“怎么做”,因此用戶無(wú)須了解存取路徑,存取路徑的選擇及SQL語(yǔ)句的操作過程由系統(tǒng)自動(dòng)完成。這不但大大減輕了用戶負(fù)擔(dān),而且有利于提高數(shù)據(jù)獨(dú)立性。

3.面向集合的操作方式

SQL語(yǔ)言采用的是面向集合的操作方式,不僅查找結(jié)果可以是元組的集合,而且一次插入、刪除、更新操作的對(duì)象也可以是元組的集合。

非關(guān)系數(shù)據(jù)模型采用的是面向記錄的操作方式,任何一個(gè)操作其對(duì)象都是一條記錄。例如,查詢所有平均成績(jī)?cè)?0分以上的學(xué)生姓名,用戶必須說(shuō)明完成該請(qǐng)求的具體處理過程,即如何用循環(huán)結(jié)構(gòu)按照某條路徑一條一條地把滿足條件的學(xué)生記錄讀出來(lái)。

4.以同一種語(yǔ)法結(jié)構(gòu)提供兩種使用方式

SQL語(yǔ)言既是自含式語(yǔ)言,又是嵌入式語(yǔ)言。

作為自含式語(yǔ)言,它能夠獨(dú)立地用于聯(lián)機(jī)交互的使用方式,用戶可以在終端鍵盤上直接輸入SQL命令對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。作為嵌入式語(yǔ)言,SQL語(yǔ)句能夠嵌入到高級(jí)語(yǔ)言(如C、PB)程序中,供程序員設(shè)計(jì)程序時(shí)使用。而在兩種不同的使用方式下,SQL語(yǔ)言的語(yǔ)法結(jié)構(gòu)基本上是一致的。這種以統(tǒng)一的語(yǔ)法結(jié)構(gòu)提供兩種不同的使用方式的做法,為用戶提供了極大的靈活性與方便性。

5.語(yǔ)言簡(jiǎn)潔,易學(xué)易用

SQL語(yǔ)言非常簡(jiǎn)潔。雖然SQL語(yǔ)言功能很強(qiáng),但它只有為數(shù)不多的幾條指令,另外SQL語(yǔ)言也非常簡(jiǎn)單,它很接近英語(yǔ)自然語(yǔ)言,因此容易學(xué)習(xí)、掌握。

正是由于SQL語(yǔ)言的這些優(yōu)點(diǎn),它才能被廣泛使用,目前所有的關(guān)系型數(shù)據(jù)管理系統(tǒng)都支持某些形式的SQL語(yǔ)言,它使全部用戶,包括應(yīng)用程序員、數(shù)據(jù)庫(kù)管理員和終端用戶。

3.1.2 如何分類SQL語(yǔ)言

在上一節(jié)中我們提到了SQL語(yǔ)言具有強(qiáng)大的功能,這些功能可以歸納為數(shù)據(jù)查詢、數(shù)據(jù)定義、數(shù)據(jù)操縱及數(shù)據(jù)控制,而我們給SQL語(yǔ)言分類也是從SQL語(yǔ)言所起的作用的角度進(jìn)行的,所以我們可以將SQL語(yǔ)言分為以下幾類。

1.數(shù)據(jù)查詢語(yǔ)言(DQL,Data Query Language)

數(shù)據(jù)查詢語(yǔ)言是在SQL語(yǔ)言中,負(fù)責(zé)進(jìn)行數(shù)據(jù)查詢而不會(huì)對(duì)數(shù)據(jù)本身進(jìn)行修改的語(yǔ)句,這是最基本的SQL語(yǔ)句。

DQL的主要功能是查詢數(shù)據(jù),本身內(nèi)核指令為SELECT,為了進(jìn)行精細(xì)的查詢,加入了各類輔助指令,其主條目包含SELECT、FROM、WHERE、GROUP BY和ORDER BY。

SELECT是查詢的指令,其語(yǔ)法結(jié)構(gòu)為:

        SELECT [要提取的字段,或是用 "*" 代表全部的字段]
        FROM   [要提取的數(shù)據(jù)來(lái)源對(duì)象,包含數(shù)據(jù)表、檢視表與表格型使用者函數(shù)等]
        WHERE  [提取的過濾條件]
        GROUP BY [要進(jìn)行匯總的群組字段]
        HAVING [要作為條件的匯總字段]
        ORDER BY [要排序的字段與方向]

2.數(shù)據(jù)定義語(yǔ)言(DDL,Data Definition Language)

數(shù)據(jù)定義語(yǔ)言是在SQL語(yǔ)言集中,負(fù)責(zé)數(shù)據(jù)結(jié)構(gòu)定義與數(shù)據(jù)庫(kù)對(duì)象定義的語(yǔ)言,由CREATE、ALTER與DROP 3個(gè)語(yǔ)法所組成,最早是由CODASYL (Conference on Data Systems Languages)數(shù)據(jù)模型開始,現(xiàn)在被納入SQL指令中作為其中一個(gè)子集。

? CREATE:是負(fù)責(zé)數(shù)據(jù)庫(kù)對(duì)象的建立,主要包括數(shù)據(jù)庫(kù)、數(shù)據(jù)表、數(shù)據(jù)庫(kù)索引、預(yù)存程序、用戶函數(shù)、觸發(fā)程序或是用戶自定型別等對(duì)象,都可以使用CREATE指令來(lái)建立,而為了各式數(shù)據(jù)庫(kù)對(duì)象的不同,CREATE也有很多的參數(shù)。

? ALTER:是負(fù)責(zé)數(shù)據(jù)庫(kù)對(duì)象修改的指令,相較于CREATE需要定義完整的數(shù)據(jù)對(duì)象參數(shù),ALTER則可依照要修改的幅度來(lái)決定使用的參數(shù),因此在使用上并不會(huì)太困難。

? DROP:是刪除數(shù)據(jù)庫(kù)對(duì)象的指令,并且只需要指定要?jiǎng)h除的數(shù)據(jù)庫(kù)對(duì)象名稱即可,在DDL語(yǔ)法中算是最簡(jiǎn)單的。

3.數(shù)據(jù)操縱語(yǔ)言(DML,Data Manipulation Language)

數(shù)據(jù)操縱語(yǔ)言是在SQL語(yǔ)言中,負(fù)責(zé)對(duì)數(shù)據(jù)庫(kù)對(duì)象運(yùn)行數(shù)據(jù)訪問工作的指令集,以INSERT、UPDATE、DELETE 3種指令為內(nèi)核,分別代表插入、更新與刪除,是開發(fā)以數(shù)據(jù)為中心的應(yīng)用程序必定會(huì)使用到的指令。

? DML主要功能即是訪問數(shù)據(jù),因此其語(yǔ)法都是以讀取與寫入數(shù)據(jù)庫(kù)為主,除了INSERT以外,其他指令都可能要搭配WHERE指令來(lái)過濾數(shù)據(jù)范圍,或是不加WHERE指令來(lái)訪問全部的數(shù)據(jù)。

? INSERT是將數(shù)據(jù)插入到數(shù)據(jù)庫(kù)對(duì)象中的指令,可以插入數(shù)據(jù)的數(shù)據(jù)庫(kù)對(duì)象有數(shù)據(jù)表、可更新查看表兩種。

? UPDATE指令是依給定條件,將符合條件的數(shù)據(jù)表中的數(shù)據(jù)更新為新的數(shù)值。

? DELETE指令為從數(shù)據(jù)庫(kù)對(duì)象中刪除數(shù)據(jù)的指令。

4.數(shù)據(jù)控制語(yǔ)言(DCL,Data Control Language)

數(shù)據(jù)控制語(yǔ)言在SQL語(yǔ)言中,是一種可對(duì)數(shù)據(jù)訪問權(quán)進(jìn)行控制的指令,它可以控制特定用戶賬戶對(duì)數(shù)據(jù)表、查看表、預(yù)存程序、用戶自定義函數(shù)等數(shù)據(jù)庫(kù)對(duì)象的控制權(quán)。由GRANT和REVOKE兩個(gè)指令組成。

這兩個(gè)指令的語(yǔ)法結(jié)構(gòu)大致是:

        GRANT [權(quán)限] ON [要授予權(quán)限的數(shù)據(jù)庫(kù)對(duì)象] TO [使用者賬戶名稱] WITH [授權(quán)選項(xiàng)]
        DENY [權(quán)限] ON [要授予權(quán)限的數(shù)據(jù)庫(kù)對(duì)象] TO [使用者賬戶名稱]

通過上面的介紹我們可以簡(jiǎn)單地了解SQL語(yǔ)言的簡(jiǎn)單分類,雖然在文中可能出現(xiàn)了很多讓初學(xué)者理解起來(lái)有些困難的詞匯,但是隨著我們學(xué)習(xí)的深入,初學(xué)者就能夠更加深刻地理解這些詞匯的含義。

3.1.3 SQL語(yǔ)法簡(jiǎn)介

其實(shí)SQL命令并不是非常多,如果要把SQL用到出神入化,則只需要短短幾個(gè)命令就夠了,因?yàn)镾QL命令是針對(duì)關(guān)系型數(shù)據(jù)庫(kù)所建立的語(yǔ)法敘述,所以SQL在這類數(shù)據(jù)庫(kù)中所發(fā)揮的功能非常的強(qiáng)。下面將對(duì)SQL語(yǔ)法基本命令進(jìn)行簡(jiǎn)單的介紹,在后面的學(xué)習(xí)中我們將詳細(xì)地介紹SQL語(yǔ)法中涉及的內(nèi)容。大致上SQL語(yǔ)法所使用到的類型,基本上可以概括為以下幾類:

? 類屬性(Predicates):在SQL命令中用來(lái)指明要選擇記錄的方式。如ALL、TOP、DISTINCT等。

? 聲明(Declaration):針對(duì)SQL Parameter或Parameter Query的名稱與數(shù)據(jù)類型做聲明,如PARAMETERS的聲明等。

? 條件字句(Clause):在SQL的查詢中,利用一些表達(dá)式定義查詢的條件,以縮小尋找的范圍,如WHERE。

? 運(yùn)算符(Operator)與操作數(shù)(Operation):在SQL的查詢中,與Operation共同組成表達(dá)式(Expression),如BETWEEN…AND運(yùn)算符與INNER JOIN操作數(shù)。

? 函數(shù)(Function):一些常見的函數(shù),如AVG()是求算數(shù)平均數(shù)的函數(shù)。

? SQL語(yǔ)句(Statement):SQL的語(yǔ)句,可以說(shuō)是SQL語(yǔ)法的主體,用來(lái)對(duì)某一個(gè)特定的數(shù)據(jù)庫(kù)發(fā)出指示,并返回相關(guān)的數(shù)據(jù),而SQL的語(yǔ)法結(jié)構(gòu),基本上可以利用下面的式子來(lái)表示:命令+條件子句。例如,SELECT*FROM TAB WHERE TAB.NAME='A'。

3.1.4 如何給標(biāo)識(shí)符起名

計(jì)算機(jī)語(yǔ)言發(fā)展至今,標(biāo)識(shí)符命名逐漸擺脫了早期不區(qū)分大小寫的書寫樣式,以及微軟借Windows平臺(tái)推薦和推廣的匈牙利命名法(Hungarian Notation),形成目前主流的命名規(guī)則,包括以下4種樣式:完全大寫、完全小寫、Pascal大小寫和Camel大小寫。所謂Pascal大小寫即組成標(biāo)識(shí)符的每個(gè)單詞的首字母大寫,其余字母小寫的書寫約定;而Camel大小寫與Pascal大小寫相似,區(qū)別僅在于其標(biāo)識(shí)符的首字母恒為小寫。此外,作為上述規(guī)則的補(bǔ)充約定,對(duì)于雙字母的縮寫單詞,Pascal大小寫要求它們?nèi)看髮懀鳦amel大小寫則要求它們出現(xiàn)在標(biāo)識(shí)符首部時(shí)全部小寫,否則全部大寫。需要強(qiáng)調(diào)的是,這條規(guī)則僅適用于縮寫的雙字母單詞,如“To”、“Is”、“As”這樣原生的雙字母單詞。

為了提供完善的數(shù)據(jù)庫(kù)管理機(jī)制,SQL Server設(shè)計(jì)了嚴(yán)格的命名規(guī)則。在創(chuàng)建或引用數(shù)據(jù)庫(kù)實(shí)體,如表、索引、約束等時(shí),必須遵守SQL Server的命名規(guī)則,否則有可能發(fā)生一些難以預(yù)料和檢查的錯(cuò)誤。

1.標(biāo)識(shí)符分類

SQL Server的所有對(duì)象,包括服務(wù)器、數(shù)據(jù)庫(kù)及數(shù)據(jù)庫(kù)對(duì)象,如表、視圖、列、索引、觸發(fā)器、存儲(chǔ)過程、規(guī)則、默認(rèn)值和約束等都可以有一個(gè)標(biāo)識(shí)符。對(duì)絕大多數(shù)對(duì)象來(lái)說(shuō),標(biāo)識(shí)符是必不可少的,但對(duì)某些對(duì)象(如約束)來(lái)說(shuō),是否規(guī)定標(biāo)識(shí)符是可選擇的。對(duì)象的標(biāo)識(shí)符一般在創(chuàng)建對(duì)象時(shí)定義,作為引用對(duì)象的工具使用。

SQL Server一共定義了兩種類型的標(biāo)識(shí)符:規(guī)則標(biāo)識(shí)符(Regular identifier)和界定標(biāo)識(shí)符(Delimited identifier)。

2.規(guī)則標(biāo)識(shí)符

規(guī)則標(biāo)識(shí)符嚴(yán)格遵守標(biāo)識(shí)符有關(guān)格式的規(guī)定,所以在Transact_SQL中凡是規(guī)則運(yùn)算符都不必使用界定符。對(duì)于不符合標(biāo)識(shí)符格式的標(biāo)識(shí)符要使用界定符[]或‘’。

3.界定標(biāo)識(shí)符

界定標(biāo)識(shí)符是那些使用了如[]和‘’等界定符號(hào)來(lái)進(jìn)行位置限定的標(biāo)識(shí)符,使用界定標(biāo)識(shí)符,既可以遵守標(biāo)識(shí)符命名規(guī)則,也可以不遵守標(biāo)識(shí)符命名規(guī)則。

4.標(biāo)識(shí)符格式

? 標(biāo)識(shí)符的首字母必須是以下兩種情況之一:

第一種情況是,所有在統(tǒng)一碼(Unicode)2.0標(biāo)準(zhǔn)規(guī)定的字符,包括26個(gè)英文字母a~z和A~Z,以及其他一些語(yǔ)言字符,如漢字。例如,可以給一個(gè)表格命名為“學(xué)生基本情況”。

第二種情況是, “ ”、“@”或“#”。

? 標(biāo)識(shí)符首字母后的字符可以是下面3種情況:

第一種情況是,所有在統(tǒng)一碼(Unicode)2.0標(biāo)準(zhǔn)規(guī)定的字符,包括26個(gè)英文字母a~z和A~Z,以及其他一些語(yǔ)言字符,如漢字。

第二種情況是, “ ”、“@”、“$”或“#”。

第三種情況是,0,1,2,3,4,5,6,7,8,9。

?標(biāo)識(shí)符不允許是T-SQL的保留字:由于T-SQL不區(qū)分大小寫,所以無(wú)論是保留字的大寫還是小寫都不允許使用。T-SQL的保留字如表3.1所示。

表3.1 T-SQL保留字

(續(xù)表)

? 標(biāo)識(shí)符內(nèi)部不允許有空格或特殊字符:最后還要說(shuō)明的是,以某些特殊符號(hào)開頭的標(biāo)識(shí)符在SQL Server系統(tǒng)中具有特定的含義。如“@”開頭的標(biāo)識(shí)符表示這是一個(gè)局部變量或是一個(gè)函數(shù)的參數(shù);以“#”開頭的標(biāo)識(shí)符表示這是一個(gè)臨時(shí)表或存儲(chǔ)過程;一個(gè)以“##”開頭的標(biāo)識(shí)符表示這是一個(gè)全局的臨時(shí)數(shù)據(jù)庫(kù)對(duì)象。T-SQL的全局變量以標(biāo)識(shí)符“@@”開頭。為避免同這些全局變量混淆,建議不要使用“@@”作為標(biāo)識(shí)符的開始。

無(wú)論是界定標(biāo)識(shí)符還是規(guī)則標(biāo)識(shí)符都最多只能容納128個(gè)字符,對(duì)于本地的臨時(shí)表最多可以有116個(gè)字符。

5.對(duì)象命名規(guī)則

SQL Server數(shù)據(jù)庫(kù)管理系統(tǒng)中的數(shù)據(jù)庫(kù)對(duì)象名由1~128個(gè)字符組成,不區(qū)分大小寫。在一個(gè)數(shù)據(jù)庫(kù)中創(chuàng)建了一個(gè)數(shù)據(jù)庫(kù)對(duì)象后,數(shù)據(jù)庫(kù)對(duì)象的全名應(yīng)該由服務(wù)器名、數(shù)據(jù)庫(kù)名、擁有者名和對(duì)象名這4個(gè)部分組成,格式如下:

        [[[server.][database].][owner_name].]object_name

命名必須都要符合標(biāo)識(shí)符的規(guī)定。在實(shí)際引用對(duì)象時(shí),可以省略其中某部分的名稱,只留下空白的位置。

6.實(shí)例的命名習(xí)慣

在SQL Server數(shù)據(jù)庫(kù)管理系統(tǒng)中默認(rèn)實(shí)例的名字采用計(jì)算機(jī)名,實(shí)例的名字一般由計(jì)算機(jī)名和實(shí)例名兩部分組成。

總之,正確掌握數(shù)據(jù)庫(kù)的命名和引用方式是用好SQL Server數(shù)據(jù)庫(kù)管理系統(tǒng)的前提,也有助于用戶理解SQL Server數(shù)據(jù)庫(kù)管理系統(tǒng)中的其他內(nèi)容。

3.2 數(shù)據(jù)類型大家族

任何一種高級(jí)語(yǔ)言都有數(shù)據(jù)類型的概念,SQL語(yǔ)言也不例外,在數(shù)據(jù)結(jié)構(gòu)中數(shù)據(jù)類型的定義為一個(gè)值的集合及定義在這個(gè)值集上的一組操作。下面我們將對(duì)SQL語(yǔ)言的數(shù)據(jù)類型進(jìn)行詳細(xì)的介紹,讀者在學(xué)習(xí)的時(shí)候可以和學(xué)過的其他高級(jí)語(yǔ)言中的數(shù)據(jù)類型進(jìn)行比較學(xué)習(xí)。

3.2.1 SQL Server數(shù)據(jù)類型概述

在本節(jié)中我們可能會(huì)遇到一些以前沒有接觸到的概念,如表的創(chuàng)建,對(duì)于這些我們現(xiàn)在不用太關(guān)心,我們只要能夠理解什么時(shí)候需要用到數(shù)據(jù)類型,以及怎樣使用數(shù)據(jù)類型就可以了,至于具體的操作流程會(huì)在后面的章節(jié)中進(jìn)行具體的介紹。

在計(jì)算機(jī)中數(shù)據(jù)有兩種特征,即類型和長(zhǎng)度。所謂數(shù)據(jù)類型就是以數(shù)據(jù)的表現(xiàn)方式和存儲(chǔ)方式來(lái)劃分的數(shù)據(jù)種類。在SQL Server中每個(gè)變量、參數(shù)、表達(dá)式都有數(shù)據(jù)類型。

我們?cè)趯?duì)數(shù)據(jù)庫(kù)進(jìn)行一些定義操作時(shí)需要指定數(shù)據(jù)類型,如定義表列就是一個(gè)典型的操作。Transact-SQL可以定義幾種數(shù)據(jù)類型,包括字符型、數(shù)字型和比特型的數(shù)據(jù)類型,在SQL Server的操作中需要用到數(shù)據(jù)類型的地方還有很多,例如,我們?cè)诙x存儲(chǔ)過程和表的時(shí)候都會(huì)用到。

使用文本和圖像數(shù)據(jù)類型定義2K字節(jié)以上的列并可以存儲(chǔ)多余2000000字節(jié)的數(shù)據(jù)。

我們?cè)趧?chuàng)建表時(shí)使用的度量單位稱為一個(gè)區(qū)域(extent)。當(dāng)創(chuàng)建一個(gè)新表時(shí),為表最初分配的空間設(shè)置為一個(gè)區(qū)域,它包括8個(gè)數(shù)據(jù)頁(yè),每個(gè)數(shù)據(jù)頁(yè)的尺寸為2K字節(jié),當(dāng)表填滿類分配的區(qū)域后,會(huì)為表自動(dòng)分配另外的存儲(chǔ)空間。

使用系統(tǒng)存儲(chǔ)過程或使用SQL企業(yè)管理器可以得到關(guān)于分配給某個(gè)表的存儲(chǔ)空間報(bào)告。

數(shù)據(jù)類型是在定義表列時(shí)需要考慮的第一個(gè)特性,表列的數(shù)據(jù)類型控制著可以存儲(chǔ)在表列中的信息類型。一旦定義了表列的數(shù)據(jù)類型,它就作為表列的一個(gè)永久性特征存儲(chǔ)起來(lái)而不能改變了。

還可以使用數(shù)據(jù)類型定義其他的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),如參數(shù)和本地變量,參數(shù)和本地變量結(jié)構(gòu)的數(shù)據(jù)存儲(chǔ)在RAM中而不是在磁盤上,可以用于定義參數(shù)和本地變量的數(shù)據(jù)類型是數(shù)據(jù)類型的一個(gè)子集。

SQL Server還能夠自動(dòng)限制每個(gè)數(shù)據(jù)類型的值的范圍。例如,我們?cè)谝粋€(gè)表列中定義了一個(gè)列的數(shù)據(jù)類型為int類型,但是我們?cè)诓迦霐?shù)據(jù)時(shí)插入的數(shù)據(jù)在smallint和tinyint范圍之內(nèi),SQL Server會(huì)自動(dòng)將我們的類型轉(zhuǎn)化為smallint或者是tinyint,這樣使用tinyint或smallint數(shù)據(jù)類型存儲(chǔ)數(shù)據(jù)只需要int數(shù)據(jù)類型1/4或1/2的存儲(chǔ)空間,這對(duì)于使用作為標(biāo)志、狀態(tài)指示等類型的數(shù)據(jù)非常有用。

SQL Server數(shù)據(jù)庫(kù)管理系統(tǒng)將數(shù)據(jù)類型大致分為了兩類,一類是系統(tǒng)默認(rèn)的數(shù)據(jù)類型,另一類是用戶自定義數(shù)據(jù)類型。下面將對(duì)這兩類數(shù)據(jù)類型進(jìn)行詳細(xì)的闡述。

3.2.2 系統(tǒng)數(shù)據(jù)類型

SQL Server中的數(shù)據(jù)類型大致分為以下7種類型:整數(shù)數(shù)據(jù)類型、浮點(diǎn)數(shù)據(jù)類型、二進(jìn)制數(shù)據(jù)類型、邏輯數(shù)據(jù)類型、字符數(shù)據(jù)類型、文本和圖像數(shù)據(jù)類型、日期和時(shí)間數(shù)據(jù)類型。下面我們對(duì)這幾種數(shù)據(jù)類型進(jìn)行逐一介紹,以便讀者對(duì)SQL Server數(shù)據(jù)類型有一個(gè)充分的認(rèn)識(shí)。

1.整數(shù)數(shù)據(jù)類型

整數(shù)數(shù)據(jù)類型可以存儲(chǔ)整個(gè)數(shù)字,你可以在整數(shù)上直接操作算術(shù)運(yùn)算符,而不是使用函數(shù)轉(zhuǎn)換,存儲(chǔ)在整數(shù)數(shù)據(jù)類型中的數(shù)據(jù)占據(jù)的存儲(chǔ)空間一樣,而不管其具體的數(shù)字位數(shù)是多少。

數(shù)據(jù)類型的名字,如integer,是大小寫敏感的。整數(shù)數(shù)據(jù)類型主要分為以下幾類:

? int數(shù)據(jù)類型:數(shù)據(jù)類型int或integer int(或integer)可以存儲(chǔ)在-(2E31)~2E31范圍內(nèi)的任意整數(shù)。以int數(shù)據(jù)類型存儲(chǔ)的數(shù)據(jù)每一個(gè)占據(jù)4個(gè)字節(jié)的空間,使用31位存儲(chǔ)數(shù)字的絕對(duì)值,使用一位存儲(chǔ)正負(fù)號(hào)。

? smallint數(shù)據(jù)類型:存儲(chǔ)-32768~32767之間的整數(shù)。存儲(chǔ)在smallint數(shù)據(jù)類型中的值占據(jù)2個(gè)字節(jié)其中15位存儲(chǔ)絕對(duì)值,使用一位存儲(chǔ)正負(fù)號(hào)。

? tinyint數(shù)據(jù)類型:只能存儲(chǔ)0~255之間的整數(shù),每個(gè)數(shù)據(jù)占據(jù)1個(gè)字節(jié)。

2.浮點(diǎn)數(shù)據(jù)類型

浮點(diǎn)數(shù)據(jù)類型是另一組數(shù)據(jù)類型,他不像整數(shù)型的數(shù)據(jù)類型,浮點(diǎn)數(shù)據(jù)類型可以存儲(chǔ)小數(shù)。

不幸的是,浮點(diǎn)數(shù)據(jù)類型要受到舍入誤差的限制,舍入誤差的浮點(diǎn)數(shù)據(jù)類型的精確度受指定的數(shù)據(jù)位數(shù)的影響。例如,如果指定數(shù)據(jù)類型位數(shù)是15位,則位數(shù)大于15的數(shù)據(jù)可以存儲(chǔ),但是大于15的數(shù)位就不能精確地表達(dá)出來(lái),還有因?yàn)檎`差的存在計(jì)算返回的結(jié)果可能也不準(zhǔn)確,舍入誤差會(huì)影響數(shù)的最低位。在浮點(diǎn)數(shù)據(jù)類型允許的位數(shù)范圍內(nèi),你可以精確存儲(chǔ)數(shù)據(jù)。

像浮點(diǎn)數(shù)據(jù)類型這樣的近似數(shù)值型的數(shù)據(jù)類型,因?yàn)榇鎯?chǔ)在其中的值只能在某個(gè)精度范圍內(nèi)準(zhǔn)確,要避免比較存儲(chǔ)在近似數(shù)值型的數(shù)據(jù)類型中的數(shù)據(jù),因?yàn)樵械拇笥诰确秶粩?shù)的數(shù)據(jù)會(huì)經(jīng)過舍入后進(jìn)行處理。

浮點(diǎn)數(shù)據(jù)類型大致可以分為以下幾類:

? real數(shù)據(jù)類型:是浮點(diǎn)數(shù)據(jù)類型的一種,它存儲(chǔ)數(shù)據(jù)在4個(gè)字節(jié)中,在這個(gè)數(shù)據(jù)類型中可以存儲(chǔ)正數(shù)和負(fù)數(shù),可以達(dá)到7個(gè)數(shù)字的精度,這個(gè)數(shù)據(jù)類型的值的范圍在3.4E-38~3.4E+38之間。

? float[(n)]數(shù)據(jù)類型:如果忽略參數(shù)n,需要8個(gè)字節(jié)的存儲(chǔ)空間,可以在其中存儲(chǔ)多達(dá)15個(gè)數(shù)字的正負(fù)數(shù),其值的參數(shù)在1.7E-308~1.7E+308之間。

? 如果指定n值為1到7,則實(shí)際上是定義了一個(gè)real數(shù)據(jù)類型。如果指定n值在8~15之間,則這個(gè)數(shù)據(jù)類型的特性和忽略參數(shù)n是一樣。

? decimal[(p[,s])]和numeric[(p[,s])]數(shù)據(jù)類型:這兩個(gè)數(shù)據(jù)類型不像float或real數(shù)據(jù)類型,它們?cè)试S按指定的值精確分配給數(shù)據(jù)存儲(chǔ)空間,值的位數(shù)和精度由給定的參數(shù)指定,可以使用2~17個(gè)字節(jié)的存儲(chǔ)空間存儲(chǔ)-10~10之間的值。使用p定義小數(shù)點(diǎn)左右兩邊的位數(shù)和,而使用s定義小數(shù)點(diǎn)右邊的小數(shù)位數(shù),s總小于等于p,如果忽略p,則指定為18;s的默認(rèn)值為0。表3.2所示為分配給指定精度的字節(jié)數(shù)。

表3.2 分配給指定精度的字節(jié)數(shù)

3.二進(jìn)制數(shù)據(jù)類型

? binary(n)數(shù)據(jù)類型:可以使用binary數(shù)據(jù)類型存儲(chǔ)由多達(dá)255個(gè)字節(jié)組成的bit形式的數(shù)據(jù)。使用在括號(hào)中的整數(shù)指定數(shù)據(jù)的長(zhǎng)度,從1~255。binary列中的尺寸至少為1個(gè)字節(jié),但你可以將這些字節(jié)存為0。在輸入第一個(gè)binary值時(shí),你必須在他前面帶0x。你可以使用字符0~9和A~F輸入binary數(shù)據(jù),如輸入0xA0代表A0。如果輸入的值大于定義的長(zhǎng)度,則會(huì)將長(zhǎng)出的部分截?cái)唷?/p>

? varbinary(n)數(shù)據(jù)類型:可以使用varbinary數(shù)據(jù)類型存儲(chǔ)由多達(dá)255個(gè)字節(jié)組成的bit形式的數(shù)據(jù)。使用在括號(hào)中的整數(shù)指定數(shù)據(jù)的長(zhǎng)度,從1~255。varbinary列中的尺寸至少為1個(gè)字節(jié),但你可以將這些字節(jié)都存為0。

與binary數(shù)據(jù)類型不同的是,varbinary數(shù)據(jù)類型的存儲(chǔ)限制為實(shí)際值使用相同的存儲(chǔ)空間。就像binary數(shù)據(jù)類型,你必須在第一個(gè)輸入的值前加上0x。你可以使用字符從0~9和A~F輸入varbinary數(shù)據(jù),如果輸入的值大于定義的長(zhǎng)度,則會(huì)將長(zhǎng)出的部分截?cái)唷?/p>

4.邏輯數(shù)據(jù)類型

在SQL Server中邏輯數(shù)據(jù)類型只有一種,那就是bit數(shù)據(jù)類型,我們可以使用bit數(shù)據(jù)類型代表兩個(gè)狀態(tài)的數(shù)據(jù)信息。一個(gè)bit數(shù)據(jù)類型的數(shù)據(jù)存儲(chǔ)在一個(gè)位中,這時(shí)只有兩個(gè)可能的狀態(tài)——0或1。如果輸入的值不是0或1,則當(dāng)做1存儲(chǔ)。不能定義bit數(shù)據(jù)類型允許為null值。

我們還可以使用單個(gè)字節(jié)定義多達(dá)8個(gè)不同的bit表列。分配給一個(gè)或多個(gè)bit的存儲(chǔ)空間是單個(gè)字節(jié)且bit表列不必是連續(xù)的。如果你定義了9個(gè)使用bit數(shù)據(jù)類型的表列,則需要2個(gè)字節(jié)存儲(chǔ)所有bit型數(shù)據(jù)。值的注意的是,我們不能在使用bit數(shù)據(jù)類型的表列上定義一個(gè)索引。

5.貨幣數(shù)據(jù)類型

? money數(shù)據(jù)類型:存儲(chǔ)貨幣值,存儲(chǔ)在money數(shù)據(jù)類型中的數(shù)據(jù)值分為兩部分存儲(chǔ),一個(gè)是整數(shù)部分,一個(gè)是小數(shù)部分,這兩部分都是4個(gè)字節(jié)的整數(shù),存儲(chǔ)在money數(shù)據(jù)類型中的值的范圍在-922337203685477.5808~922337203685477.5807之間。

? smallmoney數(shù)據(jù)類型:存儲(chǔ)的貨幣值的范圍比money數(shù)據(jù)類型小得多,其范圍在-214748.3648~214748.3647之間。這個(gè)數(shù)據(jù)類型的整數(shù)部分和小數(shù)部分存儲(chǔ)在4個(gè)字節(jié)中,所以,如果使用smallmoney而不是money,就可以節(jié)約一半的存儲(chǔ)空間。

當(dāng)向表列中插入smallmoney或money數(shù)據(jù)類型的值時(shí),必須在數(shù)據(jù)前加上美元符號(hào)($)或其他定義貨幣符號(hào),如人民幣符號(hào)(¥)。

6.字符數(shù)據(jù)類型

字符數(shù)據(jù)類型可以存儲(chǔ)包括數(shù)字在內(nèi)的許多符號(hào),字符數(shù)據(jù)類型可以存儲(chǔ)字母、數(shù)字和特殊符號(hào),如”[“,”]”號(hào)等。當(dāng)向表列等存儲(chǔ)結(jié)構(gòu)輸入數(shù)據(jù)時(shí),可以使用單引號(hào)或雙引號(hào)輸入字符數(shù)據(jù)。

字符數(shù)據(jù)類型大致分為以下幾類。

? char數(shù)據(jù)類型:這個(gè)數(shù)據(jù)類型中的每個(gè)字符都使用一個(gè)字節(jié)的存儲(chǔ)空間。括號(hào)中的數(shù)字指定整個(gè)字符串的長(zhǎng)度,如果輸入字符長(zhǎng)度小于15個(gè)字節(jié),則用空格補(bǔ)足。一個(gè)char(n)數(shù)據(jù)類型的數(shù)據(jù)最多可用255個(gè)字符。如果某表列定義char且允許null值,則它作為varchar數(shù)據(jù)類型的表列對(duì)待。

? varchar數(shù)據(jù)類型:這個(gè)數(shù)據(jù)類型存儲(chǔ)一個(gè)可變長(zhǎng)度的字符串,最多可達(dá)255個(gè)字節(jié),不像char數(shù)據(jù)類型,這個(gè)數(shù)據(jù)類型的存儲(chǔ)空間可以根據(jù)實(shí)際需要變化。

例如我們定義一個(gè)表列為varchar(15),則最大可以存儲(chǔ)的字符串長(zhǎng)度為15,而如果不足15個(gè)字節(jié),則不會(huì)分配額外的空間給這個(gè)數(shù)據(jù),所以,可以使用varchar數(shù)據(jù)類型節(jié)約存儲(chǔ)空間。

在使用char或varchar數(shù)據(jù)類型時(shí),都會(huì)制定要輸入數(shù)據(jù)的最大長(zhǎng)度。SQL Server會(huì)自動(dòng)截?cái)嚅L(zhǎng)于最大長(zhǎng)度的字符,但它不會(huì)提醒你進(jìn)行截?cái)嗖僮鳌?/p>

當(dāng)使用char數(shù)據(jù)類型時(shí),會(huì)使用空格填滿少于制定長(zhǎng)度的空間,這些空格會(huì)根據(jù)不同應(yīng)用程序顯示不同的表現(xiàn)形式。如果這些空格為報(bào)表的應(yīng)用帶來(lái)了麻煩,則可以在查詢語(yǔ)句中使用截?cái)嗪瘮?shù)或使用varchar數(shù)據(jù)類型。

7.文本和圖像數(shù)據(jù)類型

可以使用文本和圖像數(shù)據(jù)類型存儲(chǔ)大量字符數(shù)據(jù)和二進(jìn)制數(shù)據(jù)。在文本和圖像數(shù)據(jù)類型中可以存儲(chǔ)2000000個(gè)以上的字節(jié),預(yù)先為文本和圖像數(shù)據(jù)類型分配極大的存儲(chǔ)空間是一種浪費(fèi),所以一般先為它們分配一部分空間,其余的進(jìn)行動(dòng)態(tài)分配。

圖像數(shù)據(jù)類型有時(shí)用于作為行的一部分的內(nèi)嵌OLE對(duì)象。

? text數(shù)據(jù)類型:使用text數(shù)據(jù)類型存儲(chǔ)大量的文本信息。存儲(chǔ)在text數(shù)據(jù)類型中的字符是可以直接輸出到設(shè)備或打印設(shè)備的字符。在text數(shù)據(jù)類型中可以存儲(chǔ)1~2147483647個(gè)字節(jié)的數(shù)據(jù)。數(shù)據(jù)存儲(chǔ)在最初分配為2K字節(jié)固定長(zhǎng)度的單元中,而其他2K字節(jié)的單元是動(dòng)態(tài)加入并連接的。2K的數(shù)據(jù)頁(yè)是指邏輯頁(yè),而不是指物理頁(yè)。使用INSERT語(yǔ)句向文本列插入數(shù)據(jù)時(shí),必須使用單引號(hào)引起數(shù)據(jù)。

? image數(shù)據(jù)類型:可以使用image數(shù)據(jù)類型存儲(chǔ)1~2147483467個(gè)字節(jié)的比特類型的數(shù)據(jù)。例如,可以在一行的單列中存儲(chǔ)圖片、照片、畫片等。

? 文本和圖像列的限制:使用存儲(chǔ)在文本或圖像列中的數(shù)據(jù)時(shí),可能會(huì)遇到幾個(gè)限制。只可以使用文本和圖像數(shù)據(jù)類型定義表列,而不能用他們定義其他的數(shù)據(jù)結(jié)構(gòu),如本地變量或參數(shù)。

存儲(chǔ)在文本和圖像列中的數(shù)據(jù)量使得在許多SQL語(yǔ)句中使用和操作這些數(shù)據(jù)類型時(shí)都不太方便,這是因?yàn)樗麄兇鎯?chǔ)的數(shù)據(jù)量太大了。不能在ORDER BY、GROUP BY或計(jì)算從句中指定文本或圖像數(shù)據(jù)類型的表列,SQL Server不會(huì)使用包括4000000個(gè)字節(jié)的列來(lái)排序或分組。

再就是,不能在UNION中使用文本或圖像數(shù)據(jù)類型的列,除非是一個(gè)UNION ALL。也不能使用一個(gè)文本或圖像數(shù)據(jù)類型返回?cái)?shù)據(jù)值的子查詢。在WHERE或HAVING從句中,不能使用文本或圖像列,除非使用了比較操作符LIKE。也不能在文本或圖像列上指定DISTICT。

最后,不能在文本或圖像列上創(chuàng)建索引、主鍵或外鍵。

8.日期和時(shí)間數(shù)據(jù)類型

有兩個(gè)數(shù)據(jù)類型存儲(chǔ)日期和時(shí)間的組合信息,你會(huì)發(fā)現(xiàn)將日期和時(shí)間數(shù)據(jù)存儲(chǔ)在這些數(shù)據(jù)類型中比將它們存儲(chǔ)在字符型數(shù)據(jù)類型中要方便,如果將日期和時(shí)間存儲(chǔ)在這兩個(gè)數(shù)據(jù)類型中顯示他們非常方便,因?yàn)镾QL Server可以自動(dòng)按熟悉的形式對(duì)它們進(jìn)行格式化,你還可以使用特殊的日期和時(shí)間函數(shù)操作存儲(chǔ)在這些數(shù)據(jù)類型中的值。

如果使用字符數(shù)據(jù)類型存儲(chǔ)日期和時(shí)間,則SQL Server就不會(huì)自動(dòng)對(duì)它們進(jìn)行格式化。

日期和時(shí)間數(shù)據(jù)類型主要包括:

1)datetime數(shù)據(jù)類型

可以使用這個(gè)數(shù)據(jù)類型定義表列的存儲(chǔ)結(jié)構(gòu)。在這個(gè)數(shù)據(jù)類型中可以存儲(chǔ)從1/11753AD~12/31/ 9999AD的日期和時(shí)間。

這個(gè)數(shù)據(jù)類型的總存儲(chǔ)空間為8個(gè)字節(jié)。SQL Server使用前4個(gè)字節(jié)存儲(chǔ)在1900年1月1日前或后的天數(shù)。作為負(fù)數(shù)存儲(chǔ)的值代表這個(gè)日期前的天數(shù),作為正數(shù)存儲(chǔ)的值代表這個(gè)日期后的天數(shù),時(shí)間存儲(chǔ)在后4個(gè)字節(jié)中。

數(shù)據(jù)類型datetime的值存儲(chǔ)精度為每秒的1/300。例如,1~3毫秒的值都表示為0毫秒;4~6毫秒的值表示為3毫秒。

當(dāng)檢索在datetime數(shù)據(jù)類型中的值時(shí),顯式的默認(rèn)值為MMM DD YYYY hh : mm AM/PM,如OCT 23 1985 1:00 PM。當(dāng)這個(gè)數(shù)據(jù)類型的值用于SQL語(yǔ)句時(shí),必須用單引號(hào)將他們括起來(lái),因?yàn)檫@樣SQL Server才會(huì)重新組織各個(gè)部分和準(zhǔn)確存儲(chǔ)值。

當(dāng)輸入datatime值時(shí),可以使用大小寫的形式輸入日期,并在月、日和年間使用一個(gè)或多個(gè)空格,如果輸入日期而沒有時(shí)間,默認(rèn)時(shí)間為12:00 AM,如果你忽略日期和時(shí)間,則默認(rèn)值為January 1,1900 12:00 AM。

可以以幾種方法輸入日期。每種都可以由SQL Server正確組織和存儲(chǔ)。例如,可以以字母格式輸入日期,使用月的縮寫或全名。

如果輸入的日期是忽略的世紀(jì)部分,則小于50年的時(shí)間在21世紀(jì),而大于50年的時(shí)間在20世紀(jì),如果輸入的世紀(jì)值和默認(rèn)值不一樣,則必須輸入指定的世紀(jì)值;當(dāng)輸入一個(gè)沒有天的日期時(shí),默認(rèn)輸入值是月的第一天。

為了能夠讓讀者清楚地了解哪些輸入方式是正確的,下面列舉幾種正確的輸入方式:

? Sep 23 1983。

? SEP 23 1983。

? September 23 1983。

? sep 1983 23。

? 1983 sep 23。

? 19883 23 sep。

? 23 sep 1983。

datetime數(shù)據(jù)類型值的數(shù)字格式允許在不同時(shí)間單位使用斜線(/),劃線(-)和小數(shù)點(diǎn)(.)。當(dāng)使用帶格式的datetime值時(shí),必須指定這個(gè)值的月、日和年各部分。

以數(shù)字格式輸入datetime值時(shí),需要以正確的順序輸入日期的各個(gè)部分,否則可能返回錯(cuò)誤消息告訴你輸入的日期超出了實(shí)際的日期范圍。

在下面的例子中,輸入了幾個(gè)數(shù)字形式的datetime數(shù)據(jù)類型的日期值,設(shè)置的日期格式為月、日和年,設(shè)置的語(yǔ)言為US-English。

? 6/24/71。

? 06/24/71。

? 6-24-1971。

? 6.24.1971。

如果你輸入一個(gè)6位或8位沒有分開的數(shù)字的值,總是按年、月、日的順序進(jìn)行解釋的。月和日總是解釋為兩個(gè)數(shù)字。

如果在向表中輸入一個(gè)新行時(shí),忽略一個(gè)定義為datetime數(shù)據(jù)類型列的輸入,則在這個(gè)新行中,列顯示的值為January 1,1900,12 midnight。

必須按以下的順序輸入時(shí)間部分的值:小時(shí)、分鐘、秒、毫秒。在各個(gè)時(shí)間部分間必須有分隔符號(hào)以識(shí)別時(shí)間部分的各個(gè)數(shù)字。可以使用AM或PM指定上午或下午。

我們還可以使用小數(shù)點(diǎn)或劃線部分,它會(huì)影響毫秒單位的解釋。

2)smalldatetime數(shù)據(jù)類型

Smalldatetime是另外一種存儲(chǔ)日期和時(shí)間的數(shù)據(jù)類型,在這個(gè)數(shù)據(jù)類型中,你可以存儲(chǔ)從1/11900AD~6/6/2709AD的日期和時(shí)間。

這個(gè)數(shù)據(jù)類型的總存儲(chǔ)空間是4個(gè)字節(jié)。SQL Server使用兩個(gè)字節(jié)存儲(chǔ)January 1,1900后的天數(shù)。時(shí)間存儲(chǔ)在另外兩個(gè)字節(jié)中,按照零后的分鐘數(shù)計(jì)算。所以這個(gè)數(shù)據(jù)類型的精度是1分鐘,你可以使用這個(gè)數(shù)據(jù)類型存儲(chǔ)比datetime數(shù)據(jù)類型精度稍低的時(shí)間值。使用smalldatetime數(shù)據(jù)類型所花費(fèi)的存儲(chǔ)空間是datetime數(shù)據(jù)類型的一半。

3.2.3 自定義數(shù)據(jù)類型

我們?cè)趯?duì)表列的數(shù)據(jù)類型進(jìn)行定義時(shí),除了可以使用系統(tǒng)提供的數(shù)據(jù)類型外,還可以根據(jù)需要用自定義的數(shù)據(jù)類型來(lái)進(jìn)行定義。

用戶自定義數(shù)據(jù)類型和系統(tǒng)的標(biāo)準(zhǔn)數(shù)據(jù)類型最大的區(qū)別在于,用戶自定義數(shù)據(jù)類型是以標(biāo)準(zhǔn)系統(tǒng)數(shù)據(jù)類型為基礎(chǔ)的,也就是說(shuō)我們?cè)谧远x自己的數(shù)據(jù)類型時(shí)必須使用標(biāo)準(zhǔn)的系統(tǒng)數(shù)據(jù)為前提,在它們的基礎(chǔ)上加一些限制條件創(chuàng)造出屬于自己的一種數(shù)據(jù)類型。這種用戶自定義數(shù)據(jù)類型只是對(duì)已有數(shù)據(jù)的一種描述方式,并不是一種新的數(shù)據(jù)類型,利用它可以加強(qiáng)對(duì)數(shù)據(jù)庫(kù)字段數(shù)據(jù)類型的一致性維護(hù),它在整個(gè)數(shù)據(jù)庫(kù)中有效,不過很遺憾的是,在用戶自定義數(shù)據(jù)類型建立之后其屬性就不能直接更改,我們需要先刪除之后再進(jìn)行創(chuàng)建,但是如果該自定義數(shù)據(jù)類型已經(jīng)被引用,我們就無(wú)法執(zhí)行刪除操作。下面介紹用戶自定義數(shù)據(jù)類型的創(chuàng)建和刪除。

我們可以使用兩種方式來(lái)對(duì)用戶自定義數(shù)據(jù)類型進(jìn)行創(chuàng)建,一種方法是使用對(duì)象資源管理器進(jìn)行可視化創(chuàng)建,另外一種是通過SQL編程的方式來(lái)進(jìn)行創(chuàng)建,其實(shí)后面的很多操作都是使用這兩種方式完成的。

1.使用對(duì)象資源管理器創(chuàng)建用戶自定義數(shù)據(jù)類型

我們前面已經(jīng)了解了對(duì)象資源管理器,它的主要作用就是給數(shù)據(jù)庫(kù)管理系統(tǒng)提供一個(gè)用戶界面,利用這個(gè)界面對(duì)數(shù)據(jù)庫(kù)進(jìn)行一系列的操作,下面看一下我們使用對(duì)象資源管理器進(jìn)行用戶自定義數(shù)據(jù)類型創(chuàng)建的主要過程。

(1)單擊當(dāng)前數(shù)據(jù)庫(kù)節(jié)點(diǎn)下的“類型”節(jié)點(diǎn)。然后用鼠標(biāo)右鍵單擊該節(jié)點(diǎn)下的“用戶定義數(shù)據(jù)類型”節(jié)點(diǎn),在彈出的快捷菜單中選擇“新建用戶定義數(shù)據(jù)類型”命令,如圖3.1所示。

圖3.1 選擇“用戶新建用戶定義數(shù)據(jù)類型”命令

(2)彈出“新建用戶定義數(shù)據(jù)類型”對(duì)話框,可以在該對(duì)話框中創(chuàng)建自己所需的數(shù)據(jù)類型。例如,通過該對(duì)話框創(chuàng)建數(shù)據(jù)類型TestType,如圖3.2所示。

圖3.2 創(chuàng)建數(shù)據(jù)類型TestType

(3)單擊“確定”按鈕,完成用戶自定義數(shù)據(jù)類型的創(chuàng)建。

2.通過SQL編程方式來(lái)創(chuàng)建用戶自定義數(shù)據(jù)類型

我們可以使用系統(tǒng)存儲(chǔ)過程sp_addtype來(lái)創(chuàng)建自定義數(shù)據(jù)類型,至于什么是存儲(chǔ)過程,讀者在這里不必深究,在后面的章節(jié)中我們會(huì)對(duì)它進(jìn)行詳細(xì)介紹。下面先了解該存儲(chǔ)過程的使用語(yǔ)法。

        sp_addtype type, [ system_data_type ]   [ ,'nulltype' ]

? type:用戶定義數(shù)據(jù)類型的名稱。數(shù)據(jù)類型名稱必須遵循標(biāo)識(shí)符規(guī)則,并且在每個(gè)數(shù)據(jù)庫(kù)中必須是唯一的。

? system_data_type:SQL server提供的數(shù)據(jù)類型,用戶定義的數(shù)據(jù)類型即基于該類型。

? nulltype:指定如何處理null值。設(shè)置null默認(rèn)、not null或nonull。

例如,我們要建立自定義數(shù)據(jù)類型TestType,就可以使用以下語(yǔ)句進(jìn)行操作。

        sp_addtype TestType, 'NUMERIC (4,0)','NONULL'

那么我們?cè)鯓舆\(yùn)行這句代碼讓它在指定數(shù)據(jù)庫(kù)中發(fā)揮作用呢?當(dāng)然這里就要用到SQL Server 2005給我們提供的另外一個(gè)組件工具——查詢編輯器。具體的操作步驟如下:

(1)單擊“新建查詢”按鈕,新建一個(gè)SQL查詢,并且選擇要進(jìn)行操作的數(shù)據(jù)庫(kù),如圖3.3所示。

圖3.3 新建SQL查詢

(2)將操作腳本書寫到新建的查詢界面中,并且單擊“執(zhí)行”按鈕即可完成用戶自定義數(shù)據(jù)類型的添加。如圖3.4所示。

圖3.4 執(zhí)行操作腳本

同樣刪除用戶自定義數(shù)據(jù)類型也有兩種方式,在使用對(duì)象資源管理器進(jìn)行操作時(shí),直接用鼠標(biāo)右鍵單擊已經(jīng)創(chuàng)建的用戶自定義數(shù)據(jù)類型,然后選擇“刪除”命令即可,如圖3.5所示。

圖3.5 利用對(duì)象資源管理器刪除用戶自定義數(shù)據(jù)類型

我們還可以利用SQL腳本對(duì)用戶自定義數(shù)據(jù)類型進(jìn)行刪除操作,基本的SQL語(yǔ)法為:

        sp_droptype type

type即為用戶定義數(shù)據(jù)類型的名稱。

具體執(zhí)行過程和創(chuàng)建自定義數(shù)據(jù)類型類似,我們也是利用查詢分析器來(lái)進(jìn)行操作的。

在執(zhí)行用戶自定義的刪除操作時(shí)還有一個(gè)值得注意的地方,那就是如果用戶自定義數(shù)據(jù)類型在數(shù)據(jù)庫(kù)中的某個(gè)地方使用,就不能執(zhí)行刪除操作。

3.3 變量

變量是一種語(yǔ)言中必不可少的組成部分。在SQL Server依賴的Transact-SQL語(yǔ)言中有兩種形式的變量,一種是用戶自己定義的局部變量,另一種是系統(tǒng)提供的全局變量。在SQL語(yǔ)言中和變量相關(guān)的概念還有批和腳本的概念,下面我們就先介紹批和腳本的概念,然后再介紹變量。

3.3.1 批和腳本

在SQL Server中為了方便變量及函數(shù)的處理提出了批和腳本的概念,批就是一條或者多條SQL語(yǔ)句的集合,而腳本則是按照一系列順序提交的批。通過這兩個(gè)概念我們可以非常清晰地了解SQL語(yǔ)句之間的關(guān)系,便于我們對(duì)SQL語(yǔ)句的管理。

1.批

一個(gè)批是由一條或多條SQL語(yǔ)句組成的語(yǔ)句集,這些語(yǔ)句一起提交并作為一個(gè)組來(lái)執(zhí)行。SQL Server將批中的語(yǔ)句作為一個(gè)整體編譯為一個(gè)執(zhí)行計(jì)劃。因?yàn)榕械恼Z(yǔ)句是一起提交給服務(wù)器的,所以可以節(jié)省系統(tǒng)開銷。

在查詢分析器中,可以用GO命令標(biāo)志一個(gè)批的結(jié)束。GO不是一個(gè)執(zhí)行語(yǔ)句,是通知查詢分析器有多少語(yǔ)句要包含在當(dāng)前的批中。查詢分析器將兩個(gè)GO之間的語(yǔ)句組成一個(gè)字符串交給服務(wù)器去執(zhí)行。

如,以下代碼包含3個(gè)批:

        USE Test
        GO
        CREATE VIEW V_STUDENTS
        AS
        SELECT id,name
        FROM students
        WHERE id='001'
        GO
        SELECT *
        FROM V_STUDENTS
        GO

也就是每個(gè)GO的位置就是一個(gè)批結(jié)束的位置。

因?yàn)镾QL Server為一個(gè)批生成一個(gè)單獨(dú)的執(zhí)行計(jì)劃,所以一個(gè)批本身應(yīng)該是完整的,不能在一個(gè)批中引用其他批定義的變量,也不能將注釋從一個(gè)批開始,在另一個(gè)批中結(jié)束。

如果批中的語(yǔ)句出現(xiàn)編譯錯(cuò)誤,那么將不能生成執(zhí)行計(jì)劃,批中的任何一個(gè)語(yǔ)句都不會(huì)執(zhí)行。

批運(yùn)行時(shí)期的錯(cuò)誤,如果是多數(shù),則終止當(dāng)前語(yǔ)句和批中后繼語(yǔ)句的執(zhí)行,少數(shù)運(yùn)行時(shí)期錯(cuò)誤(如違反約束),只會(huì)影響當(dāng)前造成錯(cuò)誤的語(yǔ)句,而其后的語(yǔ)句仍可以正常執(zhí)行。不論是哪種運(yùn)行時(shí)期錯(cuò)誤,出錯(cuò)之前的語(yǔ)句的執(zhí)行結(jié)果不會(huì)受到影響,除非該批位于一個(gè)事務(wù)中,而且在出現(xiàn)錯(cuò)誤之后明確地將事務(wù)回滾。

批有如下限制:

? CREATE DEFAULT、CREATE PROCEDURE、CREATE RULE、CREATE TRIGGER和CREATE VIEW語(yǔ)句不能與其他語(yǔ)句位于同一個(gè)批中。

? 不能在一個(gè)批中修改一個(gè)表的結(jié)構(gòu),然后在同一個(gè)批中引用剛修改的新列。

? 如果批的第一條語(yǔ)句是EXECUTE,則EXECUTE關(guān)鍵字可以省略。否則,不能省略。

2.腳本

腳本是一系列順序提交的批。腳本可以直接在查詢分析器等工具中輸入并執(zhí)行,也可以保存在文件中,再由查詢分析器等工具執(zhí)行。

一個(gè)腳本可以包含一個(gè)或多個(gè)批,腳本中的GO命令標(biāo)志一個(gè)批的結(jié)束,如果一個(gè)腳本沒有包含任何GO命令,那么它被視為一個(gè)批。

腳本可用于:

? 將服務(wù)器上創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)的步驟永久地記錄在腳本文件中。

? 將語(yǔ)句保存為腳本文件,從一臺(tái)計(jì)算機(jī)傳遞到另一臺(tái)計(jì)算機(jī),這樣可以方便地使兩臺(tái)計(jì)算機(jī)執(zhí)行同樣的操作。

3.3.2 局部變量

局部變量是用戶自定義的變量。使用范圍是定義它的批、存儲(chǔ)過程或觸發(fā)器。局部變量的作用范圍僅限制在程序內(nèi)部。局部變量可以作為計(jì)數(shù)器來(lái)計(jì)算循環(huán)執(zhí)行的次數(shù),或是控制循環(huán)執(zhí)行的次數(shù)。另外,利用局部變量還可以保存數(shù)據(jù)值,以供控制流語(yǔ)句測(cè)試及保存由存儲(chǔ)過程返回的數(shù)據(jù)值等。局部變量前面通常加上“@”標(biāo)識(shí)。用DECLARE對(duì)局部變量進(jìn)行定義,并指明此變量的數(shù)據(jù)類型,用SET或SELECT命令對(duì)其賦值。局部變量的數(shù)據(jù)類型可以是用戶自定義的數(shù)據(jù)類型,也可以是系統(tǒng)數(shù)據(jù)類型,但不能將其定義為TEXT或IMAGE數(shù)據(jù)類型。

1.定義局部變量

定義局部變量的語(yǔ)法如下:

        DECLARE @local_variable data_type [,local_variable data_type]…

其中l(wèi)ocal_variable代表定義的局部變量的名稱。

data_type代表定義的變量類型。

可以看出,DECLARE命令可以定義多個(gè)局部變量,之間用逗號(hào)分隔。

2.用SELECT為局部變量賦值

用SELECT為局部變量賦值的語(yǔ)法如下:

        SELECT { @local_variable = expression } [ ,…n ]

其中參數(shù)@local_variable是給其賦值的聲明變量。expression是任何有效的SQL Server表達(dá)式,包括變量子查詢。

SELECT命令可以將一個(gè)表達(dá)式的值賦給一個(gè)局部變量,也可以將一個(gè)SELECT查詢的結(jié)果賦給一個(gè)局部變量。

SELECT命令通常返回一個(gè)值給局部變量。但當(dāng)返回多個(gè)值時(shí)也不會(huì)出現(xiàn)錯(cuò)誤。例如,當(dāng)expression為一個(gè)表列的名字時(shí),SELECT命令可能會(huì)返回多個(gè)值,則變量的值為最后一個(gè)返回值。如果SELECT命令沒有返回值,則局部變量保持原值不變,如expression為—個(gè)分級(jí)查詢且沒有返回值時(shí),變量被置為NULL。

3.用SET為局部變量賦值

SET命令的功能非常豐富,語(yǔ)法格式也靈活多樣,用SET為局部變量賦值的常用語(yǔ)法格式為:

        SET @local_variable= expression

SET命令和SELECT命令都可以使用表達(dá)式為變量賦值。它們之間的主要異同在于:

? SELECT可以從表、子查詢或者視圖中查詢數(shù)據(jù),并且也可以包含其他SELECT子句;而SET命令則只能從表達(dá)式中獲取數(shù)據(jù)。

? SET和SELECT命令中都可以使用函數(shù)。

? SELECT語(yǔ)句可以查詢多列,而每個(gè)列中的數(shù)據(jù)都可以賦值給一個(gè)變量。如果SELECT語(yǔ)句返回了多個(gè)行,將會(huì)把結(jié)果集中最后一行的數(shù)據(jù)賦值給變量,系統(tǒng)不會(huì)報(bào)告任何錯(cuò)誤。

3.3.3 全局變量

全局變量是由SQL Server系統(tǒng)提供并賦值的變量。用戶不能建立全局變量,也不能修改全局變量的值。與局部變量不同,全局變量在所有存儲(chǔ)過程內(nèi)均有效。通常將全局變量的值賦給局部變量,以便保存和處理。在使用全局變量時(shí)請(qǐng)注意以下規(guī)則:

? 全局變量是在服務(wù)器級(jí)定義的,不是由用戶例程定義的。

? 用戶只能使用系統(tǒng)預(yù)定義的全局變量。

? 引用全局變量時(shí),前面一定加上“@@”標(biāo)識(shí)。

? 用戶不能定義與系統(tǒng)全局變量同名的局部變量,否則將產(chǎn)生不可預(yù)測(cè)的結(jié)果。

? 全局變量以兩個(gè)at(@)開頭,下面我們對(duì)SQL Server中的預(yù)定義全局變量進(jìn)行簡(jiǎn)單的說(shuō)明。

@@servername:返回運(yùn)行SQL Server數(shù)據(jù)庫(kù)本地服務(wù)器的名稱。

@@remserver:返回登錄記錄中記載的遠(yuǎn)程SQL Server服務(wù)器的名稱。

@@connections:返回自上次啟動(dòng)SQL Server以來(lái)連接或試圖連接的次數(shù),用其可讓管理人員方便地了解今天所有試圖連接服務(wù)器的次數(shù)。

@@cursor_rows:返回最后連接上并打開的游標(biāo)中當(dāng)前存在的合格行的數(shù)量。

@@erro:返回最后執(zhí)行的Transact-SQL語(yǔ)句的錯(cuò)誤代碼。

@@rowcount:返回受上一語(yǔ)句影響的行數(shù),任何不返回行的語(yǔ)句將這一變量設(shè)置為0。

@@version:返回SQL Server當(dāng)前安裝的日期、版本和處理器類型。

@@cup_busy:返回自SQL Server最近一次啟動(dòng)以來(lái)CPU的工作時(shí)間,單位為毫秒。

@@datefirst:返回使用SET DATEFIRST命令而被賦值的DATAFIRST參數(shù)值。SET DATEFIRST命令用來(lái)指定每周的第一天是星期幾。

@@DBTS:返回當(dāng)前數(shù)據(jù)庫(kù)的時(shí)間戳值必須保證數(shù)據(jù)庫(kù)中時(shí)間戳的值是唯一的。

@@FETCH_STATUS:返回上一次FETCH語(yǔ)句的狀態(tài)值。

@@IDENTITY:返回最后插入行的標(biāo)識(shí)列的列值。

@@IDLE: 返回自SQL Server最近一次啟動(dòng)以來(lái)CPU處于空閉狀態(tài)的時(shí)間長(zhǎng)短,單位為毫秒。

@@IO_BUSY:返回自SQL Server最后一次啟動(dòng)以來(lái)CPU執(zhí)行輸入、輸出操作所花費(fèi)的時(shí)間(毫秒)。

@@LANGID:返回當(dāng)前所使用的語(yǔ)言ID值。

@@LANGUAGE:返回當(dāng)前使用的語(yǔ)言名稱。

@@LOCK_TIMEOUT:返回當(dāng)前會(huì)話等待鎖的時(shí)間長(zhǎng)短,單位為毫秒。

@@MAX_CONNECTIONS:返回允許連接到SQL Server的最大連接數(shù)目。

@@MAX_PRECISION:返回decimal和numeric數(shù)據(jù)類型的精確度。

@@NESTLEVEL:返回當(dāng)前執(zhí)行的存儲(chǔ)過程的嵌套級(jí)數(shù),初始值為0。

@@OPTIONS:返回當(dāng)前SET選項(xiàng)的信息。

@@PACK_RECEIVED:返回SQL Server通過網(wǎng)絡(luò)讀取的輸入包的數(shù)目。

@@PACK_SENT:返回SQL Server寫給網(wǎng)絡(luò)的輸出包的數(shù)目。

@@PACKET_ERRORS:返回網(wǎng)絡(luò)包的錯(cuò)誤數(shù)目。

@@PROCID:返回當(dāng)前存儲(chǔ)過程的ID值。

@@SERVICENAME:返回SQL Server正運(yùn)行于哪種服務(wù)狀態(tài)之下,如MS SQLServer、MSDTC、SQLServerAgent。

@@SPID:返回當(dāng)前用戶處理的服務(wù)器ID值。

@@TEXTSIZE:返回SET語(yǔ)句的TEXTSIZE選項(xiàng)值,SET語(yǔ)句定義了SELECT語(yǔ)句中text或image。數(shù)據(jù)類型的最大長(zhǎng)度基本單位為字節(jié)。

@@TIMETICKS:返回每一時(shí)鐘的微秒數(shù)。

@@TOTAL_ERRORS:返回磁盤讀寫錯(cuò)誤的數(shù)目。

@@TOTAL_READ:返回磁盤讀操作的數(shù)目。

@@TOTAL_WRITE:返回磁盤寫操作的數(shù)目。

@@TRANCOUNT:返回當(dāng)前連接中處于激活狀態(tài)的事務(wù)數(shù)目。

3.4 SQL的佐料——運(yùn)算符

為了實(shí)現(xiàn)編程的功能,與其他高級(jí)語(yǔ)言一樣,Transact-SQL運(yùn)用運(yùn)算符和函數(shù)實(shí)現(xiàn)各種計(jì)算和處理功能。

Transact-SQL提供了如下幾種類型的運(yùn)算符:算術(shù)運(yùn)算符、比較運(yùn)算符、字符連接運(yùn)算符、邏輯運(yùn)算符、按位運(yùn)算符。

3.4.1 算術(shù)運(yùn)算符

算術(shù)運(yùn)算符對(duì)兩個(gè)表達(dá)式執(zhí)行數(shù)學(xué)運(yùn)算,這兩個(gè)表達(dá)式可以是數(shù)值數(shù)據(jù)類型類別的一個(gè)或多個(gè)數(shù)據(jù)類型,其種類和含義如表3.3所示。

表3.3 SQL語(yǔ)言中的算術(shù)運(yùn)算符

對(duì)于算術(shù)運(yùn)算符這里有兩點(diǎn)需要說(shuō)明:

? 加(+)和減(-)運(yùn)算符也可用于對(duì)datetime和smalldatetime值執(zhí)行算術(shù)運(yùn)算。

? 取模運(yùn)算符的作用是返回一個(gè)除法運(yùn)算的整數(shù)余數(shù),例如,12%5=2,這是因?yàn)?2除以5,余數(shù)為2。

3.4.2 比較運(yùn)算符

在SQL語(yǔ)言中,比較運(yùn)算符能夠進(jìn)行除text、ntext和image數(shù)據(jù)類型之外的其他數(shù)據(jù)類型表達(dá)式的比較操作。比較運(yùn)算表達(dá)式的返回值為布爾數(shù)據(jù)類型,即TRUE、FALSE。

SQL語(yǔ)言中的比較運(yùn)算符主要包括等于、大于、小于、大于或等于、小于或等于、不大于、不小于、不等于,控制實(shí)行優(yōu)先級(jí)——小括號(hào)。

1.=(等于)

比較兩個(gè)表達(dá)式(比較運(yùn)算符)。當(dāng)比較非空表達(dá)式時(shí),如果左邊操作數(shù)的值等于右邊的操作數(shù),則結(jié)果為TRUE,否則結(jié)果為FALSE。如果在兩個(gè)操作數(shù)中有一個(gè)或者兩個(gè)都為NULL,并且SET ANSI_NULLS被設(shè)置為ON,則結(jié)果為NULL。如果SET ANSI_NULLS被設(shè)置為OFF,則當(dāng)一個(gè)操作數(shù)為NULL時(shí)結(jié)果為FALSE,當(dāng)兩個(gè)操作數(shù)都為NULL時(shí)結(jié)果為TRUE。

2.>(大于)

比較兩個(gè)表達(dá)式(比較運(yùn)算符)。當(dāng)比較非空表達(dá)式時(shí),如果左邊操作數(shù)的值大于右邊的操作數(shù),則結(jié)果為TRUE;否則結(jié)果為FALSE。如果在兩個(gè)操作數(shù)中有一個(gè)或者兩個(gè)都為NULL,并且SET ANSI_NULLS被設(shè)置為ON,則結(jié)果為NULL。如果SET ANSI_NULLS被設(shè)置為OFF,則當(dāng)一個(gè)操作數(shù)為NULL時(shí)結(jié)果為FALSE,當(dāng)兩個(gè)操作數(shù)都為NULL時(shí)結(jié)果為TRUE。

3.<(小于)

比較兩個(gè)表達(dá)式(比較運(yùn)算符)。當(dāng)比較非空表達(dá)式時(shí),如果左邊操作數(shù)的值小于右邊的操作數(shù),則結(jié)果為TRUE;否則結(jié)果為FALSE。如果在兩個(gè)操作數(shù)中有一個(gè)或者兩個(gè)都為NULL,并且SET ANSI_NULLS被設(shè)置為ON,則結(jié)果為NULL。如果SET ANSI_NULLS被設(shè)置為OFF,則當(dāng)一個(gè)操作數(shù)為NULL時(shí)結(jié)果為FALSE,當(dāng)兩個(gè)操作數(shù)都為NULL時(shí)結(jié)果為TRUE。

4.>=(大于或等于)

比較兩個(gè)表達(dá)式(比較運(yùn)算符)。當(dāng)比較非空表達(dá)式時(shí),如果左邊操作數(shù)的值大于或等于右邊的操作數(shù),則結(jié)果為TRUE;否則結(jié)果為FALSE。如果在兩個(gè)操作數(shù)中有一個(gè)或者兩個(gè)都為NULL,并且SETANSI_NULLS被設(shè)置為ON,則結(jié)果為NULL。如果SET ANSI_NULLS被設(shè)置為OFF,則當(dāng)一個(gè)操作數(shù)為NULL時(shí)結(jié)果為FALSE,當(dāng)兩個(gè)操作數(shù)都為NULL時(shí)結(jié)果為TRUE。

5.<=(小于或等于)

比較兩個(gè)表達(dá)式(比較運(yùn)算符)。當(dāng)比較非空表達(dá)式時(shí),如果左邊操作數(shù)的值小于或等于右邊的操作數(shù),則結(jié)果為TRUE;否則結(jié)果為FALSE。如果在兩個(gè)操作數(shù)中有一個(gè)或者兩個(gè)都為NULL,并且SET ANSI_NULLS被設(shè)置為ON,則結(jié)果為NULL。如果SET ANSI_NULLS被設(shè)置為OFF,則當(dāng)一個(gè)操作數(shù)為NULL時(shí)結(jié)果為FALSE,當(dāng)兩個(gè)操作數(shù)都為NULL時(shí)結(jié)果為TRUE。

6.!>(不大于)

這個(gè)操作符的作用正好和>(大于)操作符的作用相反。

7.!<(不小于)

這個(gè)操作符的作用正好和<(小于)操作符的作用相反。

8.<>、!=(不等于)

比較兩個(gè)表達(dá)式(比較運(yùn)算符)。當(dāng)比較非空表達(dá)式時(shí),如果左邊操作數(shù)的數(shù)值不等于右邊的操作數(shù),則結(jié)果為TRUE;否則結(jié)果為FALSE。如果在兩個(gè)操作數(shù)中有一個(gè)或者兩個(gè)都為NULL,并且SET ANSI_NULLS被設(shè)置為ON,則結(jié)果為NULL。如果SET ANSI_NULLS被設(shè)置為OFF,則當(dāng)一個(gè)操作數(shù)為NULL時(shí)結(jié)果為FALSE,當(dāng)兩個(gè)操作數(shù)都為NULL時(shí)結(jié)果為TRUE。

9.()(控制實(shí)行優(yōu)先級(jí))

通過這個(gè)運(yùn)算符可以提高表達(dá)式的優(yōu)先級(jí),使這個(gè)表達(dá)式的優(yōu)先級(jí)達(dá)到最高。

3.4.3 邏輯運(yùn)算符

邏輯運(yùn)算符用于測(cè)試條件是否為真,根據(jù)測(cè)試結(jié)果返回布爾值TURE、FALSE或UNKNOWN。

? AND:對(duì)兩個(gè)布爾表達(dá)式的值進(jìn)行邏輯與運(yùn)算,如果其中有一個(gè)為TURE,另一個(gè)為UNKNOWN,或兩個(gè)都為UNKNOWN,則返回值為UNKNOWN。

? OR:對(duì)兩個(gè)布爾表達(dá)式的值進(jìn)行邏輯或運(yùn)算,如果其中有一個(gè)為FALSE,則另一個(gè)為UNKNOWN,或兩個(gè)都為UNKNOWN,則返回UNKNOWN。

? NOT:對(duì)布爾表達(dá)式的值進(jìn)行取反運(yùn)算,當(dāng)其值為UNKNOWN時(shí),返回值為UNKNOWN。

? ALL:如果一組的比較都為TRUE,那么就為TRUE。

? ANY:如果一組的比較中任何一個(gè)為TRUE,那么就為TRUE。

? BETWEEN:如果操作數(shù)在某個(gè)范圍之內(nèi),那么就為TRUE。

? EXISTS:如果子查詢包含一些行,那么就為TRUE。

? IN:如果操作數(shù)等于表達(dá)式表列中的一個(gè),那么就為TRUE。

? LIKE:如果操作數(shù)與一種模式相匹配,那么就為TRUE。

? SOME:如果在一組比較中,有些為TRUE,那么就為TRUE。

3.4.4 連接運(yùn)算符

連接運(yùn)算符是指可以將一個(gè)或多個(gè)文本連接為一個(gè)組合文本的運(yùn)算符號(hào),在SQL語(yǔ)言中連接運(yùn)算符只有一種,即“+”。但是這時(shí)“+”運(yùn)算符的含義不是加法,而是字符串的連接,例如:

        fullName=”givenName”+” ”+”familyName”

這句話我們就是使用了連接運(yùn)算符“+”生成了一個(gè)新的字符串fullName,這個(gè)fullName的值就是“givenName familyName”。

3.4.5 按位運(yùn)算符

按位運(yùn)算符對(duì)整數(shù)或二進(jìn)制數(shù)據(jù)進(jìn)行按位與(&)、或(|)、異或(^)、求反(~)等邏輯運(yùn)算。

1.&(位與)

上下運(yùn)算,按照與的運(yùn)算規(guī)則:0&0=0 ;0&1=0;1&1=1。

例如:

170 & 75結(jié)果為0000 0000 0000 1010。

再把二進(jìn)制數(shù)轉(zhuǎn)換為十進(jìn)制數(shù)10。

2.~(位非)

運(yùn)算法則:0變1,1變0。

~170的二進(jìn)制:1111 1111 0101 0101, 十進(jìn)制為:-171。

~75的二進(jìn)制:1111 1111 1011 0100, 十進(jìn)制為:-76。

3.|(位或)

上下運(yùn)算,按照與的運(yùn)算規(guī)則:0&0=0 ;0&1=1;1&1=1。

例如:

170 & 75結(jié)果為0000 0000 1110 1011。

再把二進(jìn)制數(shù)轉(zhuǎn)換為十進(jìn)制數(shù)235。

4.^(位異或)

上下運(yùn)算,按照與的運(yùn)算規(guī)則:0&0=0 ;0&1=1;1&1=0。

例如:

170 & 75結(jié)果為0000 0000 1110 0001。

再把二進(jìn)制數(shù)轉(zhuǎn)換為十進(jìn)制數(shù)225。

3.4.6 運(yùn)算符的優(yōu)先級(jí)

在實(shí)際的SQL語(yǔ)言編程中,可能在一個(gè)運(yùn)算符中出現(xiàn)多個(gè)運(yùn)算符,那么在計(jì)算時(shí),就按照優(yōu)先級(jí)級(jí)別的高低進(jìn)行計(jì)算,級(jí)別高的運(yùn)算符先計(jì)算,級(jí)別低的運(yùn)算符后計(jì)算,具體運(yùn)算符的優(yōu)先級(jí)如表3.4所示。

表3.4 SQL語(yǔ)言中的優(yōu)先級(jí)級(jí)別

3.5 認(rèn)識(shí)表達(dá)式

表達(dá)式在SQL語(yǔ)言中起著非常重要的作用,可以說(shuō)是整個(gè)SQL語(yǔ)言的核心部分,因?yàn)镾QL語(yǔ)言中的很多重要操作都需要表達(dá)式來(lái)完成,這一節(jié)我們主要目的就是讓讀者對(duì)表達(dá)式有一個(gè)大致的認(rèn)識(shí),關(guān)于表達(dá)式的詳細(xì)內(nèi)容我們會(huì)在以后的章節(jié)中漸漸地深入了解。

3.5.1 什么是表達(dá)式

表達(dá)式是指用運(yùn)算符和圓括號(hào)把常量、變量和函數(shù)等運(yùn)算成分連接起來(lái)的有意義的式子,要特別指出的是單個(gè)的常量、變量、函數(shù)也可以看成是一個(gè)表達(dá)式。

SQL語(yǔ)言的核心就是SQL表達(dá)式,表達(dá)式可用于很多方面,如執(zhí)行計(jì)算、檢索控件的值或向查詢提供條件等。 在后面的章節(jié)中SQL表達(dá)式會(huì)隨處可見,特別是下一章——“走進(jìn)SQL語(yǔ)句的世界”中大部分SQL語(yǔ)句都是由SQL關(guān)鍵字加上SQL表達(dá)式組成的。在這里我們只需先了解SQL語(yǔ)句的簡(jiǎn)單概念和分類,具體的介紹我們?cè)谙乱徽抡归_。

3.5.2 SQL表達(dá)式的分類

對(duì)于SQL表達(dá)式的分類我們可以有兩種分類方法,一種是按照連接表達(dá)式的運(yùn)算符進(jìn)行分類,我們可以將表達(dá)式分為算術(shù)表達(dá)式、比較表達(dá)式、邏輯表達(dá)式、按位表達(dá)式和混合表達(dá)式等;另一種分類方法是按照表達(dá)式的作用來(lái)進(jìn)行分類,我們可以將表達(dá)式分為字段名表達(dá)式、目標(biāo)表達(dá)式和條件表達(dá)式。

對(duì)于第一種分類方法就是按照連接運(yùn)算因子的運(yùn)算符進(jìn)行劃分的,我們很容易就能夠理解,這里就不在進(jìn)行過多的闡述,下面我們按照第二種分類方式簡(jiǎn)單介紹SQL表達(dá)式。

1.字段名表達(dá)式

字段名表達(dá)式可以是單一的字段名或幾個(gè)字段的組合,還可以是由字段、作用于字段的集函數(shù)和常量的任意算術(shù)運(yùn)算(+、-、*,/)組成的運(yùn)算公式。主要包括數(shù)值表達(dá)式、字符表達(dá)式、邏輯表達(dá)式、日期表達(dá)式4種。

2.目標(biāo)表達(dá)式

目標(biāo)表達(dá)式有4種構(gòu)成方式。

? *:表示選擇相應(yīng)基表和視圖的所有字段。

? <表名>.*:表示選擇指定的基表和視圖的所有字段。

? 集函數(shù)():表示在相應(yīng)的表中按集函數(shù)操作和運(yùn)算。

? [<表名>.]<字段名表達(dá)式>[,[<表名>.]<字段名表達(dá)式>]…:表示按字段名表達(dá)式在多個(gè)指定的表中選擇。

3.條件表達(dá)式

條件表達(dá)式常用的有以下6種。

1)比較大小應(yīng)用比較運(yùn)算符構(gòu)成表達(dá)式,主要的比較運(yùn)算符有=、>、<、>=、<=、!=、<>、!>(不大于)、!<(不小于)、NOT+(與比較運(yùn)算符同用,對(duì)條件求非)。

2)指定范圍

        BETWEEN…AND… ,NOT BETWEEN…AND…

查找字段值在(或不在)指定范圍內(nèi)的記錄。BETWEEN后是范圍的下限(即低值),AND后是范圍的上限(即高值)。

3)集合

        IN…,NOT IN…

查找字段值屬于(或不屬于)指定集合內(nèi)的記錄。

4)字符匹配

        LIKE,NOT LIKE'<匹配串>'[ESCAPE'<換碼字符>']

查找指定的字段值與<匹配串>相匹配的記錄。<匹配串>可以是一個(gè)完整的字符串,也可以含有通配符“_”和“%”。其中“_”代表任意單個(gè)字符;“%”代表任意長(zhǎng)度的字符串。

5)空值

        IS NULL,IS NOT NULL

查找字段值為空(或不為空)的記錄。NULL不能用來(lái)表示無(wú)形值、默認(rèn)值、不可用值,以及取最低值或取最高值。SQL規(guī)定,在含有運(yùn)算符+、-、*、/的算術(shù)表達(dá)式中,若有一個(gè)值是空值,則該算術(shù)表達(dá)式的值也是空值;任何一個(gè)含有NULL比較操作結(jié)果的取值都為“假”。

6)多重條件

        AND,OR

AND含義為查找字段值滿足所有與AND相連的查詢條件的記錄;OR含義為查找字段值滿足查詢條件之一的記錄。AND的優(yōu)先級(jí)高于OR,但可通過括號(hào)改變優(yōu)先級(jí)。

3.6 SQL利器——通配符

在搜索數(shù)據(jù)庫(kù)中的數(shù)據(jù)時(shí),可以使用SQL通配符。SQL通配符在搜索數(shù)據(jù)庫(kù)中的數(shù)據(jù)時(shí), SQL通配符可以替代一個(gè)或多個(gè)字符。需要特別注意的是,SQL通配符必須與LIKE運(yùn)算符一起使用。在SQL語(yǔ)言中我們通常使用的通配符有以下幾種:

? %:包含零個(gè)或更多字符的任意字符串。例如:LIKE'%A%'可以查找任意位置的、包含字母A的所有項(xiàng)目。

? _(下畫線):任何單個(gè)字符。例如,LIKE'_B'將查找以b結(jié)尾的所有兩個(gè)字母的項(xiàng)目(如AB、CB等)。

? [ ]:指定范圍 ([a-f]) 或集合 ([abcdef]) 中的任何單個(gè)字符。例如,LIKE '[A-D]B' 將查找以字母B結(jié)尾且以介于A~D之間(包括起始字符)的任何單個(gè)字符開始的項(xiàng)目,如AB、CB等。

? [^]或[!]:不屬于指定范圍 ([a-f])或集合([abcdef])中的任何單個(gè)字符。例如,LIKE 'AB[^1]%'將查找以AB開始且其后的字母不為l的所有項(xiàng)目。

3.7 SQL語(yǔ)言中的注釋

和大多數(shù)的高級(jí)編程語(yǔ)言一樣,SQL語(yǔ)言也有自己的代碼注釋的標(biāo)準(zhǔn)與規(guī)則。注釋的好處是讓你的代碼變得更加清晰和易于理解,對(duì)SQL代碼加上注釋之后不僅能夠讓自己很容易地理解自己以前寫過的代碼,更重要的是在團(tuán)隊(duì)協(xié)作開發(fā)的時(shí)候,確保你所交付給同伴的源碼能夠易于被讀懂,從而不必花費(fèi)大量的精力在代碼的交接上。

SQL中的注釋方法大致分為以下兩種。

1.單行注釋

很容易理解單行注釋的作用,肯定是某一特定行的代碼注釋,指明該行代碼的作用。單行代碼的注釋是以“--”開頭的,如下所示:

        --單行注釋內(nèi)容

單行注釋在編譯的時(shí)候是被忽略的。

2.多行注釋

多行注釋是為了注釋某一代碼塊的作用,SQL語(yǔ)言的多行注釋是以“/*”開頭,以“*/”結(jié)束的,如下所示:

        /*多行注釋內(nèi)容*/

3.8 小結(jié)

通過本章的學(xué)習(xí)我們對(duì)SQL語(yǔ)言有一個(gè)大致的了解了,更加具體和詳細(xì)的內(nèi)容我們會(huì)在后面的章節(jié)中進(jìn)行詳細(xì)的闡述。

本章我們主要學(xué)習(xí)了SQL語(yǔ)言中的數(shù)據(jù)類型、變量、運(yùn)算符、表達(dá)式,以及其他一些輔助的與SQL語(yǔ)言開發(fā)相關(guān)的內(nèi)容。在本章的講述中讀者可以非常清楚地理清講解的思路,本章的講解思路清晰、重點(diǎn)突出,我們把SQL語(yǔ)言中的數(shù)據(jù)類型、運(yùn)算符、表達(dá)式等內(nèi)容進(jìn)行了詳細(xì)的闡述,它們?cè)谖覀兘窈蟮氖褂弥袝?huì)經(jīng)常出現(xiàn),是我們進(jìn)行SQL編程的重點(diǎn)內(nèi)容,也是基礎(chǔ)內(nèi)容,我們只有充分地理解它們,才能在后面的學(xué)習(xí)中游刃有余。下一章我們將進(jìn)行SQL語(yǔ)句的學(xué)習(xí),這是SQL Server中一個(gè)非常中心的內(nèi)容,SQL語(yǔ)句的編寫在很大程度上可以說(shuō)是SQL語(yǔ)言的具體應(yīng)用。

3.9 習(xí)題

1.簡(jiǎn)述SQL語(yǔ)言的特點(diǎn)。

2.試論述SQL Server系統(tǒng)數(shù)據(jù)類型的分類,以及各種數(shù)據(jù)類型的特點(diǎn)。

3.使用對(duì)象資源管理器和SQL語(yǔ)句兩種方式創(chuàng)建一個(gè)自定義數(shù)據(jù)類型,讓這個(gè)自定義數(shù)據(jù)類型滿足:基本數(shù)據(jù)類型為varchar,長(zhǎng)度為80,不能為空值。

4.區(qū)分局部變量和全局變量。

5.試論述SQL Server運(yùn)算符的分類,以及每一種運(yùn)算符的用途和特點(diǎn)。

主站蜘蛛池模板: 萨嘎县| 汶川县| 漳平市| 贵港市| 河间市| 道孚县| 广东省| 双流县| 阿克陶县| 南召县| 和顺县| 阿坝县| 墨江| 建瓯市| 无锡市| 日照市| 荆门市| 岳普湖县| 涞源县| 遂昌县| 孟州市| 荔波县| 彭泽县| 汕头市| 宾阳县| 定西市| 平乡县| 诸暨市| 鹿邑县| 平潭县| 延吉市| 汾阳市| 本溪市| 通化县| 睢宁县| 靖远县| 廊坊市| 大城县| 陆河县| 大石桥市| 九寨沟县|