SQL語句只能按照既定的順序執行,在執行過程當中不能根據某些中間結果有選擇地或循環地執行某些語句塊,不能像高級程序語言那樣進行流程控制。爲此,微軟公司在SQL語言的基礎上添加了流程控制語句,從而獲得一種結構化程序設計語言——Transact-SQL。程序員
Transact-SQL即事務SQL,也簡寫爲T-SQL,它是微軟公司對關係數據庫標準語言SQL進行擴充的結果,是SQL語言的超集。Transact-SQL支持全部的標準SQL語言操做。sql
做爲一種標準的關係數據庫語言,SQL幾乎能夠在全部的關係數據庫上使用。但因爲Transact-SQL是微軟對SQL擴充的結果,因此只有SQL Server支持Transact-SQL,而其餘關係數據庫(如Access、Oracle等)卻不支持Transact-SQL。SQL Server已經在市場中佔據了主導地位,特別是隨着SQL Server 版本的不斷翻新,加上微軟公司的強力支撐,SQL Server的主導地位將進一步獲得增強。不管是數據庫管理員仍是數據庫應用程序開發人員,要想深刻領會和掌握數據庫技術,必須認真學習Transact-SQL。除了擁有SQL語言全部的功能外,Transact-SQL還具有對SQL Server數據庫獨特的管理功能。數據庫
1. 標識符express
在數據庫編程中,要訪問任何一個邏輯對象(如變量、過程、觸發器等)都須要經過其名稱來完成。邏輯對象的名稱是利用合法的標識符來表示的,是在建立、定義對象時設置的,此後就能夠經過名稱來引用邏輯對象。編程
2. 數據類型安全
與其餘編程語言同樣,Transact-SQL語言也有本身的數據類型。數據類型在定義數據對象(如列、變量和參數等)時是必須的。自SQL Server 2008版本開始就新增了XML數據類型,以用於保存XML數據。Transact-SQL語言的其餘數據類型與SQL的相同。架構
3. 函數編程語言
SQL Server 2008內置了大量的函數,如時間函數、統計函數、遊標函數等,極大地方便程序員的使用。ide
4. 表達式函數
表達式是由表示常量、變量、函數等的標識符經過運算符鏈接而成的、具備實際計算意義的合法字符串。有的表達式不必定含有運算符,實際上單個的常量、變量等均可以視爲一個表達式,它們每每不含有運算符。
5. 註釋
Transact-SQL語言中有兩種註釋,一種是行單行註釋,一種是多行註釋。它們分別用符號「--」(連續的兩個減號)和「/* */」來實現。
6. 關鍵字
關鍵字也稱爲保留字,是SQL Server預留做專門用途的一類標識符。例如,ADD、EXCEPT、PERCENT等都是保留關鍵字。用戶定義的標識符不能與保留關鍵字重複。
標識符有兩種類型:常規標識符和分隔標識符。
常規標識符在使用時不需將其分隔開,要符合標識符的格式規則。
這些規則就是,標識符中的首字符必須是英文字母、數字、_(下劃線)、@、#或漢字,
首字符後面能夠是字母、數字、下劃線、@和$等字符,能夠包含漢字。
標識符通常不能與SQL Server的關鍵字重複,
也不該以@@開頭(由於系統全局變量的標識符是以@@開頭),
不容許嵌入空格或其餘特殊字符等。
分隔標識符是指包含在兩個單引號(' ') 或者方括號([ ]) 內的字符串,這些字符串中能夠包含空格。
在SQL Server中,全局變量是以@@開頭,後跟相應的字符串,如@@VERSION等。若是想查看全局變量的值,可用SELECT語句或print語句來完成。
查看全局變量的值@@VERSION的值,相應的print語句以下:
print @@VERSION;
該語句執行後在筆者機器上輸出以下結果:
Microsoft SQL Server 2014 - 12.0.4100.1 (X64)
Apr 20 2015 17:29:27
Copyright (c) Microsoft Corporation
Standard Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
(1)定義局部變量
局部變量是由用戶定義的,語法以下:
DECLARE @variable1 data_type[,variable2 data_type, …]
@variable1, @variable2,…爲局部變量名,它們必須以單字符「@」開頭;data_type爲數據類型,它是能夠是系統數據類型,也能夠是用戶定義的數據類型,具體選擇什麼樣的類型要根據實際須要而定。有關數據類型的說明見第4章的相關內容。
【例6.1】定義一個用於存儲姓名的局部變量。
DECLARE @name_str varchar(8);
【例6.2】同時定義三個分別用於存儲學號、出生日期和平均成績的局部變量。
DECLARE @no_str varchar(8), @birthday_str smalldatetime, @avgrade_num numeric(3,1);
(2)使用SET對局部變量賦初值
在定義局部變量之後,變量自動被賦以空值(NULL)。若是須要對已經定義的局部變量賦一個初值,可用SET語句來實現,其語法以下:
SET @variable = value;
@variable爲局部變量名,value爲新賦的值。
【例6.3】對上例定義的三個變量@no_str、@birthday_str和@avgrade_num分別賦初值'20170112'、'2000-2-5'和89.8。
這個賦值操做能夠下三個SET語句來完成:
SET @no_str='20170112'; SET @birthday_str='2000-2-5'; SET @avgrade_num = 89.8;
注意,不能同時對多個變量進行賦值,這與同時對多個變量進行定義的狀況不一樣
【例子】下列的SET語句是錯誤的:
SET @no_str='20170112', @birthday_str='2000-2-5', @avgrade_num = 89.8; -- 錯誤
(3)使用SELECT對局部變量賦初值
SELECT是查詢語句,利用該語句能夠將查詢的結果賦給相應的局部變量。若是查詢返回的結果包含多個值,則將最後一個值賦給局部變量。
使用SELECT對局部變量賦初值的語法格式以下:
SELECT @variable1= value1[, @variable2= value2, …] FROM table_name [WHERE …]
【例6.4】 查詢表student,將姓名爲「劉洋」的學生的學號、出生日期和平均成績分別賦給局部變量@no_str、@birthday_str和@avgrade_num。
該賦值操做用SELECT語句來實現則很是方便,其代碼以下:
SELECT @no_str = s_no, @birthday_str = s_birthday, @avgrade_num = s_avgrade FROM student WHERE s_name = '劉洋';
【例6.5】先定義局部變量@s_no和@s_avgrade,而後對其賦值,最後利用這兩個變量修改數據表student的相關信息。
USE MyDatabase GO -- 定義局部變量 DECLARE @s_no varchar(8), @s_avgrade numeric(3,1); -- 對局部變量賦值 SET @s_no='20170208'; SET @s_avgrade = 95.0; -- 使用局部變量 Update student SET s_avgrade = @s_avgrade WHERE s_no = @s_no;
字符串常量是由兩個單引號來定義的,是包含在兩個單引號內的字符序列。
這些字符包括字母數字字符(a-z、A-Z 和0-9)以及特殊字符,如感嘆號(!)、at 符(@) 和數字號(#)等。
默認狀況下,SQL Server 2014爲字符串常量分配當前數據庫的默認排序規則,
但也能夠用COLLATE 子句爲其指定排序規則。
【例子】下列都是合法字符串常量:
'China' '中國人民共和國'
若是字符串中包含一個嵌入的單引號,則須要在該單引號前再加上一個單引號,表示轉義,這樣才能定義包含單引號的字符串。
【例子】下列包含單引號的字符串都是合法的:
'AbC''Dd!' -- 表示字符串「AbC'Dd!」 'xx: 20%y%.'
有許多程序員習慣用雙引號來定義字符串常量。但在默認狀況下,SQL Server不容許使用這樣的定義方式。
若是將QUOTED_IDENTIFIER 選項設置爲OFF,則SQL Server同時支持運用雙引號和單引號來定義字符串。
設置QUOTED_IDENTIFIER的方法用下列語句:
SET QUOTED_IDENTIFIER OFF;
在執行該語句後,QUOTED_IDENTIFIER 被設置爲OFF。這時除了單引號之外,還能夠用雙引號來定義字符串。
【例子】下列定義的字符串都是合法的:
'China' '中國人民共和國' 'AbC''Dd!' -- 表示字符串「AbC'Dd!」 'xx: 20%y%.' "China" "中國人民共和國" "AbC''Dd!" -- 表示字符串「AbC''Dd!」 "xx: 20%y%."
注意,當用雙引號定義字符串時,若是該字符串中包含單引號,則不能在單引號前再加上另外一個單引號,不然將獲得另外的一種字符串。
【例子】 'AbC''Dd!'定義的是字符串「AbC'Dd!」,而"AbC''Dd!"定義則是字符串「AbC''Dd!」。
SQL Server將空字符串解釋爲單個空格。
若是不須要用雙引號來定義字符串,則只要將QUOTED_IDENTIFIER恢復爲默認值ON便可。須要執行下列語句:
SET QUOTED_IDENTIFIER ON;
SQL Server 2014支持Unicode字符串。Unicode字符串是指按照Unicode標準來存儲的字符串。但在形式上與普通字符串類似,不一樣的是它前面有一個N 標識符(N 表明SQL-92 標準中的區域語言),且前綴N必須是大寫字母。
【例子】 'China'是普通的字符串常量,而N'China'則是Unicode字符串常量。
整型常量也用得不少,它是不用引號括起來且不包含小數點的數字字符串。
【例子】 200七、-14等都是整型常量。
【例子】下面是定義整型常量及對其賦值的例子:
DECLARE @i integer SET @i = 99;
日期時間常量一般是用字符串常量來表示,
但前提是字符串常量可以隱式轉換爲日期時間型數據,
其格式爲「yyyy-mm-dd hh:mm:ss.nnn」或「yyyy/mm/dd hh:mm:ss.nnn」,
其中yyyy表示年份,第一個mm表示月份,dd表示月份中的日期,
hh表示小時,第二個mm表示分鐘,ss表示秒,nnn表示毫秒。
若是「yyyy-mm-dd」缺省,則日期部分默認爲1900年01月01日;
若是「hh:mm:ss.nnn」缺省,則時間部分默認爲00時00分00.000秒。
【例子】下面是一些將日期時間型常量賦給日期時間型變量的例子:
DECLARE @dt datetime SET @dt = '2017-01-03 21:55:56.890' --2017年01月03日21時55分56.890秒 SET @dt = '2017/12/03' --2017年01月03日0時0分0秒 SET @dt = '2017-01-03' --2017年01月03日0時0分0秒 SET @dt = '21:55:56.890' --1900年01月01日21時55分56.890秒
二進制常量是用前綴爲0x的十六進制數字的字符串來表示,但這些字符串不用須要使用單引號括起。
【例子】下列是將二進制常量賦給二進制變量的例子:
DECLARE @bi binary(50) SET @bi = 0xAE SET @bi = 0x12Ef SET @bi = 0x69048AEFDD010E SET @bi = 0x0
數值型常量包括三種類型:decimal型常量、float型常量和real型常量。
decimal型常量是包含小數點的數字字符串,但這些字符串不需單引號括起來(定點表示)。
【例子】下面是decimal型常量的例子:
3.14159
-1.0
float型常量和real型常量都是使用科學記數法來表示(浮點表示)。
【例子】
101.5E5
-0.5E-2
位常量使用數字0或1來表示,而且不用單引號括起來。若是使用一個大於1的數字,則該數字將轉換爲1。
【例子】
DECLARE @b bit SET @b = 0;
貨幣常量是前綴爲可選的小數點和可選的貨幣符號的數字字符串,且不用單引號括起來。SQL Server 2008不強制採用任何種類的分組規則,例如在表明貨幣的字符串中不容許每隔三個數字用一個逗號隔開。
【例子】 如下是貨幣常量的例子:
$20000.2 -- 而$20,000.2是錯誤的貨幣常量 $200
這是指uniqueidentifier類型的常量,它使用字符或二進制字符串格式來指定。
【例子】
'6F9619FF-8B86-D011-B42D-00C04FC964FF’ 0xff19966f868b11d0b42d00c04fc964ff
以上介紹的八種類型的常量主要運用於對變量和字段賦值、構造表達式、構造子句等。在從此的介紹中將進一步領會到它的使用方法。
SQL Server 2014中,字符串型數據能夠由漢字、英文字母、數字等符號組成。根據編碼方式的不一樣,字符串型又分爲Unicode字符串型和非Unicode字符串型。
Unicode字符串型數據是指對全部字符均採用雙字(16bit)節統一編碼的一類數據;
非Unicode字符串型數據則是指對不一樣國家或地區採用不一樣編碼長度的一類數據,例如英文字母使用一個字節(8bit)進行編碼,漢字則使用兩個字節(16bit)進行編碼。
SQL Server 2014主要支持的字符串型數據類型如表5.2所示。
按照不一樣的精確程度,將數值型數據類型分爲兩種,一種是精確型,另外一種是近似型。
精確型數據是指在計算機中能夠精確存儲的數據。這種數據類型包括各類整型數據類型、定點型數據類型等,
表5.3列出了SQL Server 2014支持的精確型數據類型。
近似型主要是指浮點型float和real。這種類型的數據在內存中不必定可以精確表示,可能會存在一些微小的偏差。
日期時間型,包括兩種:datetime和smalldatetiime。日期時間型既能夠用於存儲時間型數據,也能夠用於存儲日期型數據。
自從SQL Server 2012開始,新增了4種與日期時間相關的新數據類型:datetime二、dateoffset、date和time。
貨幣型是用來存儲貨幣值數據,它固定精確到小數點後四位,至關於numeric(m,n)類型的特例(n=4)。SQL Server支持兩種貨幣型。
二進制型數據類型包括三種:binary(n)、varbinary(n)和image。其做用和含義說明如表5.7所示。
SQL Server 2014還支持如下的數據類型:
sql_variant:一種通用數據類型,存儲除了text、ntext、image、timestamp和它自身之外的其餘類型的數據,其最大存儲量爲8000字節。
timestamp:時間戳類型,每次更新時會自動更新該類型的數據。做用跟郵局的郵戳相似,一般用於證實某一項活動(操做)是在某一時刻完成的。
uniqueidentitier:全局惟一標識符(GUID),其值能夠從Newsequentialid()函數得到,這個函數返回的值對全部計算機來講是惟一的。
xml:做爲一種存儲格式,xml類型具備SQL Server中其餘類型的全部功能,還能夠添加子樹、刪除子樹和更新標量值等,最多存儲2GB數據。
table:表類型,用於返回表值函數的結果集,其大小取決於表中的列數和行數。
hierarchyid:層次類型,包含對層次結構中位置的引用,佔用空間爲1至892字節+2字節的額外開銷。
cursor:遊標類型,包含對遊標的引用,只能用做變量或存儲過程參數,不能用於Create Table語句中。
根據實際須要,用戶可利用已有的標準數據類型來定義本身的數據類型,這種類型稱爲自定義數據類型。自定義數據類型可由CREATE TYPE語句來定義。
【例子】 用戶能夠用下列語句建立表示地址的數據類型——address:
CREATE TYPE address FROM varchar(350) NOT NULL;
執行上述語句後,就生成了名爲address的數據類型,同時增長了約束條件——NOT NULL。就能夠用address去定義字段和變量。該數據類型就是與varchar(350)同等,只不過它增長了一個非空約束條件。
再也不須要數據類型address,能夠用下列語句將之刪除:
DROP TYPE address;
但在刪除以前,先刪除全部引用該數據類型的數據庫對象。
在Transact-SQL程序中經常使用的系統內置函數能夠分爲四種類型:字符串處理函數、聚合函數、時間函數和數學函數。
(1)ASCII函數
該函數的語法以下:
ASCII ( character_expression )
character_expression爲char或varchar類型的字符串表達式。其做用是以int類型返回字符串表達式character_expression中第一個字符的ASCII值。
【例子】 ASCII ('Abcd')返回65,ASCII ('abcd')返回97等('A'和'a'的ASCII值分別爲65和97)。
(2)SUBSTRING函數
該函數的語法以下:
SUBSTRING( expression ,start , length )
該函數的做用是返回給定字符expression中的一個子串,該子串是從位置start開始、長度爲length的字符串。其中,expression能夠是字符串、二進制字符串、文本、圖像、列或包含列的表達式,但不能使用包含聚合函數的表達式,start , length都是整型數據。
【例子】 SU BSTRING('abcdef',2, 4)返回'bcde',SUBSTRING('abcdef',2, 1)返回'b'等。
(3)LEFT函數
該函數的語法以下:
LEFT(character_expression, integer_expression)
其做用是返回字符串character_expression中從左邊開始的integer_expression個字符。
【例子】 打印學生的姓氏,能夠用下列的語句來實現(不考慮複姓):
SELECT LEFT(s_name,1) FROM student
(4)REPLACE函數
該函數的語法以下:
REPLACE(string_expression1 , string_expression2, string_expression3)
其做用是用第三個表達式string_expression3替換第一個字符串表達式string_expression1中出現的全部第二個指定字符串表達式string_expression2的匹配項,並返回替換後的字符串表達式。
【例子】 REPLACE('abcdefghicde','cd','China')將返回'abChinaefghiChinae'。
(1)COUNT函數
該函數用於返回組中的項數,其語法以下:
COUNT({[[ALL|DISTINCT] expression]|*})
該函數有三種調用形式:
COUNT(*):返回組中的行數,包括NULL值和重複行。
COUNT(ALL expression):對組中的每一行都計算expression並返回非NULL值的個數,式中的ALL能夠省略。
COUNT(DISTINCT expression):對組中的每一行都計算expression並返回惟一非空值的個數。
(2)AVG函數
該函數返回組中各值的平均值,NULL被忽略。其語法以下:
AVG( [ ALL | DISTINCT ] expression )
【例子】 求女學生的平均成績,能夠用下列的語句來完成:
SELECT AVG(s_avgrade) FROM student WHERE s_sex = '女'
(3)MAX函數
該函數的語法格式以下:
MAX([ ALL | DISTINCT ] expression )
它返回表達式的最大值
(4)MIN函數
該函數的語法格式以下:
MIN([ ALL | DISTINCT ] expression )
它返回表達式的最小值。
(5)SUM函數
該函數的語法格式以下:
SUM([ ALL | DISTINCT ] expression )
當選擇ALL(默認)時,它返回表達式expression中全部值的和;當選擇DISTINCT時,它返回僅非重複值的和。NULL值被忽略。
經常使用的日期時間函數說明如表6.6所示。
數學函數用於對數值型字段和表達式進行處理,經常使用的函數如表6.7所示。
(1)CAST函數
該函數用於將一種數據類型的表達式顯式轉換爲另外一種數據類型的表達式。其語法以下:
CAST(expression AS data_type [(length )])
即將表達式expression的值轉換爲data_type類型的數據,並返回轉化後的數據類型。常使用的類型轉換主要包括如下幾種:
數值型 <-> 字符串型
字符串型 <-> 日期時間型
【例子】
CAST(10.6496 AS int) -- 將常量10.6496轉化int類型數據,結果變爲10 CAST('abc' AS varchar(5)) -- 將常量'abc'轉化爲varchar(5)類型 CAST('100' AS int) -- 將字符串常量'100'轉化爲數值常量100 CAST(100 AS varchar(5)) -- 將數值常量100轉化字符串常量'100' CAST('2017/12/12' AS datetime) -- 將字符串常量'2017/12/12'轉化爲時間常量12 12 2017 CAST(GETDATE() AS VARCHAR(20)) -- 將當前系統時間轉化爲字符串常量
查詢成績在70到80(不含80)分之間的學生,能夠用下列的語句實現:
SELECT * FROM student WHERE CAST(s_avgrade AS varchar(10)) like '7%'
該語句首先將成績轉換爲字符串,而後將70到80之間的分數看做是以7開頭的字符串,最後經過利用模糊查詢來實現該查詢功能。它等價於下列的SELECT語句:
SELECT * FROM student WHERE s_avgrade >= 70 and s_avgrade < 80
(2)CONVERT函數
該函數與CAST函數的功能類似,都是用於將一種數據類型的表達式顯式轉換爲另外一種數據類型的表達式,但CONVERT函數的功能更強一些。其語法以下:
CONVERT( data_type [ ( length ) ] , expression [ , style ] )
與CAST函數不一樣的是,在CONVERT函數中被轉換的表達式靠近函數式的右邊,而在CONVERT函數中則靠近左邊。
【例子】下列語句中使用了CONVERT函數,該語句與上述查詢語句等價:
SELECT * FROM student WHERE CONVERT(varchar(10), s_avgrade) like '7%'
用戶自定義函數由CREATE FUNCTION語句來定義,分爲如下幾種類型。
(1)標量函數的定義和引用
標量函數是指返回值爲標量值的函數。其語法格式以下:
CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type [ = default ] } [ ,...n ] ] ) RETURNS return_data_type [ WITH <function_option> [ ,...n ] ] [ AS ] BEGIN function_body RETURN scalar_expression END [ ; ] <function_option>::= { [ ENCRYPTION ] | [ SCHEMABINDING ] | [ RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT ] | [ EXECUTE_AS_Clause ] }
其中:
schema_name爲架構名稱。
function_name爲用戶定義的函數名,它必須符合SQL Server標識符的規則,在架構schema_name中是惟一的。
@parameter_name爲用戶定義的形式參數的名稱,能夠聲明一個或者多個參數,parameter_data_type爲參數的類型。
function_body表示函數體,即Transact-SQL語句塊,是函數的主體部分。
在<function_option>項中,ENCRYPTION用於指示數據庫引擎對包含CREATE FUNCTION語句文本的目錄視圖列進行加密,以防止將函數做爲SQL Server複製的一部分發布;SCHEMABINDING指定將函數綁定到其引用的數據庫對象,若是其餘架構綁定對象也在引用該函數,此條件將防止對其進行更改。
若是定義了 default 值,則無需指定此參數的值便可執行函數。
EXECUTE AS 子句用於指定用於執行用戶定義函數的安全上下文。
【例6.15】 構造一個函數,使之可以根據學號從表SC中計算學生已選課程的平均成績。
USE MyDatabase; GO IF OBJECT_ID(N'dbo.get_avgrade', N'FN') IS NOT NULL DROP FUNCTION dbo.get_avgrade; -- 若是已存在名爲get_avgrade的函數則將其刪除 GO CREATE FUNCTION dbo.get_avgrade(@s_no varchar(8)) RETURNS float AS BEGIN DECLARE @value float; SELECT @value = AVG(c_grade) FROM sc WHERE s_no = @s_no RETURN @value; END
對於用戶自定義函數,其調用方法與變量的引用方式同樣,主要有如下幾種調用格式。
①在SELECT或者PRINT語句中調用函數
【例子】 能夠用下列語句調用自定義函數get_avgrade:
DECLARE @SS varchar(8); SET @SS = '20170202' SELECT dbo.get_avgrade(@SS) --或者, SELECT dbo.get_avgrade('20170202') --若是僅僅用於打印輸出,能夠將上述的關鍵字SELECT改成PRINT,也有一樣的效果。
② 利用SET語句執行函數
在SET語句中,函數被看成一個表達式進行計算,而後將返回值賦給指定的變量。
【例子】
DECLARE @V float SET @V = dbo.get_avgrade('20170202')
(2)內聯表值函數
內聯表值函數返回的結果是一張數據表,而不是一個標量值。其語法以下:
CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] } [ ,...n ] ] ) RETURNS TABLE [ WITH <function_option> [ ,...n ] ] [ AS ] RETURN [ ( ] select_stmt [ ) ] [ ; ]
能夠看到,該函數返回結果是TABLE類型數據(是一張表),且沒有函數主體(BEGIN…END部分),而標量函數返回的是一個標量值,有本身的函數主體。
【例子】 定義內聯表值函數。該函數的做用是按學號查詢學生的學號、姓名和系別,其輸入參數是學號,返回結果是由學號、姓名和系別構成的表。
USE MyDatabase; GO IF OBJECT_ID(N'dbo.get_SND', N'IF') IS NOT NULL DROP FUNCTION dbo.get_SND; GO CREATE FUNCTION dbo.get_SND(@s_no varchar(8)) RETURNS TABLE AS RETURN ( SELECT s_no, s_name, s_dept FROM student WHERE s_no = @s_no );
因爲內聯表值函數返回結果是一張表,因此對其調用必須按照對錶的查詢方式進行,其調用方法與標量函數的調用方法徹底不一樣。
【例子】 如下是調用函數get_SND的一條SELECT語句,在此函數get_SND是被看成一張表來使用的:
SELECT * FROM dbo.get_SND('20170203')
內聯表值函數返回的結果是一張「數據表」,而其自己並不保存數據。在這個意義上,內聯表值函數與第8章介紹的視圖是同樣的,並且也能夠像對視圖那樣對其進行查詢操做。其優勢是它能夠帶參數,而視圖不能帶參數,但它不具有視圖的所有功能。能夠這樣簡要理解:內聯表值函數是帶參數的「視圖」。
(3)多語句表值函數
多語句表值函數返回結果也是一張表,但與內聯表值函數不一樣的是:在內聯表值函數中,TABLE返回值是經過單個SELECT語句定義的,內聯函數沒有關聯的返回變量。
在多語句表值函數中,@return_variable是TABLE類型的返回變量,用於存儲和彙總應做爲函數值返回的行。
多語句表值函數返回結果的原理是,先定義一個表變量,而後經過函數體中的語句實現向該表變量插入有關數據,最後將這個表變量做爲結果返回。
多語句表值函數的語法以下:
CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] } [ ,...n ] ] ) RETURNS @return_variable TABLE < table_type_definition > [ WITH <function_option> [ ,...n ] ] [ AS ] BEGIN function_body RETURN END [ ; ]
@return_variable爲TABLE類型變量,用於存放函數返回的表。
多語句表值函數與標量函數都有函數的主體部分(function_body),它是由一系列定義函數值的Transact-SQL語句組成。在多語句表值函數中,function_body是一系列用於填充TABLE返回變量@return_variable的Transact-SQL 語句;在標量函數中,function_body是一系列用於計算標量值的Transact-SQL 語句。
【例6.16】 下例是一個多語句表值函數,其做用是按學號查詢學生的一些基本信息。這些信息包括學號、姓名、專業、系別和平均成績,其平均成績是計算列,它由學生已選修的課程及課程成績來決定。學生選修課程記錄於表SC中。
該函數名爲get_stu_info,帶一個參數,其定義代碼以下:
USE MyDatabase; GO IF OBJECT_ID (N'dbo.get_stu_info', N'TF') IS NOT NULL DROP FUNCTION dbo.get_stu_info; GO CREATE FUNCTION dbo.get_stu_info(@no char(8)) RETURNS @stu_info TABLE -- 定義表變量 ( s_no char(8), s_name char(8), s_speciality varchar(50), s_dept varchar(50), s_avgrade numeric(3,1) ) AS BEGIN INSERT @stu_info -- 插入查詢信息 SELECT s_no,s_name,s_speciality,s_dept,s_avgrade=( /*從表SC中生成計算列s_avgrade */ SELECT AVG(c_grade) FROM SC WHERE SC.s_no = student.s_no ) FROM student WHERE s_no=@no RETURN END
多語句表值函數的調用與內聯表值函數的調用方法同樣。
【例子】要查詢學號爲'20170201'的學生信息,能夠按照下列方式調用函數get_stu_info:
SELECT * FROM dbo.get_stu_info('20170201');
用戶自定義函數的刪除實際上在上述介紹的例子中已經接觸過了,即用DROP FUNCTION來實現對函數的刪除。
【例子】 刪除函數get_stu_info可使用下列語句來完成:
DROP FUNCTION dbo.get_stu_info;
運算符是用來指定要在一個或多個表達式中執行操做的一種符號。在SQL Server 2014中,使用的運算符包括算術運算符、邏輯運算符、賦值運算符、字符串串聯運算符、按位運算符、一元運算符和比較運算符等。
1. 算術運算符
算術運算符加(+)、減(-)、乘(*)、除(/)和取模(%)等五種運算符。它們用於執行對兩個表達式的運算,這兩個表達式的返回值必須是數值數據類型,包括貨幣型。
加(+) 和減(-) 運算符還能夠用於對日期時間類型值的算術運算。
2. 邏輯運算符
邏輯運算符用於對某些條件進行測試,返回值爲TRUE或FALSE。邏輯運算符包括ALL、AND、ANY、BETWEEN、EXISTS、IN、LIKE、NOT、OR、SOME等,其含義說明如表6.2所示,其中有部分運算符已在第5章中介紹過。
3. 賦值運算符
賦值運算符就是等號「=」,它是Transact-SQL中惟一的賦值運算符。例如,上節對局部變量的賦值操做實際上已經使用了賦值運算符。
除了用做賦值操做之外,賦值運算符還能夠用於創建字段標題和定義字段值的表達式之間的關係。
【例子】 下列語句建立了兩個字段,其中第一個字段的列標題爲「中國」,全部字段值均爲「China」;第二個字段的列標題爲「姓名」,該字段的字段值來自表student中的s_name字段值。
SELECT 中國= 'China', 姓名= s_name FROM student
執行結果以下:
中國 姓名
--------------------------
China 劉洋
China 王曉珂
China 王偉志
China 嶽志強
China 賈簿
China 李思思
China 蒙恬
China 張宇
4. 字符串鏈接運算符
在SQL Server中,字符串鏈接運算符爲加號「+」,表示要將兩個字符串鏈接起來而造成一個新的字符串。該運算符能夠操做的字符串類型包括char、varchar、text以及nchar、nvarchar、ntext等。
【例子】
'abc'+'defg' -- 結果爲'abcdefg' ‘abc’ + ‘’ + ‘def’ -- 結果爲‘abcdef’(默認),當兼容級別設置爲65時結果爲 'abc def'
針對字符串的操做有不少種,如取子串等。但在SQL Server中僅有字符串鏈接操做由運算符「+」來完成,而全部其餘的字符串操做都使用字符串函數來進行處理。
5. 位運算符
位運算符是表示在兩個操做數之間執行按位進行運算的符號,操做數必須爲整型數據類型之一,如bit、tinyint、smallint、int、bigint等,還能夠是二進制數據類型(image 數據類型除外)。表6.3列出了位運算符及其含義。
6. 比較運算符
比較運算符用於測試兩個表達式的值之間的關係,這種關係是指等於、大於、小於、大於等於、小於等於、不等於、不小於、不大於等。比較運算符幾乎適用於全部的表達式(除了text、ntext 或image 數據類型的表達式外)。表6.4列出了Transact-SQL 支持的比較運算符。
7. 運算符的優先級
運算符執行順序的不一樣會致使不一樣的運算結果,因此正確地理解運算符的優先級是必要的。圖6.1給出了運算符優優先級的示意圖,其中從上到下運算符的優先級是由高到低,同一級中運算符的優先級是按照它們在表達式中的順序從左到右依次下降。
註釋是Transact-SQL程序代碼中不被執行的文本部分,其做用是說明程序各模塊的功能和設計思想,以方便程序的修改和維護。
註釋有兩種方法,一種是用「--」(緊連的兩個減號)來註釋,另外一種是用「/**/」來註釋,它們都稱爲註釋符。其中:
• --:用於註釋一行代碼,被註釋的部分是從註釋符「--」開始一直到其所在行末尾的部分。
• /* */:用於註釋多行代碼,被註釋的部分包含在兩個星號的中間。
【例子】 下面一段代碼中同時使用了這兩種註釋:
USE MyDatabase; -- 使用數據庫MyDatabase GO /* 該程序用於查詢成績及格的學生信息,包括學生姓名、性別、平均成績。 程序編寫者:xxx 程序編寫時間:2017年12月31日 */ SELECT s_name, s_sex, s_avgrade --姓名、性別、平均成績 FROM student --在表中查詢 GO