變量
變量類型
SqlServer的變量分為兩種,分別是用戶自己定義的局部變量,用 “@” 開頭的標識符表示。第二種是系統定義和維護的全局變量,用 “@@” 開頭的標識符表示。
局部變量的作用范圍為定義局部變量的批處理、存儲過程、觸發器或語句塊,變量不能是 text、ntext 或 image 數據類型。
定義變量
定義局部變量的語法為:
DECLARE @局部變量名 數據類型[ ,…n]
局部變量在賦值之前默認為 NULL,如果在程序中引用它必須要先賦值。可以用 SET 語句給局部變量賦值,語法如下:
SET @局部變量名 = 變量值
也可以在查詢語句 SELECT 中給局部變量賦值,語法如下:
SELECT{@局部變量名 = 變量值}[,…n]
要輸出局部變量的值,可以使用 SELECT 語句。
SELECT @局部變量
流程控制語句
任何的程序都可以通過 3 種基本結構相互嵌套組成,分別是順序結構、選擇結構和循環結構。控制程序執行順序的語句稱為流程控制語句,T-SQL 提供了如下的流程控制語句,用於編寫過程性代碼的語法結構。
控制流語句 | 說明 |
---|---|
BEGIN…END | 程序塊語句 |
IF…ELSE | 條件處理語句 |
CASE | 分支語句 |
WHILE | 循環語句 |
GOTO | 無條件跳轉語句 |
RETURN | 無條件退出語句 |
WAITFOR | 延遲語句 |
BREAK | 跳出循環語句 |
CONTINUE | 跳出本次循環語句 |
BEGIN…END
順序結構按照語句的先后順序依次執行,無須使用專門的控制語句。有時候,為了區分不同的語句塊,可以采用復合語句的形式。即用 begin…end 括起來進行語句塊的界定,相當於 C 語言中的 “{}”,BEGIN 和 END 語句必須成對使用。
BEGIN
{
sql_statement | statement_block
}
END
IF…ELSE
選擇結構表示有不同的路徑,但需要根據一個條件來判斷執行哪條路徑。IF…ELSE 條件處理語句,實現編程中的分支結構。
IF Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]
CASE
多條件分支選擇 CASE 實現多分支選擇結構,類似於 C 語言的 Switch。CASE具有以下兩種格式,首先是簡單表達式,將某個表達式與一組簡單表達式進行比較以確定結果。
CASE input_expression
WHEN … THEN …
[ ...n ]
[ ELSE … ]
END
第二種是選擇表達式,計算一組布爾表達式以確定結果。
CASE
WHEN … THEN …
[ ...n ]
[ ELSE … ]
END
WHILE
循環就是重復執行的意思,有的語句需要反復執行才能結束,這就是循環語句。循環結構中必須含有循環語句。循環語句是 WHILE,語法為:
WHILE Boolean_expression --布爾表達式,進行條件判斷
{ sql_statement | statement_block }
[BREAK] --跳出本層循環
{ sql_statement | statement_block }
[CONTINUE] --跳出本次循環
{ sql_statement | statement_block }
WAITFOR
WAITFOR 語句的功能是,當程序執行到該語句時,暫時停止程序執行。直到所設定的等待時間已過或到了所設定的時間,才繼續向下執行程序。
WAITFOR {DELAY ‘延時時間’ | TIME ‘到達時間’}
編寫函數
SQL Server 允許用戶設計自己的函數,以補充和擴展系統提供(內置)函數的功能。用戶定義函數采用零或多個輸入參數並返回標量值或表,SQLServer 支持三種用戶定義函數。
標量函數
標量函數返回一個標量(單值)結果,可在與標量函數返回的數據類型相同的值所能使用的任何位置使用該標量函數。創建標量函數的語法是:
CREATE FUNCTION [ owner_name.] function_name
( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] )
RETURNS scalar_return_data_type
[ WITH < function_option> [ [,] ...n] ]
[ AS ]
BEGIN
function_body
RETURN scalar_expression
END
多語句表值函數
多語句表值函數返回一個由一條或多條 Transact-SQL 語句建立的表,類似於存儲過程。與存儲過程不同的是,多語句表值函數可以在 SELECT 語句的 FROM 子句中被引用。創建多語句表值函數的語法是:
CREATE FUNCTION [ owner_name.] function_name
( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] )
RETURNS TABLE
[ WITH < function_option > [ [,] ...n ] ]
[ AS ]
RETURN [ ( ] select-stmt [ ) ]
內嵌表值函數
內嵌表值函數返回一個單條 SELECT 語句產生的結果的表,類似於視圖。內嵌表值函數可使用參數,提供了更強的適應性,擴展了索引視圖的功能。創建內嵌表值函數的語法是:
CREATE FUNCTION [ owner_name.] function_name
( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] )
RETURNS @return_variable TABLE < table_type_definition >
[ WITH < function_option > [ [,] ...n ] ]
[ AS ]
BEGIN
function_body
RETURN
END
< function_option > ::=
{ ENCRYPTION | SCHEMABINDING }
< table_type_definition > ::=
( { column_definition | table_constraint } [ ,...n ] )
編寫函數樣例
樣例一
編寫函數Fmax,求二數大者。
CREATE FUNCTION Fmax (@x int,@y int)
RETURNS int
AS
BEGIN
DECLARE @Z INT
IF @X>@Y
SET @Z=@X
ELSE
SET @Z=@Y
RETURN(@Z)
END
SELECT DBO.fMAX(1,2)
樣例二
編寫函數Fc,參數為兩個整數和一個運算符(+,-,*,/),計算其結果。
CREATE FUNCTION FC (@x int,@y int,@C CHAR)
RETURNS int
AS
BEGIN
DECLARE @Z INT
SET @Z = CASE @C
WHEN '+' THEN @X+@Y
WHEN '-' THEN @X-@Y
WHEN '*' THEN @X*@Y
WHEN '/' THEN @X/@Y
END
RETURN(@Z)
END
SELECT DBO.fC(1,2,'+')
樣例三
編寫函數 Fsum 對自然數列 1 ~ n(參數)求和。
CREATE FUNCTION Fsum(@n INT)
RETURNS int AS
BEGIN
DECLARE @sum INT, @i INT
SET @sum = 0
SET @i = 1
WHILE @i <= @n
BEGIN
SET @sum = @sum + @i
SET @i = 1 + @i
END
RETURN(@sum)
END
SELECT DBO.Fsum(100)
樣例四
Student 表、Score 表和 Course 表中有如下一些數據。
編寫函數 Fs,參數為姓名和課程名,返回該生該課程的成績。
CREATE FUNCTION FS (@xM NCHAR(4),@KCM VARCHAR(20))
RETURNS DECIMAL(4,1)
AS
BEGIN
DECLARE @Z DECIMAL(4,1)
SELECT @Z = DEGREE
FROM Student S
JOIN Score SC ON SC.SNO=S.SNO
JOIN Course C ON C.CNO=SC.CNO
WHERE SNAME = @XM AND CNAME = @KCM
RETURN(@Z)
END
SELECT DBO.fS('李君帥', '計算機導論')
樣例五
編寫函數 Fsc,參數為姓名,返回該生的所有成績。
CREATE FUNCTION Fsc(@XM Nchar(4))
RETURNS TABLE
AS
RETURN (
SELECT SNAME,CNAME,DEGREE
FROM Student S
JOIN Score SC ON SC.SNO = S.SNO
JOIN Course C ON C.CNO = SC.CNO
WHERE SNAME = @XM
)
SELECT * FROM DBO.Fsc('李君帥')
樣例六
編寫函數 FRANK,參數為學號,返回該生平均分班級排名。
CREATE FUNCTION FRANK(@sno char(3))
RETURNS int
AS
BEGIN
DECLARE @rank INT
DECLARE @class CHAR(5)
SET @class = (SELECT class FROM Student WHERE Sno = @sno)
SET @rank = (
SELECT a_rank
FROM (
SELECT row_number() OVER(ORDER BY AVG(Degree) DESC) a_rank, S.Sno
FROM Score SC
JOIN Student S ON S.Sno = SC.Sno
WHERE Class = @class
GROUP BY s.sno
) T
WHERE T.Sno = @sno
)
RETURN @rank
END
SELECT DBO.FRANK(101)
樣例七
編寫函數 FCJA,參數為姓名或姓名一部分,返回該生的所有課程的成績(學號,姓名,課程名,成績等級)。選修成績等級 A:90~100 B:80~90 C: 70~80 D:60~70 E:<60。
CREATE FUNCTION FCJA(@sname nvarchar(4))
RETURNS TABLE AS
RETURN(
SELECT SC.Sno, Sname, Cname, Degree,
CASE
WHEN Degree < 60 THEN 'A'
WHEN Degree >= 60 AND Degree < 70 THEN 'B'
WHEN Degree >= 70 AND Degree < 80 THEN 'C'
WHEN Degree >= 80 AND Degree < 90 THEN 'D'
WHEN Degree >= 90 AND Degree <= 100 THEN 'E'
ELSE 'N'
END 等級
FROM Score SC
JOIN Student S ON SC.Sno = S.Sno
JOIN Course C ON C.Cno = SC.Cno
WHERE Sname like '%'+ @sname +'%'
)
SELECT * FROM FCJA('李君')
參考資料
《SqlServer 2014 數據庫技術實用教程》,胡伏湘、肖玉朝 主編,清華大學出版社