T-SQL(Transact Structured Query Language)是标准SQL语言的增强版。标准SQL可以在所有关系型数据库中通用,但T-SQL是SQL server独有的。
SQL语句均由一个动词(Verb)开始,描述执行的动作。
后紧接着一个或多个子句(Clause),子句给出被Verb作用的数据或描述动作的详细信息,每一条子句都由一个关键字开始。语句分类
变量说明语句:说明变量的命令;
数据定义语句:用来建立数据库、数据库对象和定义列,大部分以CREATE开头的命令;
数据操纵语句:操作数据库中数据,如SELECT、INSERT、UPDATE等;
数据控制语句:控制数据库组件的存取许可、权限等命令,如GRANT、REVOKE等;
流程控制语句:设计应用程序流程的语句,如IF、WHILE和CASE等;
内嵌函数:说明变量的命令。
其它命令:嵌于命令中使用的标准函数。
常量
*数字常量
整数常量和小数常量直接输入,可加负号,以逗号分隔不同的数字,如12,-100.23
浮点数用符号e指定(类似科学计数),如1.5e3,-34e-8
*字符串常量
单引号标示,可以包含数字、字母、特殊字符、空格、感叹、@、#
可以用两个单引号表示嵌入的单引号。
*日期和时间常量
多种格式,如美国mm/dd/yyyy,欧洲dd.mm.yyyy,中国yyyy-mm-dd等
*符号常量
SQL特有,代表不同的常用数据值。如CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP等。
变量
局部变量
局部变量变量名必须以@开头,符合标识符命名规则
- 声明局部变量
DECLARE
{
@varaible_name datatype [, ... n]
}
datatype可以是text, ntext, image类型外的所有数据类型
{}不是必须的
- 赋值
使用SELECT或SET语句
DECLARE @a char(10), @b int
SELECT @a = 'hello world'
SELECT @b = Stu_col FROM table_a WHERE Stu_spe=‘English’
SET @a = 'hi world'
SET @b = 1
注意,DECLARE可以同时声明多个变量,而SET只能为一个变量赋值
全局变量
全局变量以@@开头
常用变量 | 作用 |
---|---|
@@CONNECTIONS | 自服务器最近一次启动以来,所有连接数目,包括未成功的尝试 |
@@CUP_BUSY | 自上次启动以来,所有连接以ms为单位的cpu工作时间 |
@@CURSOR_ROWS | 打开游标取出数据行的数目 |
@@DBTS | 返回当前数据库中timestamp数据类型当前值 |
@@ERROR | 返回上一条T-SQL执行的错误代码 |
@@FETCH_STATUS | 返回上一次使用游标FETCH操作返回的状态值,整型,成功0,语句失败-1,被提取的行不存在-2 |
@@IDENTITY | 返回最近一次插入的identity列的数值,numeric值 |
注释符
-- 单行注释
/* blabla 多行注释 */
运算符Operator
Operator | Description |
---|---|
+, -, *, / | 加、减、乘、除 |
% | 取余 |
= | Equal |
<>、!= | Not equal. Note: In some versions of SQL this operator may be written as != |
> | Greater than |
!> | Not greater than |
< | Less than |
!< | Not less than |
>= | Greater than or equal |
<= | Less than or equal |
& | 按位与(整型或二进制数据类型) |
| | 按位或(整型或二进制数据类型) |
~ | 按位非(整型或二进制数据类型) |
^ | 按位异或(整型或二进制数据类型) |
AND, OR, NOT | 逻辑与、或、非 |
+ | 链接字符串 |
以下逻辑运算符 | 通常与比较运算符连用 |
ANY | 任意一个true,结果为true |
ALL | 全部为true,结果为true |
BETWEEN ... AND | Between an inclusive range |
EXISTS | 存在则为true |
LIKE | Search for a pattern,模式匹配则为true |
IN | '=ANY', To specify multiple possible values for a column |
操作符
- AND操作符
要通过不止一个列进行果过滤,可以使用AND操作符对WHERE子句附加条件,用在WHERE子句中的关键字 - OR 操作符
OR操作符与AND操作符正好相反,它告诉DBMS检索匹配任一条件的行,事实上,许多DBMS在OR WHERE 子句的第一个条件得到满足的情况下就不再计算第二个条件了(在第一个条件满足时,不管第二个条件是否满足,相应的行都将被检索出来。 - IN 操作符
In操作符用来指定条件范围,范围中的每个条件都可以进行匹配,in取一组逗号分隔,括在圆括号中的合法值IN 操作符允许我们在 WHERE 子句中规定多个值
SELECT column_name(s) FROM table_name
WHERE column_name IN (value1,value2,...)
NOT操作符
WHERE子句中的NOT操作符有且只有一个功能,那就是否定其后所跟的任何条件,因为NOT从不单独使用,(他总是与其他操作符一起使用),所以了他的语法与其他操作符有所不同,NOT关键字可以用在要过滤的列前,而不仅是在其后.AS
Alias 语法
表的SQL Alias语法
SELECT column_name(s)
FROM table_name
AS alias_name
列的SQL Alias语法
SELECT column_name AS alias_name
FROM table_name
通配符
Operator | Description |
---|---|
% | 匹配0到多个字符的字符串 |
_ | 匹配单个字符 |
[] | 如[a-z],匹配指定范围或集合内的单个字符 |
[^] | [^a-c], 匹配不在指定范围或集合内的单个字符 |
流程控制
BEGIN…END
流程控制语句必须执行一个包含两条或两条以上的SQL语句块时使用
BEGIN
sql_statements...
END
在BEGIN...END中可以嵌套另外的BEGIN...END来定义另一程序块。
IF... ELSE
选择判断结构,可以单独IF使用,可以结合ELSE使用
IF<条件表达式>
命令行1 | 程序块1
ELSE
命令行2 | 程序块2
由于IF没有END结构,所以命令行只能一行,否则使用BEGIN...END程序块。IF判断为真执行IF后命令,为假则执行再下一条语句。
CASE
多重选择语句
用于计算条件列表的表达式,并返回可能的结果之一。
sql 的case 类型于编程语言里的 if-esle if-else 或者 switch,但它不用于控制sql程序的执行流程,而是作为列的逻辑使用。
case [input_expression]
when when_expression then result_expression
[...n]
[else else_result_expression]
end
注:其中[]内都是可选的。
简单case函数(case后加表达式,则根据表达式结果返回。)
--简单case函数
select *,
case sex
when '1' then '男'
when '2' then '女’
else '其他' end groupname
from @table
case搜索函数。(case 后不加表达式,则根据when的条件返回)
--case搜索函数
select *,
case
when sex = '1' then '男'
when sex = '2' then '女'
else '其他' end comment
from @table
这两种方式,可以实现相同的功能。简单case函数的写法相对比较简洁,但是和case搜索函数相比,功能方面会有些限制,比如写判定式。
还有一个需要注重的问题,case函数只返回第一个符合条件的值,剩下的case部分将会被自动忽略。
--比如说,下面这段sql,你永远无法得到“第二类”这个结果
case when col_1 in ('a','b') then '第一类'
when col_1 in ('a') then '第二类'
else '其他' end
将sum与case结合使用,可以实现分段统计。
如果现在希望将上表中各种性别的人数进行统计,sql语句如下:
SQL> select
2 sum(case u.sex when 1 then 1 else 0 end)男性,
3 sum(case u.sex when 2 then 1 else 0 end)女性,
4 sum(case when u.sex <>1 and u.sex<>2 then 1 else 0 end)性别为空
5 from users u;
男性 女性 性别为空
---------- ---------- ----------
3 2 0
--------------------------------------------------------------------------------
SQL> select
2 count(case when u.sex=1 then 1 end)男性,
3 count(case when u.sex=2 then 1 end)女,
4 count(case when u.sex <>1 and u.sex<>2 then 1 end)性别为空
5 from users u;
男性 女 性别为空
---------- ---------- ----------
3 2 0
将case与order by一起使用,可实现复杂排序
如下,存储过程需要支持多种排序,可以传递一个参数变量,然后根据该变量判断操作。
declare @orderby int
set @orderby = 1
select * from @stuinfo
order by
case when @orderby = 1 then id end desc,
case when @orderby = 2 then id end
注意:这里要用多个case,因为desc需要放在end 后面,否则会有语法错误。
WHILE
设置重复执行 SQL 语句或语句块的条件。只要指定的条件为真,就重复执行语句。可以使用 BREAK 和 CONTINUE 关键字在循环内部控制 WHILE 循环中语句的执行。
循环结构,执行其后一条命令,或配合BEGIN...END子句执行该程序块
语法
WHILE Boolean_expression
{ sql_statement | statement_block }
[ BREAK ]
{ sql_statement | statement_block }
[ CONTINUE ]
参数
Boolean_expression
返回 TRUE 或 FALSE 的表达式。如果布尔表达式中含有 SELECT 语句,必须用圆括号将 SELECT 语句括起来。{sql_statement | statement_block}
Transact-SQL 语句或用语句块定义的语句分组。若要定义语句块,请使用控制流关键字 BEGIN 和 END。
WHILE<条件表达式>
BEGIN
<命令行 | 程序块>
END
还可以使用CONTINUE和BREAK命令,控制循环执行
WHILE<条件表达式>
BEGIN
<命令行 | 程序块>
[BREAK]
[CONTINUE]
[命令行 | 程序块]
END
CONTINUE可以放在IF里,满足一定条件则路过后续,继续执行新一个loop
BREAK也可以放在IF语句里,满足条件后直接中断结束WHILE,执行后续语句
BREAK
导致从最内层的 WHILE 循环中退出。将执行出现在 END 关键字后面的任何语句,END 关键字为循环结束标记。CONTINUE
使 WHILE 循环重新开始执行,忽略 CONTINUE 关键字后的任何语句。
注释
如果嵌套了两个或多个 WHILE 循环,内层的 BREAK 将导致退出到下一个外层循环。首先运行内层循环结束之后的所有语句,然后下一个外层循环重新开始执行。
RETURN
从查询或过程中无条件退出。RETURN后语句不会被执行。
RETURN [返回值]
GOTO
程序跳到标识符指定的程序行继续执行。
GOTO 标识符
此处标识符要在名称后加冒号‘:’,如“here:”
与while 语句结合可以实现WHILE...END的功能
DECLARE @X INT
SELECT @X = 1
here:
PRINT @X
SELECT @X = @X+1
WHILE @X<=3 GOTO here
WAITFOR
指定触发器、存储过程或事务执行时间,也可以用来暂停程序执行
WAITFOR DELAY<'时间'> | TIME<‘时间’>
其中时间必须为DATETIME类型,不能包括日期。
DELAY用来设定等待时间,最长24小时
TIME用来设定等待结束的时间点。
常用命令
- DECLARE
- PRINT
向客户端显示一个字符串(最长255字符)、局部变量或全局变量的内容
PRINT msg_str | @local_variable | string_expr - READTEXT
读取text、ntext或image列中的值,从指定位置开始读取指定字符数
READTEXT table.column text_ptr offset size [HOLDLOCK]
SELECT
查询,赋值均可实现SET
赋值,功能更强更严密,推荐使用USE
在当前工作区打开数据库