本書介紹了Microsoft SQL Server 2008數據庫管理系統的基本原理和綜合應用。全書共分十個項目,項目一至九講述Microsoft SQL Server的基礎知識,項目十為一個綜合型任務實例(設計收視分析問卷調查系統),介紹SQL Server數據庫的具體應用。本書理論與實際相結合,既闡述了數據庫的基本概念和方法,又結合SQL Server數據庫管理系統基本而核心的內容詳解其技術應用,闡述了典型數據庫應用系統的設計與實現方法。本書可作為高等院校計算機相關專業數據庫應用開發設計課程的教材,也可作為其他數據庫設計開發人員的實用參考書。
本書介紹了Microsoft SQL Server 2008數據庫管理系統的基本原理和綜合應用。全書共分十個項目,項目一至九講述Microsoft SQLServer的基礎知識,項目十為一個綜合型任務實例(設計收視分析問卷調查系統),介紹SQLServer數據庫的具體應用。本書理論與實際相結合,既闡述了數據庫的基本概念和方法,又結合SQLServer數據庫管理系統基本而核心的內容詳解其技術應用,闡述了典型數據庫應用系統的設計與實現方法。本書可作為高等院校計算機相關專業數據庫應用開發設計課程的教材,也可作為其他數據庫設計開發人員的實用參考書。
項目二
Transact-SQL語言
1. 項目要點
(1) 使用RETURN語句返回存儲過程的參考值。
(2) 使用CURRENT_USER約束列。
2. 引言
Transact-SQL是SQL Server 2008的編程語言,是一種結構化查詢語言,是SQL的增強版本。使用Transact-SQL語言,可以從數據庫中提取數據,完成SQL語言的數據定義(DDL)、數據操作(DML)和數據控制(DCC)等行為。本項目首先對Transact-SQL語言進行簡單概述,然后詳細講述Transact-SQL語言的基本功能。先介紹Transact-SQL語言的兩種標識符,即常規標識符和分隔標識符,然后介紹Transact-SQL語言中常用的幾種常量、變量、常用的運算符和常用的表達式。最后介紹Transact-SQL語言中常用的9種函數,并對典型函數進行舉例。通過本項目的講述,讀者將能夠較詳細地了解Transact-SQL語言的基本功能,方便后續項目的學習。
3. 項目導入
陳倩用Transact-SQL語言編寫程序,查詢教學管理系統Teacher數據庫student_grade表中成績大于80的數據,看下面的語句:
SELECT * FROM student_grade WHERE 成績>80
程序執行結果如圖2-1所示。
圖2-1 使用Transact-SQL進行查詢
4. 項目分析
在如圖2-1所示的查詢中,比較運算符(>)的返回值為布爾數據類型,可以有3種值:TRUE、FALSE或NULL。比較表達式的條件成立時,返回TRUE,否則返回FALSE。如果打開ANSI_NULLS選項,則當比較操作數中任一個為NULL時,將返回NULL。
5. 能力目標
(1) 掌握Transact-SQL的基本語言。
(2) 掌握Transact-SQL的內置函數。
6. 知識目標
(1) 學習Transact-SQL常量、變量、運算符、表達式、控制流程語句。
(2) 學習數學函數、字符串函數、日期時間函數等。
任務1 使用RETURN語句返回存儲過程的參考值
Transact-SQL是Microsoft公司在關系型數據庫管理系統SQL Server中對SQL-3標準的實現,是微軟對SQL的擴展,具有SQL的主要特點,同時增加了變量、運算符、函數、流程控制和注釋等語言元素,使其功能更加強大。
知識儲備
1. Transact-SQL概述
Transact-SQL對SQL Server十分重要,在SQL Server中,使用圖形界面能夠完成的所有功能,都可以通過Transact-SQL來實現。與SQL Server通信的所有應用程序都通過向服務器發送Transact-SQL語句來進行操作,而與應用程序的界面無關。
根據其完成的具體功能,可以將Transact-SQL語句分為4大類,分別為數據定義語句、數據操縱語句、數據控制語句和一些附加的語言元素。
(1) 數據定義語句:CREATE TABLE、DROP TABLE、ALTER TABLE、CREATE VIEW、DROP VIEW、CREATE INDEX、DROP INDEX、CREATE PROCEDURE、ALTER PROCEDURE、DROP PROCEDURE、CREATE TRIGGER、ALTER TRIGGER、DROP TRIGGER。
(2) 數據操縱語句:SELECT、INSERT、DELETE、UPDATE。
(3) 數據控制語句:GRANT、DENY、REVOKE。
(4) 附加的語言元素:BEGIN TRANSACTION / COMMIT、ROLLBACK、SET TRANSACTION、DECLARE OPEN、FETCH、CLOSE、EXECUTE。
2. 標識符
數據庫對象的名稱即為標識符。Microsoft SQL Server中的所有內容都可以有標識符,例如服務器、表、視圖、列、索引、觸發器、過程、約束及規則等。大多數對象都要求有標識符,但有些對象標識符是不可選的,例如,約束標識符是系統自動生成的,不需要用戶提供。
對象標識符是在定義對象時創建的,標識符隨后用于引用該對象。
【例1】創建一個標識符為student的表,該表中有兩個列標識符,分別是Number和Address:
CREATE TABLE student
(Number INT PRIMARY KEY, Address nvarchar(80))
此表還有一個未命名的約束。PRIMARY KEY約束沒有標識符。
標識符的排序規則取決于定義標識符時所在的級別。實例級對象的標識符指定的是實例的默認排序規則,例如登錄名、數據庫名。數據庫對象的標識符分配數據庫的默認排序規則,例如表、視圖和列名。按照標識符的使用方式,可把標識符分為兩類,即常規標識符和分隔標識符。這兩種標識符包含的字符數必須在1~128之間。對于本地臨時表,標識符最多可以有116個字符。
(1) 常規標識符
常規標識符的格式規則取決于數據庫的兼容級別。可以使用ALTER DATABASE進行設置。當兼容級別為100時,適用下列規則。
、 第一個字符必須是下列字符之一:Unicode標準3.2所定義的字母,這些定義的字母包括拉丁字符a~z和A~Z,以及來自其他語言的字母字符;下劃線(_)、符號@或數字符號#。
在Transact-SQL中,某些位于標識符開頭位置的符號具有特殊意義。
以@符號開頭的常規標識符始終表示局部變量或參數,并且不能用作任何其他類型的對象的名稱。某些Transact-SQL函數的名稱以兩個符號(@@)開頭。為了避免與這些函數混淆,不應使用以@@開頭的名稱命名。
以一個數字符號開頭的標識符表示臨時表或過程。以兩個數字符號(##)開頭的標識符表示全局臨時對象。雖然數字符號或兩個數字符號字符可用作其他類型對象名的開頭,但這里不建議使用。
、 后續字符可以包括:Unicode標準3.2中所定義的字母;基本拉丁字符或其他國家/地區字符中的十進制數字;@符號、美元符號($)、數字符號(#)或下劃線(_)。
、 標識符一定不能是Transact-SQL保留字。SQL Server可以保留大寫形式和小寫形式的保留字。
、 不允許嵌入空格或其他特殊字符。
、 不允許使用增補字符。
例如,studentInformation、@number_20、Money_88$等是合法的常規標識符,而the student、My name_@、age 30等不是合法的標識符。
在Transact-SQL語句中,如果符合標識符的格式規則,在使用常規標識符時,不用將其分隔開。例2中使用的標識符均是合法的,不用進行分隔。
【例2】查詢學號為15的學生信息:
SELECT *
FROM student
WHERE Number = 15
知識鏈接: 變量、函數和存儲過程的名稱必須符合Transact-SQL標識符的規則。在 Transact-SQL語句中使用標識符時,不符合上述規則的標識符必須用雙引號或括號分隔,即我們下面要介紹的分隔標識符。
(2) 分隔標識符
分隔標識符是包含在雙引號(“”)或者方括號([])內的標識符。使用雙引號(“”)分隔的標識符稱為引用標識符,使用方括號([])分隔的標識符稱為括在括號內的標識符。默認情況下使用方括號([])分隔標識符。只有QUOTED_IDENTIFIER選項設置為ON時,才使用雙引號(“”)分隔標識符。
在Transact-SQL語句中,符合標識符格式規則的標識符可以分隔,也可以不分隔。下面是對例2中的合法標識符進行分隔:
SELECT *
FROM [student]
WHERE [number] = 15
在Transact-SQL語句中,如果對象名稱包含了Microsoft SQL Server中的保留字或使用了未列入限定字符的字符,均不符合標識符的格式規則,必須進行分隔。例3中包含不合法的標識符My student和保留字order,必須進行分隔。
【例3】查詢序號為15的學生信息:
SELECT *
FROM [My student]
WHERE [order] = 15
注意: 美元符號($)的關鍵字通常用得較少,不為人們所熟知,應盡量避免使用,以提高程序的可讀性。
3. 常量和變量
(1) 常量
常量是表示特定數據值的符號,也稱為字面量,在整個程序運行過程中保持不變。常量的格式取決于它所表示的值的數據類型。Transact-SQL中常用的常量主要有字符串常量、整型常量、實型常量、Money常量、uniqueidentifier常量和日期時間常量等。
、 字符串常量
分為ASCII字符串常量和Unicode字符串常量兩種。
ASCII字符串常量是用單引號括起來的由ASCII字符構成的符號串,每個ASCII字符用一個字節來存儲。
Unicode字符串常量數據中的每個字符用兩個字節存儲,與ASCII字符串常量相似。N前綴必須為大寫字母,例如N‘What is you name?’。
ASCII和Unicode常量被分配了當前數據庫的默認排序規則,除非使用COLLATE子句分配特定的排序規則,例如:
'abc' COLLATE French_CI_AI或者N'lustig' COLLATE German_Phonebook_CS_AS
注意: 如果單引號中的字符串包含引號,可以使用兩個單引號表示嵌入的單引號。
、 整型常量
按照整型常量表示方式的不同,可將整型常量分為二進制整型常量、十進制整型常量和十六進制整型常量。
* 二進制整型常量的表示:即數字0或1,并且不使用引號。如果使用一個大于1的數字,它將被轉換為1。
* 十進制整型常量的標識:即不帶小數點的十進制數,例如2012、9、+20120215、-20120215。
* 十六進制整型常量的表示:前輟0x,后跟十六進制數字串。例如0xAEBF、0x12Ff、0x48AEFD010E、0x。
③ 實型常量
實型常量按表示方式的不同,可分為定點表示和浮點表示。
* 定點表示:例如1894.1204、2.0、+145345234.2234、-2147483648.10。
* 浮點表示:例如101.5E5、0.5E-2、+123E-3、-12E5。
、 日期時間常量
日期時間常量用單引號將表示日期時間的字符串括起來構成。SQL Server可以識別的日期和時間格式有字母日期格式、數字日期格式和未分隔的字符串格式。例如‘April 15, 2012’、‘4/15/1998’、‘20001207’、‘04:24:PM’、‘April 15, 2012 14:30:24’。
、 money常量
money常量是以$作為前綴的整型或實型常量數據。例如$12、$542023、-$45.56、+$423456.99。下面是將money常量應用到Transact-SQL中的例子:
SELECT Price +$6.50
FROM CommodityTable
⑥ uniqueidentifier常量
uniqueidentifier常量是表示全局唯一標識符(GUID)值的字符串。uniqueidentifier常量可以使用字符或者十六進制字符串格式來指定。例如‘642D-000F96D458AB19FF011-B04FC964FF’、0x2012ff6fd00c04fc964ff。
注意: 引用數值常量時不用單引號,引用日期、字符串常量時需要加單引號。
(2) 變量
變量是在程序運行過程中會發生改變的量。根據作用范圍,可以將變量分為局部變量和全局變量兩種。
、 局部變量
局部變量是指在批處理或腳本中用來保存數據值的對象,是用戶自己定義的變量。局部變量一次只能保存一個值,它的作用范圍僅在程序內部。
一般局部變量只在一個批處理或存儲過程中使用,用來存儲從表中查詢到的數據,或當作程序執行過程中的暫存變量使用。通常,局部變量可以作為計數器,計算循環執行的次數或控制循環執行的次數;此外,利用局部變量還可以保存數據值,以供流程控制語句測試,以及保存由存儲過程返回的數據值等。
局部變量使用Declare語句來聲明,其語法格式如下:
Declare {變量名 數據類型}[...n]
例如:
DECLARE @name varchar(8)
DECLARE @seat int
聲明完局部變量后,就可以對其進行賦值了,賦值格式如下:
SET @變量名 = 值 (普通賦值)
SELECT @變量名 = 值[,...](查詢賦值)
使用SELECT語句賦值時,若返回多個值,結果為返回的最后一個值。若省略“=”及其后的表達式,可以將局部變量的值顯示出來。
例如下面兩個為變量賦值的語句:
SET @name = '張三'
SELECT @name = sname FROM student
WHERE snum = '001'
注意: 局部變量必須先聲明后使用,初值為NULL。
【例4】編寫程序,計算兩個整數之和:
DECLARE @i int, @j int, @sum int
SET @i = 50
SET @j = 60
SELECT @sum = @i + @j
PRINT @sum
GO
語法說明如下:DECLARE聲明局部變量。@i、@j、@sum為變量名,總是以@開始。int為變量的數據類型。SELECT和SET用來對局部變量進行賦值。SET一次只能給一個局部變量賦值,SELECT可以同時給多個局部變量賦值。
② 全局變量
全局變量也稱配置函數,是SQL Server系統提供并賦值的變量,用于存儲系統的特定信息,作用范圍并不局限于某一程序,而是任何程序均可隨時調用。
全局變量是在服務器級定義的,以@@開頭。例如@@version。
全局變量對用戶來說,是只讀的,用戶只能使用預先定義的全局變量,不能建立全局變量,也不能修改其值,但可在程序中用全局變量來測試系統的設定值或Transact-SQL命令執行后的狀態值。
在Transact-SQL語句中,常用的全局變量如表2-1所示。
【例5】使用全局變量查看SQL Server的版本信息和服務器名稱:
print '當前所用的SQL Server版本信息如下:'
print @@version
print ''
print '目前所用SQL Server服務器的名稱為:' + @@servername
print語句用于顯示char類型、varchar類型,或可自動轉換為字符串類型的數據。
表2-1 Transact-SQL中的全局變量
變 量
說 明
@@CPU_BUSY
SQL Server自上次啟動后的工作時間,單位:毫秒
@@CURSOR_ROES
打開上一個游標中當前限定行的數目
@@ERROR
上一條Transact-SQL語句報告的錯誤號
@@IDENTITY
最后插入的標識值
@@LANGID
當前使用語言的ID
@@NESTLEVEL
當前存儲過程的嵌套級別(初始值為0)
@@PROCID
Transact-SQL當前模塊的ID
@@ROWCOUNT
上一條Transact-SQL語句影響的行數
@@SERVERNAME
本地服務器的名稱
@@SPID
當前用戶進程的會話ID
@@VERSION
當前SQL Server的版本、處理器體系結構、生成日期
4. 運算符
運算符是一種符號,它們能夠用來執行算術運算、字符串連接、賦值,以及在字段、常量和變量之間進行比較。在Transact-SQL中,常用到的運算符主要有算術運算符、賦值運算符、邏輯運算符、比較運算符、位運算符和字符串串聯運算符。
(1) 算數運算符
算術運算符可以在兩個表達式上執行數學運算,這兩個表達式可以是數字數據類型分類的任何數據類型。
Transact-SQL中提供了5種算術運算符,表2-2列出了這些運算符及作用。
表2-2 算數運算符
運 算 符
含 義
例 子
結 果
+
加法運算
6+8
14
-
減法運算
10-7
3
*
乘法運算
2*3
6
/
除法運算
14/5
2
%
取模運算
14%5
4
(2) 賦值運算符
賦值運算符的作用,是將數據值指派給特定的對象,也可以使用賦值運算符在列標題與為列定義值的表達式之間建立關系。
Transact-SQL中只有一個賦值運算符,即等號(=)。
【例6】下面的語句先定義一個int變量@number,然后將其值賦為20:
declare @number int
set @number = 20
(3) 邏輯運算符
邏輯運算符可以把多個邏輯表達式連接起來。邏輯運算符包括AND、OR和NOT等運算符。邏輯運算符和比較運算符一樣,返回帶有TRUE或FALSE值的布爾數據類型。
表2-3列出了Transact-SQL中常用的10種邏輯運算符。
表2-3 邏輯運算符
運 算 符
含 義
ALL
如果一組的比較都返回TRUE,則比較結果為TRUE
AND
如果兩個布爾表達式都返回TRUE,則結果為TRUE
ANY
如果一組的比較中任何一個返回TRUE,則結果為TRUE
BETWEEN
如果操作數在某個范圍之內,則結果為TRUE
EXISTS
如果子查詢中包含了一些行,則結果為TRUE
IN
如果操作數等于表達式列表中的一個,則結果為TRUE
LIKE
如果操作數與某種模式相匹配,則結果為TRUE
NOT
對任何其他布爾運算符的結果值取反
OR
如果兩個布爾表達式中的任何一個為TRUE,則結果為TRUE
SOME
如果在一組比較中,有些比較為TRUE,則結果為TRUE
【例7】從student表中查詢年齡為20或姓為“王”的學生信息:
Select *
From student
Where stu_age = 20 or stu_name like '王'
【例8】查找由位于以字母B開頭的城市中的任一出版商出版的書名。
方法1:
USE pubs
GO
SELECT title
FROM titles
WHERE EXIST
(SELECT *
FROM publishers
WHERE pub_id=titles.pub_id
AND city LIKE \'B%\')
GO
方法2:
USE pubs
GO
SELECT title
FROM titles
WHERE pub_id IN
(SELECT pub_id
FROM publishers
WHERE city LIKE \'B%\')
GO
(4) 位運算符
位運算符是在兩個表達式之間執行位操作,這兩個表達式可以是任意兩個整型數據或者二進制數據(image數據類型除外)類型的表達式。此外,位運算符的兩個操作數不能同時是二進制數據。
Transact-SQL中提供了3種位運算符,表2-4中列出了這些運算符及作用。
表2-4 位運算符
運 算 符
含 義
例 子
結 果
&
位與
170&75
10
|
位或
170|75
235
^
位異或
170^75
225
(5) 比較運算符
比較運算符用于比較兩個表達式的大小是否相同,其比較的結果是布爾值。如果表達式的結果為真,用TRUE表示;如果表達式的結果為假,用FALSE表示;如果表達式的結果是空值,則用UNKNOWN表示。
空值不與任何值匹配,包括其他情況下的空值。
例如,搜索以字母“M”或“M”后的字母開始的姓名(name>=‘M’),并且某些行不包含值,則無論使用何種比較運算符,這些行都不顯示。
比較中所使用數據的數據類型必須匹配。即文本只能比較文本,數字只能比較數字。比較文本數據時,結果取決于當前使用的字符集。例如,如果表是使用斯堪的納維亞語字符集創建的,搜索的結果可能會不同,這取決于當前的字符集(代碼頁)是斯堪的納維亞語字符集還是另外一種字符集。
Transact-SQL中提供了9種比較運算符,表2-5中列出了這些運算符及作用。
表2-5 比較運算符
運 算 符
含 義
=
等于
>
大于
<
小于
>=
大于等于
<=
小于等于
<>
不等于
!=
不等于
!<
不小于
!>
不大于
【例9】查找編號為770的產品的名稱和產品號:
USE Adventureworks2008;
GO
DECLARE @product0 int;
SET @product0 = 770;
IF (@product0 <> 0)
SELECT ProductID, Name, ProductNumber
FROM Production.product
WHERE ProductID = @product0
(6) 字符串串聯運算符
字符串串聯運算符允許通過加號(+)進行字符串串聯,這個加號即被稱為字符串串聯運算符。
【例10】執行下面的語句:
SELECT 'abc' + 'def';
結果為‘abcdef’。
(7) 一元運算符
一元運算符只對一個表達式執行操作,這個表達式可以是數字數據類型中的任意數據類型。
Transact-SQL中提供了3種一元運算符,表2-6中列出了這些運算符及作用。
表2-6 一元運算符
運 算 符
含 義
+
正
-
負
~
位非
拓展提高: “+”和“-”運算符可以用于數字數據類型中的任意表達式,“~”運算符只能用于整型數據類型類別中的任意數據類型的表達式。
【例11】將一個變量設為正值:
DELARE @num decimal(10,2)
SET @num = +2012.45;
SELECT @num;
GO
結果為2012.45。
(8) 運算符的優先級
如果一個表達式中使用了多種運算符,則運算符的優先順序決定計算的先后次序。計算時,從左向右依次先做優先級高的運算,再做優先級低的運算。
Transact-SQL中,運算符的優先級如表2-7所示。
表2-7 運算符的優先級
優 先 級
運 算 符
1
~(位非)
2
*(乘)、/(除)、%(取模)
3
+(正)、-(負)、+(加)、+(連接)、-(減)、&(位與)
4
=、>、<、>=、<=、<>、!=、!>、!<
5
^(位異或)、|(位或)
6
NOT
7
AND
8
ALL、ANY、BETWEEN、IN、LIKE、OR、SOME
9
=(賦值)
拓展提高: 當表達式中使用括號替代運算符優先級時,首先要對括號中的內容進行求值,然后再對括號外的運算符進行求值。當表達式中的多個運算符有相同的優先級時,要按照這些運算符在表達式中的位置,從左到右依次進行求值。
5. 表達式
在Transact-SQL語言中,表達式是由標識符、常量、變量、函數和運算符組成的式子。Transact-SQL語言中包括三種表達式:字段名表達式、目標表達式和條件表達式。
注意: 單個常量、變量或函數亦可稱作表達式。
(1) 字段名表達式
字段名表達式可以是單一的字段名,或幾個字段的組合,還可以是由字段及作用于字段的集函數和常量的任意算術運算組成的運算公式,例如+(加)、-(減)、*(乘)、/(除)。字段名表達式主要包括數值表達式、字符表達式、邏輯表達式、日期表達式4種。
(2) 目標表達式
目標表達式有如下4種構成方式。
* *:表示選擇相應基表和視圖的所有字段。
* <表名>.*:表示選擇指定的基表和視圖的所有字段。
* 集函數():表示在相應的表中按集函數操作和運算。
* [<表名>.]<字段名表達式>[, [<表名>.]<字段名表達式>]…:表示按字段名表達式在多個指定的表中選擇。
(3) 條件表達式
常用的條件表達式主要有比較大小、指定范圍、是否在集合中、字符匹配、空值和多重條件6種。
、 比較大小的條件表達式由比較運算符構成,主要的比較運算符有=、>、<、>=、<=、!=、<>、!>(不大于)、!<(不小于)、NOT+(取非)。
② 指定范圍的條件表達式由(NOT)BETWEEN ... AND...構成。
(NOT)BETWEEN ... AND ...表示查找字段值在(或不在)指定的記錄范圍內。BETWEEN后是范圍的下限(即低值),AND后是范圍的上限(即高值)。
、 集合的條件表達式由(NOT) IN構成。
(NOT) IN表示查找字段值屬于(或不屬于)指定集合內的記錄。
、 字符匹配的條件表達式格式如下:
(NOT) LIKE <匹配串> [ESCAPE <換碼字符>]
(NOT) LIKE <匹配串> [ESCAPE <換碼字符>]表示查找指定的字段值與<匹配串>相匹配(或不相匹配)的記錄。<匹配串>可以是一個完整的字符串,也可以含有通配符_和%。其中,“_”代表任意單個字符,“%”代表任意長度的字符串。
⑤ 空值的條件表達式由IS (NOT) NULL構成。
IS (NOT) NULL表示查找字段值為空(或不為空)的記錄。NULL不能用來表示無形值、默認值、不可用值以及取最低值或取最高值。Transact-SQL中規定,在含有運算符+、-、*、/的算術表達式中,若有一個值是空值,則該算術表達式的值也是空值;任何一個含有NULL比較操作結果的取值都為“假”。
⑥ 多重條件的條件表達式由AND和OR構成。
AND表示查找字段值滿足所有與AND相連的查詢條件的記錄;OR表示查找字段值滿足查詢條件之一的記錄。AND的優先級高于OR,但可通過括號來改變優先級。
6. 控制流語言
流程控制語句是指那些用來控制程序執行和流程分支的命令,在SQL Server 2008中,流程控制語句主要用來控制Transact-SQL語句、語句塊和存儲過程的執行流程。
控制流語句包括BEGIN ... END語句、IF ... ELSE語句、CASE語句、WHILE語句、CONTINUE、BREAK、GOTO語句、WAITFOR語句。
(1) BEGIN ... END語句
BEGIN ... END語句能夠將多個Transact-SQL語句組合成一個語句塊,并將它們視為一個單元來處理。在條件語句和循環等控制流程語句中,當符合特定條件便要執行兩個或者多個語句時,就需要使用BEGIN ... END語句,其語法如下:
BEGIN
{sql_statement | statement_block}
END
說明:
① BEGIN ... END:為語句關鍵字,允許嵌套。
、 {sql_statement | statement_block}:指任何有效的Transact-SQL語句或語句組。
【例12】使用BEGIN ... END語句,將一組Transact-SQL語句組成語句組,并作為一個單元來運行:
USE AdventureWork2008
GO
BEGIN TRANSACTION;
GO
IF @@TRANCOUNT = 0
BEGIN
SELECT *
FROM PERSON.PERSON
WHERE LastName = 'SMITH';
ROLLBACK TRANSACTION
PRINT N'Rolling back the transaction two times would cause an error.'
END
ROLLBACK TRANSACTION
PRINT N'Rolled back the transaction.'
GO
(2) IF ... ELSE語句
IF ... ELSE語句是條件判斷語句,用來判斷當某一條件成立時執行某段程序,條件不成立時執行另一段程序。其中,ELSE子句是可選的。SQL Server允許嵌套使用IF ... ELSE語句,而且嵌套層數沒有限制。
IF ... ELSE語句的語法格式如下:
IF Boolean_expression
{sql_statement | statement_block}
[ ELSE
{sql_statement | statement_block}
]
說明:
、 IF ... ELSE構造可用于批處理、存儲過程和即時查詢。
② 可以在其他IF之后或在ELSE下面嵌套IF語句。
、 Boolean_expression:返回TRUE或FALSE的表達式。如果布爾表達式中含有SELECT語句,則必須用圓括號將SELECT語句括起來。
④ {sql_statement | statement_block}:指任何有效的Transact-SQL語句或語句組。
【例13】使用IF ... ELSE進行事務處理,正常則提交數據,否則回滾數據:
IF(@ErrorCode <> 0)
BEGIN
PRINT 'Last error encountered: ' + CAST(ErrorCode AS VARCHAR(10))
ROLLBACK
END
ELSE
BEGIN
PRINT 'No error encountered, committing.'
END
RETURN ErrorCode
(3) CASE語句
CASE語句用于計算條件列表,并將其中一個符合條件的結果表達式返回。CASE函數按照使用形式的不同,可以分為簡單CASE函數和搜索CASE函數。
簡單CASE函數用于將某個表達式與一組簡單表達式進行比較,以確定結果。它的語法形式為:
CASE
WHEN when_expression THEN result_expression
[...n]
[
ELSE else_result_expression
]
END
說明:
、 WHEN when_expression:表示使用簡單CASE格式時要與input_expression進行比較的表達式。
、 n:占位符,這表明可以使用多個WHEN when_expression THEN result_expression子句。
、 THEN result_expression:表示當輸入input_ expression = when_expression的結果為TRUE時返回的表達式。
、 ELSE else_result_expression:表示比較運算結果為FALSE時的表達式。
【例14】在SELECT語句中,使用簡單的CASE函數檢查表達式是否相等:
USE AdventureWork2008
GO
SELECT Productnumber AS '產品編號', N'種類'=CASE ProductLine
When 'R' THEN N '公路',
When 'M' THEN N '山地',
When 'T' THEN N '旅行',
When 'S' THEN N '其他項',
ELSE N '非賣品'
END,
Name As '名稱'
FROM Production.product
ORDER By ProductNumber;
搜索CASE函數用于計算一組布爾表達式,以確定結果。它的語法形式為:
CASE
WHEN Boolean_expression THEN result_expression
[...n]
[
ELSE else_result_expression
]
END
說明:
WHEN Boolean_expression:表示使用CASE搜索格式時所計算的布爾表達式。
【例15】使用CASE函數對Production.product數據表中的價格進行分段歸類:
USE AdventureWork2008
GO
SELECT Productnumber AS '產品編號', Name As '名稱', N'價格范圍'=
CASE ProductLine
When ListPrice = 0 THEN N'0元',
When ListPrice < 50 THEN N'50元以下',
When ListPrice >= 50 THEN N'250元以下',
When ListPrice >= 250 THEN N'1000元以下',
ELSE N'1000元以上'
END,
FROM Production.product
ORDER By ProductNumber;
(4) WHILE、CONTINUE和BREAK語句
WHILE、CONTINUE和BREAK語句用于設置重復執行Transact-SQL語句或語句塊的條件。當指定的條件為真時,重復執行語句。
知識鏈接: CONTINUE語句可以使程序跳過CONTINUE語句后面的語句,回到WHILE循環的第一行命令。BREAK語句則使程序完全跳出循環,結束WHILE語句的執行。
語法格式如下:
WHILE Boolean_expression
{ sql_statement | statement_block }
[BREAK]
{ sql_statement | statement_block }
[CONTINUE]
{ sql_statement | statement_block }
說明:
、 如果嵌套了兩個或多個WHILE循環,則內層的BREAK將退出到下一個外層循環。將首先運行內層循環結束之后的所有語句,然后重新開始下一個外層循環。
、 Boolean_expression表達式返回TRUE或FALSE。
、 {sql_statement | statement_block}為Transact-SQL語句或語句塊定義的語句分組。
、 BREAK導致從最內層的WHILE循環中退出。
⑤ CONTINUE使WHILE循環重新開始執行,忽略CONTINUE關鍵字后面的任何語句。
【例16】在嵌套的IF ... ELSE中使用BREAK和CONTINUE,根據條件判斷是否繼續執行WHILE循環,如果中斷,則執行BREAK,如果繼續,則執行CONTIOUE:
USE AdventureWork2008
GO
WHILE (SELECT AVG(ListPrice) FROM Production.product) > $600
BEGIN
UPDATE Production.product
SET ListPrice = ListPrice/2
SELECT MIN(ListPrice)
FROM Production.product
IF(SELECT MIN(ListPrice) FROM Production.product) < $200
BREAK
ELSE
CONTINUE
END
(5) GOTO語句
GOTO語句可以使程序直接跳到指定的標有標識符的位置繼續執行。
GOTO語句和標識符可以用在語句塊、批處理和存儲過程中,標識符可以為數字與字符的組合,但必須以冒號“:”結尾。GOTO語句允許嵌套。
語法形式如下:
label:
some execution
GOTO label
說明:
① GOTO可出現在條件控制語句、語句塊或過程中,但它不能跳轉到該批處理以外的標簽。GOTO分支可跳轉到定義在GOTO之前或之后的標簽。
、 label:如果GOTO語句指向該標簽,則該標簽為處理的起點。
注意: 默認情況下,GOTO語句的權限授予任何有效用戶。
【例17】使用GOTO語句建立循環結構,循環條件由IF語句和GOTO組成:
USE AdventureWork2008
GO
DELARE @table0 sysname
DELARE @count int
SET @table0 = N'Production.product'
SET @count = 0;
LOOP:
IF(@@ERROR = 0)
BEGIN
EXEC ('select''' + table + '''= count(*) FROM' + @table0)
SET @count = @count+1;
PRINT STR(@count) + N'執行完成'
END
IF(@@ERROR = 0 AND @count<2)
GOTO LOOP
GO
(6) WAITFOR語句
WAITFOR語句用于暫時停止執行Transact-SQL語句、語句塊或者存儲過程等,直到所設定的時間已過,或者所設定的時間已到,才繼續執行。
WAITFOR語句的處理過程為:如果查詢不能返回任何行,WAITFOR將一直等待,直到滿足TIMEOUT條件為止。如果查詢超出了設定的查詢時間值,則WAITFOR語句參數不運行即可完成。
語法形式為:
WAITFOR
DELAY 'time_to_pass'
| TIME 'time_to_execute'
| (receive_statement) [, TIMEOUT timeout]
說明:
、 DELAY:表示可以繼續執行Transact-SQL語句、語句塊或者存儲過程之前,必須經過的指定時段(最長為24小時)。
② time_to_pass:指等待時間。
、 TIME:表示指定的運行Transact-SQL語句、語句塊或者存儲過程的時間。
④ time_to_execute:指WAITFOR語句完成時間。
、 receive_statement:指有效的RECEIVE語句。
、 TIMEOUT timeout:表示指定消息到達隊列前的等待時間。
【例18】使用WAITFOR設置啟動任務:
Begin
WAITFOR TIME '7:00';
EXECUTE sp_job;
END;
GO
(7) RETURN語句
RETURN語句用于無條件地終止一個查詢、存儲過程或批處理,此時位于RETURN語句之后的程序將不會被執行。RETURN的執行是即時且完全的,在任何時候都可以從批處理、過程或語句塊中退出。
RETURN語句的語法形式為:
RETURN [integer_expression]
其中,integer_expression指返回的整型值。存儲過程可向執行調用的過程或應用程序返回一個整數值。
任務實踐
使用RETURN語句返回存儲過程的參考值:
CREATE PROCEDURE findjob @n system = NULL
AS
IF @n IS NULL
BEGIN
PRINT 'you must give a user name'
RETURN
END
ELSE
BEGIN
SELECT O.name, o.id, o.uid
FROM sysobjects o INNER JOIN master.syslogins l
ON o.uid = l.sid
WHERE l.name = @n
END;
Exec findjob
EXEC findjob @n='sa'
任務2 使用CURRENT_USER約束列
知識儲備
T-SQL中的內置函數很多,大體上可分為下面幾類:數學函數、字符串函數、日期和時間函數、系統函數、系統統計函數、聚合函數、配置函數、游標函數、元數據函數、安全函數、排名函數、加密函數、行集函數以及文本和圖像函數。這里僅就一些常用的函數進行介紹,如表2-8所示,列出了這些常用內置函數的作用。
表2-8 常用的系統內置函數
函數類別
作 用
聚合函數
執行的操作是將多個值合并為一個值。例如COUNT、SUM、MIN和MAX
配置函數
是一種標量函數,可返回有關配置設置的信息
轉換函數
將值從一種數據類型轉換為另一種
游標函數
返回有關游標狀態的信息
日期和時間函數
可以更改日期和時間的值
數學函數
執行三角、幾何和其他數字運算
元數據函數
返回數據庫和數據庫對象的屬性信息
安全函數
返回有關用戶和角色的信息
字符串函數
可更改char、varchar、nchar、nvarchar、binary和varbinary的值
系統函數
對系統級的各種選項和對象進行操作或報告
系統統計函數
返回有關SQL Server性能的信息
知識鏈接: SQL Server內置函數可以是確定或不確定的。如果任何時候用一組特定的輸入值調用內置函數,返回的結果總是相同的,則這些內置函數為確定的。如果每次調用內置函數時,即使所用的是同一組特定輸入值,也總是返回不同的結果,則這些內置函數為不確定的。
1. 數學函數
數學函數是對數值型的輸入值執行計算,并返回一個數值。如算數函數ABS、CEILING、DEGREES、FLOOR、POWER、RADIANS和SIGN將返回與輸入值具有相同數據類型的值,而三角函數和其他函數(如EXP、LOG、LOG10、SQUARE和SQRT)先將輸入值轉換為float類型后,再返回float類型值。數學函數都是標量函數。
表2-9列出了所有數學函數及其描述。
表2-9 數學函數
函 數
描 述
ABS(numeric_expression)
返回指定數值表達式的絕對值(正值)的數學函數。
numeric_expression表示精確數字或近似數字數據類型(bit數據類型除外)的表達式。
返回值類型與numeric_expression相同
ACOS(float_expression)
返回其余弦是所指定的float表達式的角(弧度);也稱為反余弦
ACOS(float_expression)
float_expression表示類型為float或類型可以隱式轉換為float的表達式,取值范圍是(-1~1)。對超過此范圍的值,函數將返回NULL并報告域錯誤。
返回值類型為float
ASIN(float_expression)
返回以弧度表示的角,其正弦為指定float表達式;也稱為反正弦。float_expression表示類型為float或可隱式轉換為float類型的表達式,取值范圍是(-1~1)。對超過此范圍的值,函數將返回NULL并且報告域錯誤。
返回值類型為float
ATAN(float_expression)
返回以弧度表示的角,其正切為指定的float表達式。
也稱為反正切函數。
float_expression表示float類型或可以隱式轉換為float類型的表達式。
返回值類型為float
ATN2(float_expression,
float_expression)
返回以弧度表示的角,該角位于正X軸和原點至點(y, x)的射線之間,其中,x和y是兩個指定的浮點表達式的值。
float_expression表示數據類型為float的表達式。
返回值類型為float
CEILING
(numeric_expression)
返回大于或等于指定數值表達式的最小整數。
numeric_expression表示精確數字或近似數字數據類型(bit 數據類型除外)的表達式。
返回值類型與numeric_expression相同
COS(float_expression)
返回指定表達式中以弧度表示的指定角的三角余弦。
float_expression表示數據類型為float的表達式。返回值類型為float
COT(float_expression)
返回指定的float表達式中所指定角度(以弧度為單位)的三角余切值。
float_expression表示屬于float類型或能夠隱式轉換為float的表達式。
返回值類型為float
DEGREES
(numeric_expression)
返回以弧度指定的角的相應角度。
numeric_expression表示精確數字或近似數字數據類型類別(bit數據類型除外)的表達式。返回值類型與numeric_expression相同
續表
函 數
描 述
EXP(float_expression)
返回指定的float表達式的指數值。
float_expression表示float類型或能隱式轉換為float類型的表達式。
返回值類型為float
SIGN(numeric_expression)
返回指定表達式的正號(+1)、零(0)或負號(-1)。
numeric_expression是精確數字或近似數字數據類型的表達式
SIN(float_expression)
以近似數字(float)表達式返回指定角度(以弧度為單位)的三角正弦值
SIN(float_expression)
float_expression屬于float類型或能夠隱式轉換為float類型的表達式。
返回值類型為float
SQRT(float_expression)
返回指定浮點值的平方根。
float_expression是float類型或能夠隱式轉換為float類型的表達式。
返回值類型為float
SQUARE(float_expression)
返回指定浮點值的平方。
float_expression是float類型或能夠隱式轉換為float類型的表達式。
返回值類型為float
TAN(float_expression)
返回輸入表達式的正切值。
float_expression是float類型或可隱式轉換為float類型的表達式,解釋為弧度數。
返回值類型為float
【例19】下例產生4個不同的隨機數:
DECLARE @counter SMALLINT
SET @counter = 1
WHILE @counter < 5 BEGIN
PRINT RAND(@counter)
SET @counter = @counter + 1
END
【例20】計算指定的x向量和y向量的ATN2:
DECLARE @x float
DECLARE @y float
SET @x = 35.175643
SET @y = 129.44
SELECT 'The ATN2 of the angle is: ' + CONVERT(varchar,ATN2(@x,@y))
GO
注意: 除RAND以外的所有數學函數都為確定性函數。在每次使用特定的輸入值集調用這些函數時,它們都將返回相同的結果。僅當指定種子參數時,RAND才是確定性函數。
2. 字符串函數
字符串函數對字符串執行操作,并返回字符串或數值。字符串函數也為標量函數。所有內置字符串函數都是具有確定性的函數。表2-10列出了所有字符串函數及其含義。
表2-10 字符串函數
函 數
描 述
ASCII(character_expression)
返回character_expression最左端字符的ASCII代碼值。
character_expression為char或varchar類型的表達式。返回值為int型
CHAR(integer_expression)
以char(1)類型返回ASCII代碼等于整型表達式integer_expression的值的字符。integer_expression是介于0~255之間的整數。如果該整數表達式不在此范圍內,將返回NULL值
UNICODE
(ncharacter_expression)
返回給定字符串最左端字符的Unicode代碼值。
ncharacter_expression是nchar或nvarchar表達式。返回值為int型
NCHAR(integer_expression)
返回Unicode代碼等于整型表達式integer_expression的值的字符。
integer_expression是介于0~65535之間的正整數。如果指定了超出此范圍的值,將返回NULL。返回值類型為nchar(1)
CHARINDEX(expression1, expression2[, start_location])
在expression2中從start_location位置開始搜索expression1的首次出現,返回首字符位置。注意字符位置從1開始計算。expression1包含要查找的序列的字符表達式。最大長度限制為8000個字符。expression2表示要搜索的字符表達式。
start_location表示搜索起始位置的整數或bigint表達式。如果未指定 start_location,或者start_location為負數或0,則將從expression2的開頭開始搜索。若expression2的數據類型為varchar(max)、nvarchar(max)或varbinary(max),則返回值類型為bigint,否則為int
SOUNDEX
(character_expression)
返回字符串的四字符代碼,常用來評估兩個字符串的相似性。
character_expression是字符數據的字母數字表達式,可以是常量、變量或列。
返回值類型為varchar
DIFFERENCE
(character_expression1, character_expression2)
返回兩個字符表達式的SOUNDEX值的差別。
character_expression是類型為char或varchar的表達式,也可以是text 類型,但只有前8000個字節有效。
返回值類型為int
LEFT/RIGHT
(character_expression, count)
以varchar類型返回從字符串character_expression左邊(右邊)截取的長度為count的子串。
character_expression是字符或二進制數據表達式,可以是常量、變量
REPLICATE
(character_expression, count)
將給定字符串重復count次后返回。
string_expression是字符串或二進制數據類型的表達式,可以是字符或二進制數據。返回值類型與string_expression的類型相同
續表
函 數
描 述
REVERSE(
character_expression)
將給定字符串反轉后返回。
string_expression是字符串或二進制數據類型的表達式,可以是常量、變量,也可以是字符列或二進制數據列。
返回值類型為varchar或nvarchar
STR(float_expression
[, length[, decimal]])
將給定數值轉換成長度為length,小數位數為decimal的數字字符串。
float_expression是帶小數點的近似數字(float)數據類型的表達式。
length表示總長度,包括小數點、符號、數字以及空格。默認值為10。
decimal指小數點右邊的小數位數。decimal必須小于等于16。如果decimal大于16,則將結果截斷為小數點右邊的16位。
返回值類型為varchar
SPACE(count)
返回由count個空格組成的字符串。
integer_expression是指示空格個數的正整數。如果integer_expression為負,則返回空字符串。返回值類型為varchar
STUFF(string_expression1,
start, length,
string_expression2)
用字符串string_expression2替換string_expression1中從start開始的length個字符并返回替換結果。
character_expression是一個字符數據表達式,是常量、變量,也可以是字符列或二進制數據列。
start為指定刪除和插入的開始位置。如果start或length為負,則返回空字符串。如果start比第一個character_expression長,則返回空字符串。start可以是bigint類型。
length指定要刪除的字符數。如果length比第一個character_expression長,則最多刪除到最后一個character_expression中的最后一個字符。
length可以是bigint類型。
如果character_expression是受支持的字符數據類型,則返回字符數據。如果character_expression是一個受支持的binary數據類型,則返回二進制數據
LEN(string_expression)
返回指定字符串表達式的字符數,其中不包含尾隨空格。
string_expression要求值的字符串表達式,可以是常量、變量,也可以是字符列或二進制數據列。
如果expression的數據類型為varchar(max)、nvarchar(max)或 varbinary (max),則為bigint;否則為int
LOWER/UPPER (character_expression)
將大(小)寫字符數據轉換為小(大)寫字符數據后返回字符表達式。
character_expression是一個字符數據表達式,可以是常量、變量,也可以是字符列或二進制數據列。character_expression的數據類型必須可隱式轉換為varchar,否則,應使用CAST顯式轉換。
返回值類型為varchar或nvarchar 續表
函 數
描 述
PATINDEX(‘%pattern%’,
expression)
返回指定表達式中某種模式第一次出現的起始位置;如果在全部有效的文本和字符數據類型中沒有找到該模式,則返回零。
pattern是文字字符串數據類型的表達式,可以使用通配符,但pattern 之前和之后必須有%字符(搜索第一個或最后一個字符時除外)。
expression是一個字符串數據類型的表達式,通常為要在其中搜索指定模式的列。
如果expression的數據類型為varchar(max)或nvarchar(max),則為bigint,否則為int
REVERT(
WITH COOKIE =
@varbinary_variable)
執行上下文切換回最后一個EXECUTE AS語句的調用方。
WITH COOKIE = @varbinary_variable是指定在相應的EXECUTE AS獨立語句中創建的Cookie。
@varbinary_variable的數據類型為varbinary(100)
SUBSTRING(
value_expression,
start_expression,
length_expression)
返回字符表達式、二進制表達式、文本表達式或圖像表達式的一部分。
value_expression是character、binary、text、ntext或image類型的表達式。start_expression指定返回字符的起始位置的整數或bigint表達式。如果start_expression小于1,則返回的表達式的起始位置為value_ expression中指定的第一個字符。在這種情況下,返回的字符數是start_expression與length_expression-1和0兩者中的較大值。如果 start_expression的值大于表達式中的字符數,將返回一個零長度的表達式。length_expression是正整數或指定要返回的value_expression的字符數的bigint表達式。
如果length_expression是負數,會生成錯誤并終止語句。如果start_ expression與length_expression的和大于value_expression中的字符數,則返回起始位置為start_expression的整個值表達式。
如果expression是其中一個受支持的字符數據類型,則返回字符數據。如果expression是支持的binary數據類型中的一種數據類型,則返回二進制數據。返回的字符串類型與指定表達式的類型相同(表中顯示的除外)
【例21】對“Du monde entier”字符串中的每個字符,設定一個ASCII字符集并返回ASCII值以及char字符:
SET TEXTSIZE 0
SET NOCOUNT ON
-- Create the variables for the current character string position
-- and for the character string.
DECLARE @position int, @string char(15)
-- Initialize the variables.
SET @position = 1
SET @string = 'Du monde entier'
WHILE @position <= DATALENGTH(@string)
BEGIN
SELECT ASCII(SUBSTRING(@string, @position, 1)),
CHAR(ASCII(SUBSTRING(@string, @position, 1)))
SET @position = @position + 1
END
SET NOCOUNT OFF
GO
【例22】輸出字符串“New Moon”中每個字符的ASCII值和字符:
SET TEXTSIZE 0
-- Create variables for the character string and for the current
-- position in the string.
DECLARE @position int, @string char(8)
-- Initialize the current position and the string variables.
SET @position = 1
SET @string = 'New Moon'
WHILE @position <= DATALENGTH(@string)
BEGIN
SELECT ASCII(SUBSTRING(@string, @position, 1)),
CHAR(ASCII(SUBSTRING(@string, @position, 1)))
SET @position = @position + 1
END
GO
3. 日期時間函數
日期時間函數是對日期和時間輸入值執行操作,并返回一個字符串、數字或日期和時間值。這些函數都是標量函數。日期時間函數可分為用來獲取系統日期和時間值的函數、用來獲取日期和時間部分的函數、用來獲取日期和時間差的函數、用來修改日期和時間值的函數、用來設置或獲取會話格式的函數和用來驗證日期和時間值的函數等6類函數。下面分別對這6類函數進行介紹。
拓展提高: SQL Server 2008 R2使用GetSystemTimeAsFileTime() Windows API來獲取日期和時間值。精確程度取決于運行SQL Server實例的計算機硬件和Windows版本。此API的精度固定為100納秒。可通過使用GetSystemTimeAdjustment() Windows API來確定該精確度。
(1) 用來獲取系統日期和時間值的函數
所有的系統日期和時間值均來自運行SQL Server實例的計算機操作系統。
用來獲取系統日期和時間值的函數有SYSDATETIME()、SYSDATETIMEOFFSET()、SYSUTCDATETIME()、CURRENT_TIMESTAMP()、GETDATE()和GETUTCDATE(),共6種函數,如表2-11所示。
表2-11 獲取系統日期和時間值的函數
函 數
描 述
SYSDATETIME()
返回包含計算機的日期和時間的datetime2(7)值,SQL Server的實例正在該計算機上運行。時區偏移量未包含在內
SYSDATETIMEOFFSET()
返回包含計算機的日期和時間的datetimeoffset(7)值,SQL Server的實例正在該計算機上運行。時區偏移量包含在內
SYSUTCDATETIME()
返回包含計算機的日期和時間的datetime2(7)值,SQL Server的實例正在該計算機上運行。日期和時間作為UTC時間(通用協調時間)返回
CURRENT_TIMESTAMP()
返回包含計算機的日期和時間的datetime2(7)值,SQL Server的實例正在該計算機上運行。時區偏移量未包含在內
GETDATE()
返回包含計算機的日期和時間的datetime2(7)值,SQL Server的實例正在該計算機上運行。時區偏移量未包含在內
GETUTCDATE()
返回包含計算機的日期和時間的datetime2(7)值,SQL Server的實例正在該計算機上運行。日期和時間作為UTC時間(世界標準時間)返回
【例23】使用日期和時間函數返回其他格式的日期時間:
SELECT SYSDATETIME() AS SYSDATETIME
,SYSDATETIMEOFFSET() AS SYSDATETIMEOFFSET
,SYSUTCDATETIME() AS SYSUTCDATETIME
,CURRENT_TIMESTAMP AS CURRENT_TIMESTAMP
,GETDATE() AS GETDATE
,GETUTCDATE() AS GETUTCDATE;
【例24】使用6個返回當前日期和時間的SQL Server系統函數,來返回當前系統的日期和時間:
SELECT 'SYSDATETIME() ', SYSDATETIME();
SELECT 'SYSDATETIMEOFFSET()', SYSDATETIMEOFFSET();
SELECT 'SYSUTCDATETIME() ', SYSUTCDATETIME();
SELECT 'CURRENT_TIMESTAMP ', CURRENT_TIMESTAMP;
SELECT 'GETDATE() ', GETDATE();
SELECT 'GETUTCDATE() ', GETUTCDATE();
(2) 用來獲取日期和時間部分的函數
用來獲取日期和時間部分的函數有DATENAME()、DATEPART()、DAY()、MONTH()和YEAR(),共5種函數,如表2-12所示。
表2-12 獲取日期和時間部分的函數
函 數
描 述
DATENAME(datepart, date)
返回表示指定日期的指定datepart的字符串
DATEPART(datepart, date)
返回表示指定date的指定datepart的整數
DAY(date)
返回表示指定date的“日”部分的整數
續表
函 數
描 述
MONTH(date)
返回表示指定date的“月”部分的整數
YEAR(date)
返回表示指定date的“年”部分的整數
【例25】返回指定日期:
SELECT DATENAME(datepart, '2007-10-30 12:15:32.1234567 +05:10')
【例26】使用YEAR()、MONTH()、DAY()函數返回年、月、日:
SELECT YEAR('2012-04-15T01:01:01.1234567-07:00')
SELECT MONTH('2012-04-15T01:01:01.1234567-07:00')
SELECT DAY('2012-04-15T01:01:01.1234567-07:00')
(3) 用來獲取日期和時間差的函數
用來獲取日期和時間差的函數只有DATEDIFF()函數。它的語法格式如下:
DATEDIFF(datepart, startdate, enddate)
該函數返回startdate和enddate之間所跨的日期或時間datepart邊界的數目。
【例27】計算一個表的兩列中的日期之間所跨越的日邊界數:
CREATE TABLE dbo.Duration
(
startDate datetime2, endDate datetime2
)
INSERT INTO dbo.Duration(startDate,endDate)
VALUES('2007-05-06 12:10:09','2007-05-07 12:10:09')
SELECT DATEDIFF(day,startDate,endDate) AS 'Duration'
FROM dbo.Duration;
(4) 用來修改日期和時間值的函數
修改日期和時間值的函數有DATEADD()、SWITCHOFFSET()、TODATETIMEOFF-SET(),共3種函數,如表2-13所示。
表2-13 修改日期和時間值的函數
函 數
描 述
DATEADD(datepart,
number, date)
將指定的number時間間隔(有符號整數)與指定的date的指定datepart相加后,返回該date
SWITCHOFFSET (DATETIMEOFFSET, time_zone)
SWITCHOFFSET更改DATETIMEOFFSET值的時區偏移量,并保留UTC值
TODATETIMEOFFSET(expression, time_zone)
TODATETIMEOFFSET將datetime2值轉換為datetimeoffset值。
datetime2值被解釋為指定time_zone的本地時間
【例28】將用戶定義的變量指定為number和date的參數:
DECLARE @days int;
DECLARE @datetime datetime;
SET @days = 365;
SET @datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */
SELECT DATEADD(day, @days, @datetime);
【例29】使用SWITCHOFFSET顯示與數據庫中所存儲的值不同的時區偏移量:
CREATE TABLE dbo.test
(
ColDatetimeoffset datetimeoffset
);
GO
INSERT INTO dbo.test
VALUES ('1998-09-20 7:45:50.71345 -5:00');
GO
SELECT SWITCHOFFSET (ColDatetimeoffset, '-08:00')
FROM dbo.test;
GO
SELECT ColDatetimeoffset
FROM dbo.test;
(5) 用來設置或獲取會話格式的函數
用來設置或獲取會話格式的函數包括@@DATEFIRST()、SET DATEFIRST()、SET DATEFORMAT、@@LANGUAGE、SET LANGUAGE、sp_helplanguage,共3種函數,如表2-14所示。
表2-14 設置或獲取會話格式的函數
函 數
描 述
@@DATEFIRST
返回對會話進行SET DATEFIRST操作所得結果的當前值
SET DATEFIRST {
number | @number_var }
將一周的第一天設置為1~7的一個數
SET DATEFORMAT {
format | @format_var }
設置用于輸入datetime或smalldatetime數據的日期各部分(月/日/年)的順序
@@LANGUAGE
返回當前使用的語言的名稱。@@LANGUAGE不是日期或時間函數。但是,語言設置會影響日期函數的輸出
SET LANGUAGE {
[N] ‘language’ | @language_var }
設置會話和系統消息的語言環境。SET LANGUAGE不是日期或時間函數。但是,語言設置會影響日期函數的輸出
sp_helplanguage [
[@language = ] ‘language’ ]
返回有關所有支持語言日期格式的信息。sp_helplanguage不是日期或時間存儲過程。但是,語言設置會影響日期函數的輸出
【例30】將每周的第一天設為5(星期五),并假定當天(Today)是星期六。該SELECT語句返回DATEFIRST值和當天是此周的第幾天。代碼如下:
SET DATEFIRST 5;
SELECT @@DATEFIRST AS 'First Day'
,DATEPART(dw, SYSDATETIME()) AS 'Today';
(6) 用來驗證日期和時間值的函數
用來驗證日期和時間值的函數只有ISDATE()。
其語法格式如下:
ISDATE(expression)
該函數用來確定datetime或smalldatetime輸入表達式是否為有效的日期或時間值。
【例31】使用ISDATE函數測試某一字符串是否是有效的datetime:
IF ISDATE('2009-05-12 10:19:41.177') = 1
PRINT 'VALID'
ELSE
PRINT 'INVALID'
4. 聚合函數
聚合函數對一組值執行計算,并返回單個值。所有聚合函數均為確定性函數。這表示任何時候使用一組特定的輸入值調用聚合函數,所返回的值都是相同的。一般情況下,若字段中含有空值,聚合函數會忽略,但COUNT除外。
聚合函數在下列位置可作為表達式使用:
* SELECT語句的選擇列表(子查詢或外部查詢)。
* COMPUTE或COMPUTE BY子句。
* HAVING子句。
T-SQL中的聚合函數有AVG、MIN、CHECKSUM、SUM、HECKSUM_AGG、STDEV、COUNT、STDEVP、COUNT_BIG、VAR、GROUPING、VARP、MAX。
表2-15分別對這些函數進行了介紹。
表2-15 聚合函數
函 數
描 述
AVG(
[ALL | DISTINCT] expression)
返回組中各值的平均值。空值將被忽略,后面可以跟OVER子句。
ALL:對所有的值進行聚合函數運算。ALL是默認值。
DISTINCT:指定AVG只在每個值的唯一實例上執行,而不管該值出現了多少次。
expression:是精確數值或近似數值數據類別(bit數據類型除外)的表達式。不允許使用聚合函數和子查詢
CHECKSUM
(* | expression[, ...n])
返回按照表的某一行或一組表達式計算出來的校驗和值。
CHECKSUM用于生成哈希索引。
*:指定對表的所有列進行計算。如果有任一列是非可比數據類型,則CHECKSUM返回錯誤。非可比數據類型為text、ntext、image 和cursor,也可以將上述任一類型作為基類型的sql_variant。
expression:除可比數據類型之外的任何類型的表達式 續表
函