目录
1、T-SQL的元素
1.1 标识符
1. 常规标识符
2. 分隔标识符
1.2 变量
1. 全局变量
2. 局部变量
1.3 运算符
1. 算数运算符
2. 赋值运算符
3. 位运算符
4. 比较运算符
5. 逻辑运算符
6. 字符串连接运算符
7. 一元运算符
8. 运算符的优先级和结合性
1.4 批处理
1.5 注释
2、流程控制语句
2.1 BEGIN…AND
2.2 IF…ELSE
2.3 CASE
2.4 WHILE…CONTINUE…BREAK
2.5 RETURN
2.6 RAISERROR
3、函数
3.1 系统内置函数
3.2 用户自定义函数
1. 标量值函数
2. 内联表值函数
3. 多语句表值函数
4、游标
4.1 游标的概述
4.2 游标的类型
1. 只进游标
2. 静态游标
3. 键集游标
4. 动态游标
4.3 游标的使用
1. 声明游标
2. 打开游标
3. 提取数据
4. 关闭游标
5. 释放游标
4.4 定位修改游标
4.5 定位删除游标
T-SQL的语法约定
数据库的概念和操作-CSDN博客
1、T-SQL的元素
1.1 标识符
1. 常规标识符
1. 必须以汉字、字母、下划线_、@、#开头,后续字符可以是数字、汉字、字母、下划线_、@、#的组合。
2. 不能是SQL Server 的关键字。
3. 不能超过128个字符。
2. 分隔标识符
需要使用分隔标识符的情况:放在方括号[ ]或双引号" "中
1. 标识符的命名不符合常规标识符格式的规则。
2. 使用关键字作为对象名或对象名的一部分。
1.2 变量
1. 全局变量
由系统提供且预先声明,全局变量名由“@@”符号开始。
用户只能使用全局变量,不能进行修改。
作用域是整个SQL Server 系统,任何程序都可以随时调用它们。
2. 局部变量
一般在批处理(go),过程(procedure)中可见。
定义(DECLARE):局部变量名由“@”符号开始。一定要先定义再使用。
DECLARE {@local_variable data_type}[,...n]
赋值(SET|SELECT):
-- 只能对单个变量赋值
SET {@local_variable = expression}
--可对多个变量赋值
SELECT {@local_variable = expression}[,...n]
输出(PRINT|SELECT):
-- 只能单个字符串|局部变量|字符串表达式
PRINT {msg_str|@local_variable|string_expr}
-- 可以多个局部变量的值
SELECT {@local_variable}[,...n]
局部变量的作用域:批处理(go),过程(procedure)中。
例:
DECLARE @myvar char(20),@i int
SET @myvar = 'This is a test'
SET @i=20
SELECT @myvar as a ,@i as b
GO
1.3 运算符
1. 算数运算符
加(+),减(-),乘(*),除(/),取模(%)。
注意:取模(%),只能是int,tinyint,smallint。
2. 赋值运算符
T-SQL中只有一个赋值运算符,即等号(=)。
3. 位运算符
按位与(&),按位或(|),按位异或(^)。
注意:两个数据可以是整型数据或二进制数据,但不能同时是二进制数据。
4. 比较运算符
=、>、<、>=、<=、<>(!=)。
运算结果为逻辑值:TRUE,FALSE,UNKNOWN(当NULL参与时)。
5. 逻辑运算符
返回值为TRUE或FALSE或UNKNOWN(当NULL参与时)。
ALL:如果一组的比较都为TRUE,那么就为,TRUE。
AND:如果两个布尔表达式都为TRUE,那么就,为 TRUE。
ANY:如果一组的比较中任何一个为TRUE,那,么就为TRUE。
BETWEEN:如果操作数在某个范围之内,那么就为,TRUE。
EXISTS:如果子查询包含一些行,那么就为TRUE。
IN:如果操作数等于表达式列表中的一个,那么就为TRUE。
LIKE:如果操作数与一种模式相匹配,那么就为,TRUE。
NOT:对任何其他布尔运算符的值取反。
OR:如果两个布尔表达式中的一个为TRUE,那么就为TRUE。
SOME:如果在一组比较中,有些为TRUE,那么就为TRUE。
6. 字符串连接运算符
“+”
7. 一元运算符
“+”,正,“-”,负,“~”,按位取反(只能是整数数据类型)。
8. 运算符的优先级和结合性
级别 | 运算符 |
---|---|
1 | ~(按位取反) |
2 | *(乘)、/(除)、%(取模) |
3 | +(正)、-(负)、+(加)、+(串联)、-(减)、&(位与)、^(位异或)、|(位或) |
4 | =、>、<、>=、<=、<>(!=)、!>、!< |
5 | NOT |
6 | AND |
7 | ALL、ANY、BETWEEN、IN、LIKE、OR、SOME |
8 | =(赋值) |
1.4 批处理
批处理是包含一个或多个T-SQL语句的集合,从应用程序一次性地发送到SQL Server2014进行执行,一次可以节省系统开销。SQL Server将批处理的语句编译为一个可执行单元,称之为执行计划,批处理的结束符为“GO”。
编译错误(如:语法错误)可使执行计划无法编译。因此未执行批处理中的任何语句。
运行时错误(如:算术溢出或违反约束)会产生以下两种影响之一:
1. 大多数运行时错误,将停止执行批处理中,当前语句及后面的语句。
2. 某些运行时错误(如:违反约束)仅停止执行当前语句,而继续执行批处理中的其他语句。
1.5 注释
“--” 或 “/*……*/”
2、流程控制语句
2.1 BEGIN…AND
BEGIN
{sql_statement|statement_block}
END
sql_statement|statement_block:T-SQL语句|语句块。
BEGIN…END主要用于下列情况:
WHILE,CASE,IF…ELSE。
BEGIN…END可以嵌套。
2.2 IF…ELSE
IF Boolean_expression
{sql_statement|statement_block}
[ELSE {sql_statement|statement_block}]
IF…ELSE语句可以嵌套。
如果Boolean_expression中有SELECT语句,要加()。
例:如果,学号“20160211”的学生选修的,课程号为“0101”的课程成绩>=90,“成绩优秀”,否则“成绩一般”。
USE teaching
GO
IF ( SELECT score FROM sc WHERE sno='20160211' and cno=’0101’) >=90PRINT '成绩优秀'
ELSEPRINT '成绩一般'
2.3 CASE
简单CASE格式:(CASE后面)某个表达式与(WHEN后面)一组简单表达式或常量进行比较,以确定结果。
搜索CASE格式:计算(WHEN后面)一组布尔表达式,以确定结果。
例:查询所有学生的考试等级,包括学号,课程号,成绩等级(优秀,良好,中等,及格,不及格)
简单CASE: 整数/整数 = 整数
use teaching
select sno as 学号,cno as 课程号,
CASE score/10
when 10 then '优秀'
when 9 then '优秀'
when 8 then '良好'
when 7 then '中等'
when 6 then '及格'
else '不及格'
END
from sc
搜索CASE(推荐):
use teaching
select 学号=sno,课程号=cno,成绩等级=
CASE
when score>=90 then '优秀'
when score>=80 then '良好'
when score>=70 then '中等'
when score>=60 then '及格'
else '不及格'
END
from sc
2.4 WHILE…CONTINUE…BREAK
WHILE Boolean_expressionession
[BEGIN]
sql_statement|statement_block [BREAK|CONTINUE]
[END]
例:求1到100的累加,并输出。
DECLARE @i int,@sum int
SELECT @i = 1,@sum = 0
WHILE @i <= 100BEGINSET @sum = @sum+@iSET @i = @i+1END
SELECT @sum as 'sum',@i as 'i'
2.5 RETURN
可以从查询或过程中无条件退出。
2.6 RAISERROR
RAISERROR:将错误信息显示在屏幕上,同时也可以记录在NT日志中。
RAISERROR{{msg_id|msg_str},severity,state}
msg_id|msg_str:错误信息。
severity:错误的严重级别。
state:发生错误时的状态信息。
如:
RAISERROR('NO !',16,1)
3、函数
3.1 系统内置函数
聚合函数,数学函数,日期和时间函数,字符串函数。
强制类型转换函数:
CAST( expression AS data_type[(length)] )
如:把int类型的@age强制转换为char(2)类型
CAST(@age as char(2))
CONVERT(data_type[(length),expression[,style])
3.2 用户自定义函数
1. 标量值函数
一般需要declare变量。
CREATE FUNCTION [schema_name.]function_name
([{@parameter_name parameter_data_type [= default_expression]}[,...n]])
RETURNS return_data_type
[AS] -- 一般不省略BEGINfunction_bodyRETURN expressionEND
GO
注意:调用标量值函数,需要指定架构名,默认为dbo。
例:创建一个标量值函数,接受学号,返回该学号的平均成绩。
use teaching
go
create function avgscore(@sno char(8))
returns tinyint
as
begindeclare @avgscore tinyintselect @avgscore=avg(score)from scwhere sno = @snoreturn @avgscore
end
go
-- 调用标量值函数,需要指定架构名,默认为dbo
select dbo.avgscore('20160211') as '平均成绩'
2. 内联表值函数
一般不需要declare变量。
CREATE FUNCTION [schema_name.]function_name
([{@parameter_name parameter_data_type [= default_expression]}[,...n]])
RETURNS TABLE
[AS] -- 一般不省略
RETURN(select_statement)
注意:内联表值函数返回的是表。
例1:创建一个内联表值函数,查询各个专业的专业名称及学生人数的。
use teaching
go
create function ZY_RS() -- ()不能省略
returns table
as
return(
select specialty,count(*) as '学生人数'
from student
group by specialty)
go
select * from ZY_RS() -- 返回的是一个表,所以from
例2:创建一个内联表值函数,接受课程号,返回该课程号的选修信息,不传课程号,就返回所有课程号的选修信息。
use teaching
go
create function XK
(@cno varchar(4) = '%') -- 如果是char(4),实际上是'%'+3个空格
returns table
as
return(
select * from sc where cno like @cno)
go
select * from XK('0101') -- 特定课程号的选修信息
select * from XK(default) -- 全部选修信息
3. 多语句表值函数
可以自定义返回表的结构。
CREATE FUNCTION [schema_name.]function_name
([{@parameter_name parameter_data_type [= default_expression]}[,...n]])
RETURNS @return_variable TABLE<table_definition>
[AS] -- 一般不省略
BEGINfunction_bodyRETURN
END
例:创建一个多语句表值函数,查询选修特定课程名的学号,姓名,课程号,课程名,成绩
use teaching
go
create function KCM_XK(@cname varchar(32))
-- 返回的表名必须是局部变量名的形式(@)
returns @xk table(学号 char(8),姓名 varchar(10),
课程号 char(4),课程名 varchar(32),成绩 tinyint)
as
begininsert into @xk select s.sno,s.sname,sc.cno,c.cname,sc.score -- 对应好表中的列from sc inner join student as s on sc.sno = s.sno -- 不需要逗号inner join course as c on sc.cno = c.cnowhere c.cname = @cnamereturn
end
go
select * from KCM_XK('C语言')
4、游标
4.1 游标的概述
游标是处理数据的一种方式,它允许应用程序每一次处理一行或一部分行。
游标可以看作一个指针,可以指定结果中的任何位置。
4.2 游标的类型
1. 只进游标
FORWARD_ONLY,即只进游标只能从第一行滚动到最后一行。
2. 静态游标
STATIC,静态游标在打开时会创建一个数据快照,该快照不会随着后续数据库的修改而改变。
静态游标是在数据快照上进行操作。
3. 键集游标
KEYSET,键集游标在打开时,会固定结果集中行的成员身份和顺序。这意味着,当游标打开后,即使底层数据表中的数据发生变化,游标所指向的行集也不会改变(除非这些行的键被更改)。然而,与静态游标不同的是,如果结果集中的行由于键的更改而被删除或更新,这些更改在键集游标中是可见的。
4. 动态游标
DYNAMIC,动态游标与静态游标相对,反映结果集中所做的所有更改。
4.3 游标的使用
1. 声明游标
DECLARE cursor_name CURSOR [LOCAL | GLOBAL] -- 局部|全局[FORWARD_ONLY | SCROLL] -- 只进|滚动[STATIC | KEYSET | DYNAMIC | FAST_FORWARD][READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]FOR select_statement[FOR UPDATE [OF column_name [,...n]]] -- 通过游标进行修改
2. 打开游标
OPEN {{[GLOBAL] cursor_name}|cursor_variable_name}
3. 提取数据
-- 下一行|上一行|第一行|最后一行
FETCH [[NEXT|PRIOR|FIRST|LAST|
ABSOLUTE {n|@nvar}|RELATIVE {n|@nvar}]FROM] -- 指定第几行|相对当前行的第几行
{{[GLOBAL] cursor_name}|cursor_variable_name}
[INTO @variable_name [,...n]] -- 提取到变量中
4. 关闭游标
CLOSE {{[GLOBAL] cursor_name}|cursor_variable_name}
5. 释放游标
DEALLOCATE {{[GLOBAL] cursor_name}|cursor_variable_name}
4.4 定位修改游标
例:声明一个游标,用以更新第五个女生的年龄信息。
USE teaching
DECLARE S_Cur1 SCROLL CURSOR
FOR
SELECT * FROM student WHERE ssex='女'
FOR UPDATE
GO
OPEN S_Cur1
GO
FETCH ABSOLUTE 5 FROM S_Cur1
GO
UPDATE student SET Sage=20
WHERE CURRENT OF S_Cur1 -- CURRENT OF,修改当前游标所指定的行
GO
CLOSE S_Cur1
GO
DEALLOCATE S_Cur1
注意:
(1)定位修改一次只能更新当前游标位置确定的一行。OPEN语句将游标位置定位在结果集第一行前,可以使用FETCH语句把游标位置定位在要被更新的数据行处。
(2)进行定位修改所使用的游标必须声明为FOR UPDATE 方式。进行定位修改数据表中的行时,不移动游标位置。被更新的行可以再次被修改,直到下一个FETCH语句的执行。
(3)定位修改可以更新多数据表或被连接的多表,但只能更新其中一个表的行,即所有被更新的列都来自同一个表。
4.5 定位删除游标
例:声明一个游标,用以删除最后一个女生记录。
USE teaching
DECLARE S_Cur2 SCROLL CURSOR
FOR
SELECT * FROM student WHERE ssex='女'
FOR UPDATE
GO
OPEN S_Cur2
GO
FETCH LAST FROM S_Cur2
GO
DELETE student
WHERE CURRENT OF S_Cur2 -- CURRENT OF,删除当前游标所指定的行
GO
CLOSE S_Cur2
GO
DEALLOCATE S_Cur2
注意:
(1)进行定位删除时,一次只能删除当前游标位置确定的一行,删除后游标位置向前移动一行。OPEN语句将游标位置定位在结果集第一行前,可以使用FETCH语句把游标位置定位在要被删除的行处。
(2)进行定位删除所使用的游标必须声明为FOR UPDATE 方式。而且声明游标的SELECT语句不能含有连接操作或涉及多表。否则,即使声明中指明了FOR UPDATE 方式,也不能删除其中的行。
(3)对使用游标删除行的数据表,要求有一个唯一索引。