在T-SQL中,變量以@
符號開頭,使用DECLARE
聲明變量(一次能夠聲明多個變量),並同時定義變量的數據類型。sql
SET
或者使用SELECT
給變量賦值DECLARE @Num AS INT ,@Result AS INT SET @Num=10 SELECT @Result=20 SET @Result=@Num+@Result SELECT @Result
AS
DECLARE @Num INT SET @Num=10 SELECT @Num
DECLARE @i INT=100--聲明變量的同時給變量賦值 SELECT @i
SET
一次只能給一個變量賦值,而使用SELECT
能夠一次賦值多個變量SET @Num=10--SET一次只能個一個變量賦值 SELECT @Num=10,@Resutl=100--SELECT一次能夠給多個變量賦值
SELECT
即對某個變量使用某個字段賦值,又同時從表中查詢另外字段。DECLARE @Age varchar(50) SELECT NAME,@AGE=Age FROM T_STUDENTS--這裏就是即用Age字段對@Age賦值,又同時查詢Name字段
上面的語句就會報錯:數據庫
向變量賦值的 SELECT 語句不能與數據檢索操做結合使用。
可是注意如果SELECT
僅是經過查詢字段賦值給某個變量,則是徹底沒有問題的express
DECLARE @Age VARCHAR(50),@Name VARCHAR(50) WITH Temp AS ( SELECT '張三' AS Name ,12 AS Age UNION ALL SELECT '李四' AS Name, 14 AS Age UNION ALL SELECT '王五' AS Name, null AS Age ) SELECT @Name=Name ,@Age=Age FROM Temp WHERE Name='張三' SELECT @Name, @Age 結果: ----- ------ 張三 12
批處理是做爲一個單元而進行分析和執行的一組T-SQL語句。編程
批處理須要經歷的處理階段:分析(語法檢查)-->解析(檢查查詢的對象和列是否存在,是否具備訪問權限)-->優化(做爲一個執行單元)服務器
批處理和事務是不同的:簡單的說一個批處理裏中能夠有多個事務!函數
在SQL SERVER Management中,能夠使用GO命令,表示一個批處理結束標誌。可是注意:GO命令是SQL SERVER Management工具的命令,而不是SQL SERVER服務器的命令。工具
GO
命令能夠帶有參數,實現重複執行同一個批處理(SQL SERVER 2005),GO n
,n爲執行批處理的次數。優化
SELECT SYSDATETIME() GO 3 結果: 開始執行循環 --------------------------- 2020-11-24 23:19:39.8413125 --------------------------- 2020-11-24 23:19:39.8523131 --------------------------- 2020-11-24 23:19:39.8573134 批處理執行已完成 3 次。
在執行批處理的時候首先是進行分析,若是批處理中出現語法錯誤,則整個批處理就不會執行。code
DECLARE @Name NVARCHAR(50) ='Tom' SELECT @Name GO--以上是第一個批處理 SELECT GETDATE() SELECT GETDAT()--有意製造一個錯誤 GO--以上是第二個批處理 執行結果: ------------ Tom (1 行受影響) 消息 195,級別 15,狀態 10,第 6 行 'GETDAT' 不是能夠識別的 內置函數名稱。
說明:第一批處理執行完畢,第二批處理中存在語法錯誤,故第二批處理中的全部SQL都沒有執行。server
批處理與變量:定義在批處理中的變量是該批處理的局部變量。
DECLARE @Name NVARCHAR(50) ='Tom' GO SELECT @Name 結果: 消息 137,級別 15,狀態 2,第 3 行 必須聲明標量變量 "@Name"。
說明:SELECT @Name
不在定義變量@Name的批處理中,故執行失敗
IF……ELSE
用於更具條件來控制SQL代碼塊的執行流程。若是條件取值爲TRUE,則執行IF中的的SQL語句;若是條件取值爲FALSE或UNKNOWN,則執行ELSE中的SQL語句(ELSE語句爲可選)。
DECLARE @i int =100 IF @i=100 PRINT 'i=100' ELSE PRINT 'i!=100'
如果須要在IF或ELSE部分運行多條語句,則能夠使用語句塊。語句塊使用BEGIN……END
關鍵字識別,就至關於「{}」
DECLARE @i int =100 IF @i=100 BEGIN PRINT 'i=100' END ELSE BEGIN PRINT 'i!=100' END
在其餘語句中,有if……else if……else的語法,在SQL中沒有這樣的語法,可是能夠嵌套使用if……else
DECLARE @i int =99 IF @i=101 BEGIN PRINT 'i=101' END ELSE IF @i=100 BEGIN PRINT 'i=100' END ELSE BEGIN PRINT 'i!=101 and i!=100' END
判斷當前數據庫Test中是否存在Employee表
USE Test GO IF EXISTS(SELECT * FROM SYSOBJECTS WHERE NAME='Employee') Begin PRINT '當前Test數據庫中存在Employee表' END ELSE BEGIN PRINT '當前Test數據庫中不存在Employee表' END
另一種查詢當前數據庫中是否存在指定的T-SQL編程對象的方法
USE Test GO IF OBJECT_ID('Employee','U') IS NOT NULL Begin PRINT '當前Test數據庫中存在Employee表' END ELSE BEGIN PRINT '當前Test數據庫中不存在Employee表' END
CASE
表達式是一個標量表達式,返回一個基於條件邏輯的值。
CASE
是一個標量表達式,所以能夠在任何容許使用標量表達式的地方使用它。例如:SELECT
,WHERE
,HAVING
和ORDER BY
子句中。
若是CASE
表達式沒有ELSE
子句,默認爲ELSE NULL
簡單示例1——在SELCET語句中使用--簡單格式表達式
經常使用的場景,將某個縮寫詞字段中的值替換爲完整描述性的值
WITH Temp AS ( SELECT 'Tom' AS Name ,14 AS Age ,1 AS Grade UNION ALL SELECT 'Bob' AS Name ,15 AS Age ,2 AS Grade UNION ALL SELECT 'Jery' AS Name,16 AS Age,3 AS Grade ) SELECT Name,Age, CASE Grade WHEN 1 THEN '一年級' WHEN 2 THEN '二年級' WHEN 3 THEN '三年級' ELSE 'NULL' END AS Grade FROM Temp 結果: Name Age Grade ---- ----- ------ Tom 14 一年級 Bob 15 二年級 Jery 16 三年級
根據條件在查詢結果集中添加一個列(字段)
WITH Temp AS ( SELECT 'Tom' AS Name ,13 AS Age UNION ALL SELECT 'Bob' AS Name ,15 AS Age UNION ALL SELECT 'Jerry' AS Name,16 AS Age ) SELECT Name,Age , CASE WHEN Age<=14 THEN '未成年' WHEN Age>14 THEN '成年人' END AS 類型 FROM Temp
排序的時候,既不是升序也不是降序,而是按照自定義的順序排序
WITH Temp AS ( SELECT 'Tom' AS Name ,14 AS Age UNION ALL SELECT 'Bob' AS Name ,15 AS Age UNION ALL SELECT 'Jerry' AS Name,16 AS Age ) SELECT Name,Age FROM Temp ORDER BY CASE WHEN Name='Jerry' then 1 WHEN Name='Tom' then 2 WHEN Name='Bob' THEN 3 END
結果:
Name Age ----- ----- Jerry 16 Tom 14 Bob 15
使用情形1:根據不一樣的值選擇不一樣的字段做爲篩選條件中使用的字段。
當輸入參數@Flag爲1的時候,取數學成績爲100的學生,當輸入參數@Flag爲2的時候,取語文成績爲100的學生
固然這裏也可以使用使用IF語句判斷不一樣的@Flag值執行不一樣的SELECT語句,這裏使用CASE WHEN語句演示:
DECLARE @Flag INt=1; WITH Temp AS ( SELECT '張三' AS Name ,12 AS Age,'男' AS Gender,100 AS MathGrade,80 AS ChineseGrade UNION ALL SELECT '李四' AS Name, 14 AS Age,'女' AS Gender,90 AS MathGrade,80 AS ChineseGrade UNION ALL SELECT '王五' AS Name, 15 AS Age,'男'AS Gender,80 AS MathGrade,90 AS ChineseGrade UNION ALL SELECT '趙六' AS Name, 15 AS Age,'女'AS Gender,80 AS MathGrade,100 AS ChineseGrade ) --select * from temp where (case when @Flag=1 then MathGrade=100 when @Flag=2 then ChineseGrade=100 end)--錯誤寫法 --select * from temp where (case @Flag when 1 then MathGrade when 2 then ChineseGrade end)=100 --等價於下面寫法: SELECT * FROM Temp WHERE (CASE WHEN @Flag=1 Then MathGrade WHEN @Flag=2 THEN ChineseGrade END)=100 --更常規,更便於理解的寫法 SELECT * FROM temp WHERE (@Flag=1 AND MathGrade=100) OR (@Flag=2 AND ChineseGrade=100)
使用情形2:篩選條件中出現IN(……),再對某個特定的值,作篩選
首先年齡在12~15歲的人,且15歲年齡的只取女性
WITH Temp AS ( SELECT '張三' AS Name ,12 AS Age,'男' AS Gender,100 AS MathGrade,80 AS ChineseGrade UNION ALL SELECT '李四' AS Name, 14 AS Age,'女' AS Gender,90 AS MathGrade,80 AS ChineseGrade UNION ALL SELECT '王五' AS Name, 15 AS Age,'男'AS Gender,80 AS MathGrade,90 AS ChineseGrade UNION ALL SELECT '趙六' AS Name, 15 AS Age,'女'AS Gender,80 AS MathGrade,100 AS ChineseGrade ) SELECT * FROM Temp WHERE Age IN (12,13,14,15) AND (CASE WHEN age=15 AND gender<>'女' THEN 0 ELSE 1 END)=1 結果: 張三 12 男 100 80 李四 14 女 90 80 趙六 15 女 80 100
T-SQL中使用WHILE
循環執行代碼。只要在WHILE關鍵字以後指定的表達式爲TRUE,WHILE會重複執行一個語句塊
DECLARE @i INT =0; WHILE @i<10 BEGIN PRINT @i; SET @i=@i+1; END;
DECLARE @i INT =0; WHILE @i<10 BEGIN IF @i=6 BREAK;--當@i=6的時候,就中止循環 PRINT @i; SET @i=@i+1; END;
DECLARE @i INT =0; WHILE @i<10 BEGIN SET @i=@i+1; IF @i=6 CONTINUE;--當@i=6的時候,跳出本次循環 PRINT @i; END;
T-SQL支持的某些函數,本質上是能夠看做是CASE表達式的縮寫:
ISNULL()
:使用指定的替換值替換 NULL。DECLARE @Name VARCHAR SELECT ISNULL(@Name,'')
COALESCE()
:返回列表中第一個非null表達的值。若是全部表達式求值爲null,則返回nullDECLARE @Name VARCHAR DECLARE @Age INT SELECT Coalesce(@Name,@Age,2) 結果: Result ------- 2
IFF()
:根據布爾表達式計算爲 true 仍是 false,返回其中一個值。IFF(boolean_expression, true_value, false_value)
DECLARE @a INT = 45, @b INT = 40; SELECT IIF ( @a > @b, 'TRUE', 'FALSE' ) AS Result; 結果: Result ------ TRUE
關於IFF()的使用,其實能夠替代CASE兩個分支的情形,當前CASE分支是兩個相互對象的情形的時候,能夠使用IFF()簡單的實現:
WITH Temp AS ( SELECT 'Tom' AS Name ,13 AS Age UNION ALL SELECT 'Bob' AS Name ,15 AS Age UNION ALL SELECT 'Jerry' AS Name,16 AS Age ) SELECT Name,Age, IIF(Age<14,'未成年人','成年人') AS AgeType FROM temp 結果: Name Age AgeType ----- ----------- -------- Tom 13 未成年人 Bob 15 成年人 Jerry 16 成年人
CHOOSE
:從值列表返回指定索引處的項。注意值列表的索引是從1開始的計數的。
SELECT CHOOSE ( 3, '第一名', '第二名', '第三名', '第四名' ) AS Result; 結果: Result ------ 第三名
其做用和CASE的簡單表達式的做用同樣,將某一列縮寫類的值轉換爲描述性的值
簡單示例:根據出生日期,肯定出生季節
WITH Temp AS ( SELECT 'Tom' AS Name ,'2020-1-11' AS Birthday UNION ALL SELECT 'Bob' AS Name ,'2020-5-11' AS Birthday UNION ALL SELECT 'Jerry' AS Name,'2020-10-11' AS Birthday ) SELECT Name, Birthday, CHOOSE(MONTH(Birthday), 'Spring','Spring','Spring','Summer','Summer', 'Summer','Autumn','Autumn','Autumn','Winter','Winter','Winter') AS Birth_Quarter FROM Temp 結果: Name Birthday Birth_Quarter ----- ---------- ------------- Tom 2020-1-11 Spring Bob 2020-5-11 Summer Jerry 2020-10-11 Winter