在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