T-SQL编程

目录

1、T-SQL的元素

[1.1 标识符](#1.1 标识符)

[1. 常规标识符](#1. 常规标识符)

[2. 分隔标识符](#2. 分隔标识符)

[1.2 变量](#1.2 变量)

[1. 全局变量](#1. 全局变量)

[2. 局部变量](#2. 局部变量)

[1.3 运算符](#1.3 运算符)

[1. 算数运算符](#1. 算数运算符)

[2. 赋值运算符](#2. 赋值运算符)

[3. 位运算符](#3. 位运算符)

[4. 比较运算符](#4. 比较运算符)

[5. 逻辑运算符](#5. 逻辑运算符)

[6. 字符串连接运算符](#6. 字符串连接运算符)

[7. 一元运算符](#7. 一元运算符)

[8. 运算符的优先级和结合性](#8. 运算符的优先级和结合性)

[1.4 批处理](#1.4 批处理)

[1.5 注释](#1.5 注释)

2、流程控制语句

[2.1 BEGIN...AND](#2.1 BEGIN…AND)

[2.2 IF...ELSE](#2.2 IF…ELSE)

[2.3 CASE](#2.3 CASE)

[2.4 WHILE...CONTINUE...BREAK](#2.4 WHILE…CONTINUE…BREAK)

[2.5 RETURN](#2.5 RETURN)

[2.6 RAISERROR](#2.6 RAISERROR)

3、函数

[3.1 系统内置函数](#3.1 系统内置函数)

[3.2 用户自定义函数](#3.2 用户自定义函数)

[1. 标量值函数](#1. 标量值函数)

[2. 内联表值函数](#2. 内联表值函数)

[3. 多语句表值函数](#3. 多语句表值函数)

4、游标

[4.1 游标的概述](#4.1 游标的概述)

[4.2 游标的类型](#4.2 游标的类型)

[1. 只进游标](#1. 只进游标)

[2. 静态游标](#2. 静态游标)

[3. 键集游标](#3. 键集游标)

[4. 动态游标](#4. 动态游标)

[4.3 游标的使用](#4.3 游标的使用)

[1. 声明游标](#1. 声明游标)

[2. 打开游标](#2. 打开游标)

[3. 提取数据](#3. 提取数据)

[4. 关闭游标](#4. 关闭游标)

[5. 释放游标](#5. 释放游标)

[4.4 定位修改游标](#4.4 定位修改游标)

[4.5 定位删除游标](#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):局部变量名由"@"符号开始。一定要先定义再使用。

sql 复制代码
DECLARE {@local_variable data_type}[,...n]

赋值(SET|SELECT):

sql 复制代码
-- 只能对单个变量赋值
SET {@local_variable = expression}
--可对多个变量赋值
SELECT {@local_variable = expression}[,...n]

输出(PRINT|SELECT):

sql 复制代码
-- 只能单个字符串|局部变量|字符串表达式
PRINT {msg_str|@local_variable|string_expr}
-- 可以多个局部变量的值
SELECT {@local_variable}[,...n]

局部变量的作用域:批处理(go),过程(procedure)中。

例:

sql 复制代码
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. 算数运算符

加(+),减(-),乘(*),除(/),取模(%)。

注意:取模(%),只能是****inttinyintsmallint

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

sql 复制代码
BEGIN
{sql_statement|statement_block}
END

sql_statement|statement_block:T-SQL语句|语句块。

BEGIN...END主要用于下列情况

WHILECASEIF...ELSE

BEGIN...END可以嵌套

2.2 IF...ELSE

sql 复制代码
IF Boolean_expression
{sql_statement|statement_block}
[ELSE {sql_statement|statement_block}]

IF...ELSE语句可以嵌套。

如果Boolean_expression中有SELECT语句,要加**()**。

例:如果,学号"20160211"的学生选修的,课程号为"0101"的课程成绩>=90,"成绩优秀",否则"成绩一般"。

sql 复制代码
USE teaching
GO
IF ( SELECT score FROM  sc  WHERE sno='20160211'  and cno='0101') >=90
  PRINT '成绩优秀'
ELSE
  PRINT '成绩一般' 

2.3 CASE

简单CASE格式:(CASE后面)某个表达式与(WHEN后面)一组简单表达式或常量进行比较,以确定结果。

搜索CASE格式:计算(WHEN后面)一组布尔表达式,以确定结果。

例:查询所有学生的考试等级,包括学号,课程号,成绩等级(优秀,良好,中等,及格,不及格)

简单CASE: 整数/整数 = 整数

sql 复制代码
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(推荐):

sql 复制代码
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

sql 复制代码
WHILE Boolean_expressionession
[BEGIN]
sql_statement|statement_block [BREAK|CONTINUE]
[END]

例:求1到100的累加,并输出。

sql 复制代码
DECLARE @i int,@sum int
SELECT @i = 1,@sum = 0
WHILE @i <= 100
  BEGIN
    SET @sum = @sum+@i
    SET @i = @i+1
  END
SELECT @sum as 'sum',@i as 'i'

2.5 RETURN

可以从查询或过程中无条件退出。

2.6 RAISERROR

RAISERROR:将错误信息显示在屏幕上,同时也可以记录在NT日志中。

sql 复制代码
RAISERROR{{msg_id|msg_str},severity,state}

msg_id|msg_str:错误信息。

severity:错误的严重级别。

state:发生错误时的状态信息。

如:

sql 复制代码
RAISERROR('NO !',16,1)

3、函数

3.1 系统内置函数

聚合函数,数学函数,日期和时间函数,字符串函数。

强制类型转换函数

CAST( expression AS data_type[(length)] )

如:把int类型的@age强制转换为char(2)类型

sql 复制代码
CAST(@age as char(2))

CONVERT(data_type[(length),expression[,style])

3.2 用户自定义函数

1. 标量值函数

一般需要declare变量

sql 复制代码
CREATE FUNCTION [schema_name.]function_name
([{@parameter_name parameter_data_type [= default_expression]}[,...n]])
RETURNS return_data_type
[AS] -- 一般不省略
  BEGIN
    function_body
	RETURN expression
  END
GO

注意:调用标量值函数,需要指定架构名默认dbo

例:创建一个标量值函数,接受学号,返回该学号的平均成绩。

sql 复制代码
use teaching
go
create function avgscore(@sno char(8))
returns tinyint
as
begin
  declare @avgscore tinyint
  select @avgscore=avg(score)
  from sc
  where sno = @sno
  return @avgscore
end
go
-- 调用标量值函数,需要指定架构名,默认为dbo
select dbo.avgscore('20160211') as '平均成绩'
2. 内联表值函数

一般不需要declare变量

sql 复制代码
CREATE FUNCTION [schema_name.]function_name
([{@parameter_name parameter_data_type [= default_expression]}[,...n]])
RETURNS TABLE
[AS] -- 一般不省略
RETURN(select_statement)

注意:内联表值函数返回的是

例1:创建一个内联表值函数,查询各个专业的专业名称及学生人数的。

sql 复制代码
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:创建一个内联表值函数,接受课程号,返回该课程号的选修信息,不传课程号,就返回所有课程号的选修信息。

sql 复制代码
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. 多语句表值函数

可以自定义返回表结构

sql 复制代码
CREATE FUNCTION [schema_name.]function_name
([{@parameter_name parameter_data_type [= default_expression]}[,...n]])
RETURNS @return_variable TABLE<table_definition>
[AS] -- 一般不省略
BEGIN
  function_body
  RETURN
END

例:创建一个多语句表值函数,查询选修特定课程名的学号,姓名,课程号,课程名,成绩

sql 复制代码
use teaching
go
create function KCM_XK(@cname varchar(32))
-- 返回的表名必须是局部变量名的形式(@)
returns @xk table(学号 char(8),姓名 varchar(10),
课程号 char(4),课程名 varchar(32),成绩 tinyint)
as
begin
  insert 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.cno
  where c.cname = @cname
  return
end
go
select * from KCM_XK('C语言')

4、游标

4.1 游标的概述

游标 是处理数据的一种方式,它允许应用程序每一次处理一行或一部分行

游标可以看作一个指针 ,可以指定结果中的任何位置

4.2 游标的类型

1. 只进游标

FORWARD_ONLY,即只进游标只能第一行滚动到最后一行

2. 静态游标

STATIC静态游标打开时创建 一个数据快照 ,该快照不会随着后续数据库的修改而改变

静态游标是在数据快照上进行操作。

3. 键集游标

KEYSET键集游标 在打开时,会固定结果集成员身份和顺序 。这意味着,当游标打开后,即使底层数据表中的数据发生变化,游标所指向的行集也不会改变(除非这些行的键被更改)。然而,与静态游标不同的是,如果结果集中的行由于键的更改而被删除或更新 ,这些更改在键集游标中可见的。

4. 动态游标

DYNAMIC动态游标 与静态游标相对,反映结果集中所做的所有更改

4.3 游标的使用

1. 声明游标
sql 复制代码
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. 打开游标
sql 复制代码
OPEN {{[GLOBAL] cursor_name}|cursor_variable_name}
3. 提取数据
sql 复制代码
-- 下一行|上一行|第一行|最后一行
FETCH [[NEXT|PRIOR|FIRST|LAST|
ABSOLUTE {n|@nvar}|RELATIVE {n|@nvar}]FROM] -- 指定第几行|相对当前行的第几行
{{[GLOBAL] cursor_name}|cursor_variable_name}
[INTO @variable_name [,...n]] -- 提取到变量中
4. 关闭游标
sql 复制代码
CLOSE {{[GLOBAL] cursor_name}|cursor_variable_name}
5. 释放游标
sql 复制代码
DEALLOCATE {{[GLOBAL] cursor_name}|cursor_variable_name}

4.4 定位修改游标

例:声明一个游标,用以更新第五个女生的年龄信息。

sql 复制代码
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 定位删除游标

例:声明一个游标,用以删除最后一个女生记录。

sql 复制代码
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)对使用游标删除行的数据表要求有一个唯一索引

相关推荐
Lzc77414 天前
视图和索引
sql server 2014·数据库原理及应用
Lzc77415 天前
数据库的概念和操作
数据库原理与应用·sql server 2014