T-SQL語言分類和變數,運算符及示例,控制語句(begin,if else,case,while,waitfor,return,goto,try catch),常用函數的數據類型轉換函數cast()和convert()的異同 ...
目錄
1.使用Transact-SQL語言編程
儘管SQL Server 2008提供了圖形化界面,但只有一種Transact-SQL語言能夠直接與資料庫引擎進行交互。根據執行功能特點可以將Transact-SQL語言分成3大類:數據定義語言DDL,數據操縱語言DML,數據控制語言DCL。
1.1.數據定義語言DDL
是最基礎的Transact-SQL語言類型,用來創建資料庫和創建,修改,刪除資料庫中的各種對象,為其他語言的操作提供對象。例如資料庫,表,觸發器,存儲過程,視圖,函數,索引,類型及用戶等都是資料庫中的對象。常見的DDL語句包括
CREATE TABLE--創建表
DROP TABLE--刪除表
ALTER TABLE--修改表
1.2.數據操縱語言DML
是用於操縱表和視圖中的數據的語句,例如查詢數據(SELECT),插入數據(INSERT),更新數據(UPDATE)和刪除數據(DELETE)等。
1.3.數據控制語言DCL
涉及到許可權管理的語言稱為數據控制語言,主要用於執行有關安全管理的操作。如授予許可權(GRANT),收回許可權(REVOKE),拒絕授予主體許可權,並防止主體通過組或角色成員繼承許可權(DENY)
1.4.Transact-SQL語言基礎
1.4.1.常量與變數
常量不多說。在SQL Server 2008中,存在兩種變數。一種是系統定義和維護的全局變數,一種是用戶定義用來保存中間結果的局部變數。
1.4.1.1.系統全局變數
系統全局變數分為兩大類,一類是與當然SQL Server連接或與當前處理有關的全局變數,如@@Rowcount表示最近一個語句影響的行數。@@error表示保存最近執行操作的錯誤狀態。一類是與整個SQL Server系統有關的全局變數,如@@Version表示當前SQL Server的版本信息。
SELECT @@VERSION AS 當前版本;--查看當前SQL Server的版本信息
結果如圖所示
1.4.1.2.局部變數
局部變數能夠擁有特定數據類型,有一定的作用域,一般用於充當計數器計算或控制迴圈執行次數,或者用於保存數據值。局部變數前只有1個@符,用DECLARE語句聲明局部變數。
USE test
DECLARE @StudentId varchar(20)
SET @StudentId=(
SELECT Student.stu_no
FROM Student
WHERE stu_enter_score='603')
SELECT @StudentId AS 入學分數為603的學生學號
GO
結果如圖所示
2.運算符
2.1.算數運算符
在SQL Server 2008中,算數運算包括加(+)減(-)乘(*)除(/)取模(%)。舉一個簡單的例子。
示例1:在Student表中添加一列,列名為stu_age,根據Student表的stu_birthday列計算stu_age列並插入數據。(演示插入整列數據的方法)
Student表數據如圖所示
執行下麵的語句
ALTER TABLE Student
ADD stu_age int;--在Student表中添加stu_age列
CREATE TABLE #agetemp(stu_no varchar(8),age int);--新建一個臨時表
INSERT INTO #agetemp(stu_no,age)--在臨時表中插入學號和計算出來的年齡
SELECT Student.stu_no,YEAR(GETDATE())-YEAR(stu_birthday)--利用函數和運算符計算年齡
FROM Student;
UPDATE Student
SET Student.stu_age=#agetemp.age--將臨時表中的age列數據整個複製到Student表的stu_age列
FROM #agetemp
WHERE Student.stu_no=#agetemp.stu_no--條件是兩個表的stu_no列值相等
GO
SELECT * FROM Student
結果如圖所示
2.2.賦值運算符
即等號(=),將表達式的值賦予另一個變數。舉一個簡單的例子。
示例2:計算Student表中學生的平均入學成績並列印。
Student表的數據如圖所示,stu_enter_score列存放了學生的入學成績
執行下麵的語句
DECLARE @average int--聲明@average變數
SET @average=(--將計算出的平均值賦值給@average
SELECT AVG(stu_enter_score)
FROM Student)
PRINT @average--列印@average的值
結果如圖所示
2.3.位運算符
位運算符包括與運算(&),或運算(|)和異或運算(^),可以對兩個表達式進行位操作,這兩個表達式可以是整型數據或二進位數據。Transact-SQL首先把整型數據轉換為二進位數據,然後按位運算。舉個簡單的例子。
示例3:聲明2個int型變數@num1,@num2,對這兩個賦值且做與或異或運算。
執行下麵的語句
DECLARE @num1 int,@num2 int
SET @num1=5
SET @num2=6
SELECT @num1&@num2 AS 與,
@num1|@num2 AS 或,
@num1^@num2 AS 異或
結果如圖所示
擴展示例4:寫一個十進位轉換為二進位的函數
CREATE FUNCTION Bin_con_dec(@dec int)--定義十進位轉換為二進位函數
RETURNS varchar(20)
AS
BEGIN
DECLARE @quo int,@remainder varchar(20),@quo1 int
SET @quo=@dec
SET @remainder=''
WHILE @quo<>0
BEGIN
SET @quo1=@quo/2
SET @remainder=CAST(@quo%2 AS varchar(20))+@remainder
SET @quo=@quo1
END
RETURN @remainder
END
執行上面的函數後,運行下列語句驗證函數正確性
PRINT dbo.Bin_con_dec(42)
結果為101010,函數定義正確。
2.4.比較運算符
也稱關係運算符,用於比較兩個值的關係,常見的有等於(=),大於(>),小於(<),大於等於(>=),小於等於(<=),不等於(<>或!=)
示例5:從Student表中查詢入學成績在平均分以上的學生信息
Student表的數據如圖所示
執行下列語句
DECLARE @ave int
SET @ave=(SELECT AVG(stu_enter_score) FROM Student)
SELECT *FROM Student
WHERE stu_enter_score>=@ave;
結果如下圖所示
註:不能直接把代碼寫成下麵的形式
SELECT * FROM Student
WHERE stu_enter_score>=AVG(stu_enter_score)
消息147,級別15,狀態1,第2 行
聚合不應出現在WHERE 子句中,除非該聚合位於HAVING 子句或選擇列表所包含的子查詢中,並且要對其進行聚合的列是外部引用。
因為AVG是聚合函數。
2.5.邏輯運算符
邏輯運算符的作用是對條件進行測試。ALL,AND,ANY,BETWEEN,EXISTS,IN,LIKE,NOT,ALL,SOME。下麵用SOME來舉例。SOME的作用是如果在一組比較中,有些為true那就為true。
示例6:查詢Student表中是否存在入學成績高於平均分的學生,如果存在,輸出true,不存在輸出false。
Student表的stu_enter_score列(入學成績)數據如圖所示
執行下麵的語句
USE test
IF (SELECT AVG(stu_enter_score) FROM Student)<=SOME(SELECT stu_enter_score FROM Student)
PRINT 'true'
ELSE
PRINT 'false'
GO
結果如圖所示
2.6.連接運算符
加號(+)是字元串連接運算符,可以用它把字元串串連起來,在示例4的十進位轉二進位函數中,就用上了加號。
示例7:將Student表的stu_name列和stu_enter_score列放在同一列顯示,列名為score
Student表的數據如圖所示
執行下列語句
SELECT stu_name+CAST(stu_enter_score AS VARCHAR(3)) AS score FROM Student
執行結果如圖所示
註:stu_enter_score列數據類型為int,加號只對字元串類型數據有效,因此要用CAST函數將stu_enter_score的數據類型轉換為varchar(3),這樣才能實現字元串拼接。
2.7.一元運算符
一元運算符只對一個表達式執行操作,該表達式可以是數字數據類型中的任何一種數據類型。SQL Server 2008提供的一元運算符包含正(+),負(-),位反(~)。
示例8:聲明一個int數據類型變數@num並賦值,對該變數做正負位反操作。
執行下列語句
DECLARE @num INT
SET @num=45
SELECT +@num AS 正,-@num AS 負,~@num AS 位反
GO
結果如圖所示
註:位反操作符用於取一個數的補數,只能用於整數。
2.8.運算符的優先順序
優先順序 | 運算符 |
---|---|
1 | ~(位反) |
2 | *(乘),/(除),%(取模) |
3 | +(正),-(負),+(加),+(連接),-(減),&(位與) |
4 | =,>,<,>=,<=,<>,!=,!>,!<(比較運算符) |
5 | ^(位異或),位或(符號打不出來,前面有,自己翻) |
6 | NOT |
7 | AND |
8 | ALL,ANY,BETWEEN,IN,LIKE,ALL,SOME |
9 | =(賦值) |
當表達式中的運算符有相同的優先順序時,按照它們在表達式中的位置,一元運算符按從右往左運算,二元運算符(對兩個表達式作用的運算符)按從左往右運算。
示例9:驗證運算符優先順序
執行下列語句
DECLARE @result INT,@num INT
SET @num=45
SET @result=@num+(~@num)*4-@num/(~@num)
SELECT @result AS result
GO
結果如圖所示
計算代碼中的表達式
@result=@num+(~@num)4-@num/(~@num)
=@num+(-46)4-@num/(-46)
=45+(-46)4-45/(-46)
=45+(-46)4
=-139
3.控制語句
3.1.BEGIN END語句塊
BEGIN END可以定義SQL Server語句塊,使這些語句作為一組語句執行,允許語句嵌套。舉例請見示例4
3.2.IF ELSE語句塊
用於指定T-SQL語句的執行條件,若條件為真,則執行條件表達式後面的語句,條件為假時,可以試用ELSE關鍵字指定要執行的T-SQL語句。舉例請見示例4。
3.3.CASE分支語句
示例10:將Student表的學生,性別和籍貫列印出來,要求籍貫只能顯示省內,省外或自治區。
Student表的數據如圖所示
執行下列語句
SELECT stu_name AS 姓名,stu_sex AS 性別,
(CASE stu_native_place
WHEN '浙江' THEN '省內'
WHEN '內蒙古' THEN '自治區'
WHEN '西藏' THEN '自治區'
WHEN '寧夏' THEN '自治區'
WHEN '新疆' THEN '自治區'
WHEN '廣西' THEN '自治區'
ELSE '省外'
END) AS 籍貫
FROM Student
結果如圖所示
3.4.WHILE語句
用於設置重覆執行T-SQL語句或語句塊的條件。
示例11:用“*”在屏幕上輸出一個寬度為9的菱形。
執行下列語句
DECLARE @width int,@j int
SET @width=9--@width為菱形的最大寬度
SET @j=1--@j表示每行列印的“*”符號的個數
WHILE @j<=@width
BEGIN
PRINT SPACE((@width-@j)/2)+REPLICATE('*',@j)--SPACE函數列印n個空字元,REPLICATE列印n個特定字元串
SET @j=@j+2
END
SET @j=@width-2
WHILE @j>0
BEGIN
PRINT SPACE((@width-@j)/2)+REPLICATE('*',@j)
SET @j=@j-2
END
結果如圖所示
3.5.WAITFOR延遲語句
WAITFOR延遲語句可以讓在它之後的語句在一個指定的時刻或是時間間隔後執行,可以懸掛起批處理,存儲過程或事務的執行。
示例12:在某個時間點查詢Student表學號為20180101的學生信息
BEGIN
WAITFOR TIME '15:03'--在15點03分查詢
SELECT * FROM Student
WHERE stu_no='20180101'
END
示例13:在3分鐘後查詢Student表學號為20180102的學生信息
BEGIN
WAITFOR DELAY '00:03'--在3分鐘後查詢
SELECT * FROM Student
WHERE stu_no='20180102'
END
3.6.RETURN無條件退出語句
該語句表示無條件終止查詢,批處理或存儲過程的執行。存儲過程和批處理RETURN語句後面的語句都不再執行。當在存儲過程中使用該語句時,可以指定返回給調用應用程式、批處理或過程的整數值。如果RETURN未指定返回值,則存儲過程的返回值是0
3.7.GOTO跳轉語句
該語句使T-SQL批處理的執行跳轉至指定標簽。由於該語句破壞結構化語句的結構,儘量少用
示例13:將GOTO作為分支機制
執行下麵語句
DECLARE @Counter int;
SET @Counter = 1;
WHILE @Counter < 10
BEGIN
SELECT @Counter
SET @Counter = @Counter + 1
IF @Counter = 4 GOTO Branch_One --Jumps to the first branch.
IF @Counter = 5 GOTO Branch_Two --This will never execute.
END
Branch_One:
SELECT 'Jumping To Branch One.'
GOTO Branch_Three; --This will prevent Branch_Two from executing.
Branch_Two:
SELECT 'Jumping To Branch Two.'
Branch_Three:
SELECT 'Jumping To Branch Three.';
結果如圖所示
當Counter=4時,執行GOTO語句輸出Branch One,執行完這個語句之後就打破了WHILE迴圈,接著執行Branch_One語句中的GOTO,輸出Branch Three,結束。
註:在WHILE迴圈中使用GOTO會打破迴圈。
示例14:用GOTO語句實現示例11中列印菱形的功能
執行下列語句
DECLARE @width int,@j int,@i int
SET @width=9--@width為菱形的最大寬度
SET @j=1--@j表示每行列印的“*”符號的個數
SET @i=1--@i表示下一行列印第i行
Set3:PRINT SPACE((@width-@j)/2)+REPLICATE('*',@j)--SPACE函數列印n個空字元,REPLICATE列印n個特定字元串
SET @i=@i+1
IF @i<=(@width+1)/2
GOTO Set1
ELSE
GOTO Set2
Set1:
SET @j=@j+2
GOTO Set3
Set2:
SET @j=@j-2
IF @j>=1
GOTO Set3
結果如圖所示
3.8.TRY CATCH錯誤處理語句
如果TRY塊內部發生錯誤,會將控制傳遞給CATCH塊內的語句組。TRY CATCH構造捕捉所有嚴重級別大於10但不會終止資料庫連接的錯誤。
示例15:TRY CATCH的示例
執行下列語句
BEGIN TRY
SELECT * FROM Student
SELECT 120/0 FROM Student
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS '錯誤信息'
END CATCH
執行結果如圖所示
語句中3個select語句全部都執行了。如果把報錯的select語句放到正常的select語句前面,正常的select語句還能不能執行呢?執行下列語句
BEGIN TRY
SELECT 120/0 FROM Student
SELECT * FROM Student
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS '錯誤信息'
END CATCH
結果如圖所示
正常select語句無法執行。TRY CATCH語句的邏輯是,一旦TRY語句塊中出現問題語句,立刻跳轉到CATCH語句塊,TRY語句塊接下去的語句不再執行。
4.常用函數
4.1.數據類型轉換函數
預設情況下SQL Server會對一些數據類型進行自動轉換,這種轉換稱為隱式轉換。遇到無法自動轉換,則需要用CAST()函數和CONVERT()函數轉換,這種轉換稱為顯式轉換。CAST()函數和CONVERT()函數的功能是相同的,CAST函數更容易使用,CONVERT函數的優點是可以指定日期和數值格式。
示例16:將Student表中的學號轉換為日期格式
下麵兩句語句的功能是一樣的,執行下列語句
SELECT stu_name,CAST(stu_no AS DATE) AS 學號轉換成日期,stu_enter_score,stu_birthday FROM Student
SELECT stu_name,CONVERT(DATE,stu_no) AS 學號轉換成日期,stu_enter_score,stu_birthday FROM Student
結果如圖所示
示例17:用CONVERT()函數將stu_birthday轉化成指定格式的日期
執行下列語句
SELECT stu_name,CONVERT(VARCHAR(20),stu_birthday,101) FROM Student
--CONVERT函數將DATE類型的stu_birthday欄位轉化為字元串,並限定了樣式,代碼101
結果如圖所示
註:在上述代碼中,CONVERT(DATE,stu_birthday,101)這麼寫是沒用的。101格式碼只對日期格式轉化為字元串有效,其他格式轉化為日期格式是無效的。
其他常用函數太簡單了這邊不寫了,略。