数据库(八)之T-SQL编程
什么是Transact-SQL?
结构化查询语言(SQL)是有美国国家标准协会(ANSI)和国际标准化组织(ISO)定义的标准,而Transact-SQL是Microsoft公司对此标准的一个实现。
transact-SQL语言是结构化查询语言(SQL)的增强版本,与多种ANSI SQL标准兼容,而且在标准的基础上还进行了许多扩展。Transact-SQL代码已成为SQL Server的核心。Transact-SQL在关系数据库管理系统中实现数据的检索,操纵和添加功能。
分类
在Microsoft SQL Server 2008系统中,Transact-SQL可以创建,维护,保护数据对象中的数据,所以Transact-SQL语言是一种完整的语言。根据T-SQL语言的执行功能特点,可以将T-SQL语言分为三种基本类型:
- 数据定义语言
- 数据操纵语言
- 数据控制语言
还有一些其他类型:
- 数据控制语言
- 流程控制语言
- 附加的语言元素
常量与变量
变量声明:
declare
{@local_variable[as]data_type | @cursor_variable_name CURSOR
}[,…n]
赋值:
要给声明的局部变量赋值,可以使用set或select语句,格式如下:
set @local_variable = expression
select @local_variable = expression [,…n]
例子:
declare @name nvarchar(50)
set @name = 'Bob'
select @name = 'Peter'
select @name
print @name
运算符:
算术运算符:
位运算符:
比较运算符:
逻辑运算符:
其他运算符:
表达式:
注释:
if…else语句:
语法格式:
if boolean_expression
{sql_statement | statement_block}
else
{sql_statement | statement_block}
例子:
declare @num int
select @num = avg(分数) from 成绩信息
where 考试编号 = '0802' and 课程编号 = '2'
if @num > 80
begin
print 'good'
end
else
begin
print 'bad'
end
if…else语句嵌套
declare @num int
select @num = avg(分数) from 成绩信息
where 课程编号 = '2' and 考试编号 = '0802'
if @num >= 60
begin
if @num < 70
print 'just so so'
else if @num < 80
print 'mid'
else if @num < 90
print 'good'
else
print 'wonderful'
end
else
begin
print 'terrible'
end
case 语句
语法格式:
case input_expression
when when_expresion then result_expression
[…n]
[else else_result_expression]
end
例子:
select 员工姓名,所任职位,员工职称 =
case 所任职位
when '经理' then '高级职称;
when '主管' then '中级职称'
when '职员' then '初级职称'
else '其他职称'
end
from 员工信息
while 语句
while boolean_expression
{sql_statement | statement_block}
[break]
{sql_statement | statement_block}
[continue]
{sql_statement | statement_block}
例子:
declare @i int, @sum int
set @i = 1
set @sum = 0
while @i <= 10
begin
set @sum = @sum + @i
set @i = @i + 1
end
select @sum as result
例2:
declare @i int
declare @j int
set @i = 3
while @i <= 100
begin
declare @bol int
set @bol = 1
set @j = 2
while @j <= sqrt(@i)
begin
if @i % @j = 0
begin
set @bol = 0
break
end
set @j = @j + 1
end
if @bol = 1 print @i
set @i = @i + 1
end
wati for延迟语句
语法格式:
waitfor
{
delay time | time time
}
例子:
watifor delay '00:00:05'
exec sp_helpdb
例2:
waitfor time '11:20:00'
select getdate()
goto语句
例子:
declare @Counter int
set @Counter = 1
while @Counter < 10
begin
print @Counter
set @Counter = @Counter + 1
if @Counter = 1 goto branch_one
else @counter = 2 goto branch_two
else goto branch_three
end
branch_one:
print 'Jumping to branch one'
goto branch_three
branch_two:
print 'Jumping to branch two'
branch_three:
print 'Jumpint to branch_three'
try … catch错误处理语句
begin try
{sql_statement | statement_block}
end try
begin catch
{sql_statement | statement_block}
end catch
例子:
begin try
declare @num int
set @num = 1/0
select @num
end try
begin catch
select error_line() as '错误行数', error_message() '错误消息'
end catch
数学函数
abs 绝对值
exp 返回指定表达式以e为底的指数
ceiling 返回大于或等于数值表达式的最小整数
floor 返回小于或等于数值表达式的最大整数
ln 返回数值表达式的自然对数
log
power
round 返回舍入到指定长度或精度的数值表达式
sign 返回+,-或0
square 返回数值表达式的平方
sqrt 返回数值表达式的平方根
字符串函数
ascii 返回字符表达式中最左侧的字符的ascii代码值
char ascii代码转换函数,返回指定ascii代码的字符
left 左字串函数,返回字符串中从左边开始指定个数的字符
len 字符串函数,返回指定字符串表达式的字符数,其中不包含尾随空格
lower 小写字母函数,将大写字符数据转换位小写字符数据后返回字符表达式
ltrim 删除前导空格字符串,返回删除了前导空格之后的字符表达式
replace 替换函数,用第三个表达式替换第一个字符串表达式中出现的所有第二个指定字符串表达式的匹配项
replicate 赋值函数,以指定的词数重复字符表达式
right 右子串函数,返回字符串中从右边开始指定个数的字符
rtrim 删除尾随空格函数,删除所有尾随空格后返回一个字符串
space 空格函数,返回由重复空格组成的字符串
str 数字向字符转换函数,返回由数字数据转换来的字符数据
substring 字串函数,返回字符表达式,二进制表达式,文本表达式或图像表达式的一部分
upper 大写函数,返回小写字符数据转换为大写的字符表达式
字符串函数
charindex()
返回字符串中某个指定的字串出现的开始位置。
charindex(<'substring_expression'>, <expression>)
其中substring_expression是所要查找的字符表达式,expression可以为字符串也可为列名表达式。如果没有发现子串,则返回0值
此函数不能用于test和image数据类型
patindex()
返回字符串中某个指定的子串出现的开始位置
patindex(<'%substring_expression%'>, <column_name>)其中子串表达式前后必须有百分号‘%’否则返回值为0
与charindex函数不同的是,patindex函数的子串中可以使用通配符,且此函数可用于char,varchar和test数据类型。
例子:
declare @str1 nvarchar(20),
@str2 nvarchar(20),
@str3 nvarchar(20),
@str4 nvarchar(20),
@str5 nvarchar(20)
set @str1 = '上海分公司经理'
set @str2 = '北京分公司经理'
set @str3 = '天津分公司经理'
set @str4 = '上海分公司财务经理'
set @str5 = '天津分公司财务经理'
select charindex('经理', @str4)
select right(@str4, len(@str4) - charindex('分公司', @str4) + 1)
聚合函数
avg 平均值
count 计数
max 最大值
min 最小值
sum 求和
例子:
select avg(分数) as 平均成绩
from 成绩信息
where 考试编号 = '0801' and 课程编号 = '2'
select sum(分数) as 总分数
from 成绩信息
where 考试编号 = '0801' and 课程编号 = '2'
select min(分数) as 最低分
from 成绩信息
where 考试编号 = '0801' and 课程编号 = '2'
select max(分数) as 最高分
from 成绩信息
where 考试编号 = '0801' and 课程编号 = '2'
select count(分数) as 人数
from 成绩信息
where 考试编号 = '0801' and 课程编号 = '2'
日期和时间函数
dateadd 返回给指定日期加上一个时间间隔后的新datetime值
datediff 返回跨两个日期的日期边界数和时间边界数
datename 返回表示指定日期的指定日期部分的字符串
datepart 返回表示指定日期的指定日期部分的整数
day 返回一个整数,表示指定日期的天datepart部分。
getdate 以datetime值得SQL Server 2008标准内部格式返回当前系统日期和时间
getutcdate 返回表示当前得utc时间得datetime值。
month 返回表示指定日期得“月”部分的整数
year 返回表示指定日期的年份的整数。
例子:
select GETDATE() as 日期
select GETutcDATE() as 日期
select YEAR(getdate())
select month(getdate())
select day(getdate())
select DATEPART(YY, GETDATE())
select DATEPART(mm, GETDATE())
select DATEPART(dd, GETDATE())
select DATEADD(DD, 1, GETDATE())
标量值函数
语法格式:
create function function_name
([{@parament_name scalar_parameter_data_type [ = default]}[,…n]])
returns scalar_return_data_type
[with encryption]
[as]
begin
function_body
return scalar_expression
end
例子:
create function sorceAve(@id, nvarchar(50))
returns int
as
begin
declare @score int
select @sorce = avg(分数) from 成绩信息
where 课程编号 = @id
return @score
end
go
select dbo.sorceAvg('2')
表值函数
语法格式:
create function function_name
([{@parameter_name scalar_parameter_data_type [ = default]}[,…n]])
returns table
with encryption
as
return (select_statement)
例子:
create function findSorce(@id varchar(10))
returns table
as
return (
select 课程名称,姓名,分数 from (
select B.课程名称, c.姓名, avg(A.分数) 分数
from 成绩信息 A join 课程信息 B
on A.课程编号 = B.课程编号
join 教师信息 c on b.任课教师 = c.教师编号
where A.考试编号= @id
group by B.课程编号, C.姓名
) a
where 分数 >= 85
)
select * from findcourse('0802')
游标
什么是游标?
游标(Cursor)是一种数据访问机制,它允许用户访问单独的数据行,而不是对整个行集进行操作。
用户可以通过单独处理每一条逐行收集信息并对数据逐行进行操作,这样可以降低系统开销和潜在的
阻隔情况。用户也可以使用这些数据生成SQL代码并立即执行或输出。
游标主要包括以下两个部分:
(1)游标结果集 由定义游标的select语句返回的行的集合。
(2)游标位置 指向这个结果集中的某一行的指针。
游标的特点:
游标返回一个完整的结果集,但允许程序设计语言只调用集合中的一行。
允许定位在结果集中的特定行。
从结果集的当前位置检索一行或多行
支持对结果集中当前位置的行进行数据修改。
可以为其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性支持。
提供脚本,存储过程和触发器中使用的访问结果集中数据的T-SQL语句。
语法格式:
declare cursor_name [insensitive] [scroll] cursor
for select_statement
[for{read only|update [of column_name [,…n]]}]
例子:
declare student_cursor scroll cursor
for
select * from 学生信息
for read only
declare student_cursor cursor
for
select * from 学生信息
for update
释放游标
deallocate student_cursor
操作有标
打开游标 open{{[global] cursor_name} | cursor_variable_name}
检索游标 fetch
[[next | prior | first | last | absolute { n | @nvar } | relative{n|@nvar}]
from]
{{[global] cursor_name} | @cursor_variable_name }
[into @variable_name[,…n]]
关闭游标 close {{[global] cursor_name} | @cursor_variable_name}
释放游标 deallocate {{[global] cursor_name} | @cursor_variable_name}
例子:
declare stu_cursor scroll cursor for
select 姓名 from 学生信息
declare @name varchar(20)
open stu_cursor
fetch next from stu_cursor into @name
close stu_cursor
deallocate stu_cursor
print @name
游标可选项:next, prior, first, last, absolute
判断游标提取状态
@@fetch_statue
0, fetch 语句成功
-1, fetch 语句失败或行不在结果集中
-2 提取的行不存在
例子:
declare stu_cursor scroll cursor for
select 姓名 from 学生信息
open stu_cursor
declare @name varchar(20)
fetch next from stu_cursor into @name
if @@fetch_status = 0
print @name
else
print 'error'
close stu_cursor
deallocate stu_cursor
游标应用示例
declare stu_cursor scroll cursor for
select 学号 from 学生信息
create table #t(name nvarchar(20), sorce int)
open stu_cursor
fetch next from stu_cursor into @name
while @@fetch_status = 0
begin
insert into #t
select B.姓名, avg(分数) as 分数
from 成绩信息 A join 学生信息 B
on A.学生编号 = B.学号
where A.考试编号 = '0801' and B.学号 = @name
group by B.姓名
fetch next from stu_cursor into @name
end
close stu_cursor
deallocate stu_cursor
select name 姓名, sorce 平均分数 from #t
drop table #t
例2
declare stu_cursor scroll cursor for
select 姓名from 学生信息
create table #t_name(姓名 varchar(20))
declare @name varchar(20)
open stu_cursor
fetch next from stu_cursor into @name
while @@fetch_status = 0
begin
insert into #t_name values(@name)
fetch next from stu_cursor into @name
end
close stu_cursor
deallocate stu_cursor
select * from #t_name
drop table #t_name
事务
在SQL Server 2008中只要使用下列4条语句管理事务:
begin transaction
commit transaction
rollback transaction
save transaction
例子:
begin transaction
declare @nation varchar(20)
set @nation = '汉族'
insert into 学生信息
values('2111605165', '小龙', '男', '1999-1-1', @nation, 102, '上海', '111111')
if @nation = '汉族'
begin
commit transaction
end
else
rollback transaction
锁
所谓锁,就是一个事务可向系统提出请求,对被操作的数据加锁(lock)。其他事务必须
等到此事务解锁(unlock)之后才能访问该数据。从而,在多个用户并发访问数据库时,
确保不互相干扰。可封锁的单位是:行,页,表,盘区和数据库。
锁的类型
共享锁(S) :用于读操作。
多个事务可封锁一个共享单位的数据。
任何事物都不能修改加S锁的数据。
通常是加S锁的数据被读取完毕,S锁立即被释放。
独占(X)锁:用于写操作。
仅允许一个事务封锁此共享数据。
其他任何事物必须等到X锁被释放才能对该数据进行访问。
X锁一直到事务结束才能被释放。
更新(U)锁
用来预定对此页施加X锁,它允许其他事务读,但不允许再施加U锁或X锁。
当被读取数据页要被更新时,则升级为X锁。
U锁一直到事务结束时才能被释放。
系统与元数据函数
convert() 讲一种数据类型的数据转变为另一种数据类型的数据。
current_user() 返回当前用户的名称。
isdate() 判断它的输入是不是一个有效日期。
isnull() 用一个指定替换值替换任何空值。
isnumeric() 判断它的输入是不是一个数值。
例子:
declare @str varchar(10), @i int, @j int
set @str = '12'
set @i = 10
if isnumeric(@str) = 1
begin
print convert(int, @str) *i
end
print isnull(@j, 10) @i
begin…end语句块
begin
{
sql_statement | statement_block
}
end
例子:
declare @sex varchar(5)
if @sex is not null
begin
select * from 学生信息 where 性别 = @sex
print '查询成功'
end
else
begin
print '查询失败'
end
事务模式
自动提交事务 每条单独的语句都是一个事务
显示事务 每个事务均以begin transaction开始,以commit或rollback语句显
式结束。
隐式事务 在前一个事务完成时新事物隐式启动,但每个事务仍以commit或
rollback语句显示完成。
批处理级事务 只能用于多个活动结果集(MARS),在MARS会话中启动的Transact-
SQL显示或隐式事务变为批处理级事务。当批处理完成时没有提交
或回滚的批处理级事务自动由SQL Server进行回滚。
xact_abort选项
xact_abort选项用于指定当SQL语句出现运行时错误时,SQL Server是否自动回滚当前
事务。其语法格式如下所示:
set xact_abort{on | off}
当set xact_abort为on时,如果执行SQL语句产生运行时错误,则整个事务将终止并回滚
当set xact_abort为off时,有时只回滚产生错误的SQL语句,而事务将继续进行处理。
如果错误很严重,那么即使set xact_abort为off,也可能回滚整个事务。
set xact_abort的设置是在执行或运行时设置,而不是在分析时设置。对于大多数ole db
提供程序,必须将隐式或显示事务中的数据修改语句中的xact_abort设置为on。唯一不
需要该选项的情况是在提供程序支持嵌套事务时。
死锁
所谓死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待
的现象,若无外力作用,它们都将无法推进下去,此时称系统处于死锁状态或系统产生
了死锁,这些永远在互相等待的进程称为死锁进程。
由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,
永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。
一种情形,此时执行程序中两个或多个线程发生永久阻塞(等待),每个线程都在等待
被其他线程占用并阻塞了的资源。例如,如果线程A锁住了记录1并等待记录2,而
线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象。
必要条件:
互斥条件 一个资源每次只能被一个进程使用
请求与保存条件:一个进程因请求资源阻塞,对已获得的资源保持不妨
不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发送死锁,这些条件必然成立,而只要
上述条件之一不满足,就不会死锁。
死锁的解除和预防:
按同一顺序访问对象
避免事务中的用户交互
保持事务简短并在一个批处理中
使用低隔离级别
使用绑定连接
死锁的建议:
对于频繁使用的表使用集簇化的索引
设法避免一次性影响大量记录的T-SQL语句,特别是insert和update语句
设法让update和delete语句使用索引
使用嵌套事务时,避免提交和回退冲突
对一些数据不需要及时读取更新值得表在写SQL得时候在表后台加上nolock
如:select * from tableA(nolock)
嵌套事务:
begin transaction t1
update 班级信息 set 班级名 = '金融管理系1班'
where 班级编号 = '20180101'
if exist(select * from 班级信息 where 班级名 = '金融管理系1班')
begin
begin transaction t2
update 班级信息 set 辅导员 = '李民'
where 班级名 = '金融管理系1班'
if exist(select * from 辅导员信息 where 姓名 = '李民'
commit transaction t2
else
begin
rollback transaction t2
end
commit transaction t1
end
else
rollback transaction t1
数据库(八)之T-SQL编程的更多相关文章
- Oracle数据库建表并用SQL编程分等级
--创建学生表create table XS_543 ( XH char(6) not null , XM varchar2(20) not null, ZYM varchar2(10), XB ch ...
- 数据库之SQL编程
定义局部变量 declare @num int 途径一: 途径二: set 和select赋值方式的区别 唯一区别,如果从数据库表中获取数据,只能用 select ) select @name =st ...
- SQL Server数据库(SQL Sever语言 函数以及SQL编程)
1.数学函数:操作一个数据,返回一个结果 --去上限: ceiling ☆select ceiling(price) from car --去下限:floor ☆select floor(price) ...
- 【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航
原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人 ...
- Oracle数据库编程:PL/SQL编程基础
2.PL/SQL编程基础: PL/SQL块: declare 定义部分 begin 执行部分 exception 异 ...
- pl/sql编程
body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...
- SQL编程的一些良好好习惯
|转载自:cnblog |原文链接:http://www.cnblogs.com/MR_ke/archive/2011/05/29/2062085.html 我们做软件开发的,大部分人都离不开跟数据库 ...
- SQL编程篇 (二) 定义与流程控制
分类: sql编程:标准的sql 编程 * 纯sql 在标准的编程中又分为 sqlserver-->T-sql oracle-->pl-sql(扩展) 变量:在使用变量之前先定义 声明变量 ...
- Oracle 数据库 基础学习 (一) SQL基本知识
Oracle 从零开始,不知所措.要掌握一种技能,最好的方式是先学会怎么使用它,然后再深入学习,先有样子,再有技术. 一,什么是数据库? 为什么需要数据库? 数据库实质上是一个信息的列表,或者是一 ...
- SQL Server(六)——索引、视图和SQL编程
1.索引 添加索引,设计界面,在任何一列前右键--索引/键--点击进入添加某一列为索引 2.视图 视图就是我们查询出来的虚拟表 创建视图:create view 视图名 as SQL查询语句,分组,排 ...
随机推荐
- PAT 甲级 1151 LCA in a Binary Tree
https://pintia.cn/problem-sets/994805342720868352/problems/1038430130011897856 The lowest common anc ...
- 【SQLSERVER】动态游标的实现
方法1: CREATE TABLE #tabTmp(id int) INSERT #tabTmp EXECUTE('SELECT id FROM '+@Table ...
- 钉钉开发c#帮助类 获取用户信息 DingHelper.cs
using System;using System.Collections.Generic;using System.Configuration;using System.Linq;using Sys ...
- VS2012 Nuget 安装 AutoMapper时报错的解决方法
VS2012 在.net 4.0下安装AutoMapper时,会报以下错误: “AutoMapper”已拥有为“Standard.Library”定义的依赖项. 'AutoMapper' alread ...
- 【Java并发编程】之一:可重入内置锁
每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...
- jenkins+maven+Tomcat8实现热部署
个人记录 公司使用jenkins实现代码自动更新并部署 采用jenkins安装方式为war包,版本为:2.138.3,启动方式为Tomcat启动jenkins, 该博客操作步骤有些地方进行简化,各位需 ...
- python爬虫实战之bilibili弹幕生成云图
突然想到了这个题目,先开了题,看能不能一次搞定,#后记,花了两天时间搞定的,一直想用自己的方法爬,但是效果都不好 首先去分析一下bilibili的网站请求,但是弹幕的异步传输的包抓不到(或者隐藏的好, ...
- mysql测试索引在表中的作用
//未完成 参考书:(完成对缓存中执行计划的查看对比 P133~) Microsoft SQL Server 2008技术内幕:T-SQL查询 实验内容 单表中的索引使用 1.建表 create ta ...
- c++11 委托构造
c++11 委托构造 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #includ ...
- Zju1610 Count the Colors
题面: 画一些颜色段在一行上,一些较早的颜色就会被后来的颜色覆盖了. 你的任务就是要数出你随后能看到的不同颜色的段的数目. Input: 每组测试数据第一行只有一个整数n, 1 <= n < ...