数据库(八)之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查询语句,分组,排 ... 
随机推荐
- 学习mysql触发器遇到的问题
			在 mysql.exe 下面运行的.如果是的话, 可能是需要加一个 定义 DELIMITER // 意思是告诉 mysql , 遇到 // 符号以后, 才认为语句结束了. 否则 mysql 遇到 分号 ... 
- [转帖]DAS、SAN、NAS
			http://blog.itpub.net/26736162/viewspace-2214368/ DAS(Direct-attached Storage) 直连存储 直连式存储与服务器主机之间的连接 ... 
- 小程序      获取用户的openid
			wx.login({ success: res => { var code = res.code; //返回code // 小程序appid var appId = 'wxd751fc845c9 ... 
- maven 手动执行下载
			先把命令行切换到Maven项目的根目录,比如:/d/xxxwork/java/maven-test,然后执行命令: mvn clean compile 
- 【刷题】BZOJ 3667 Rabin-Miller算法
			Input 第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数.你需要对于每个数字:第一,检验是否是质数,是质数就输出Prime 第二,如 ... 
- 【2018CCPC秦皇岛】
			递推式的线段树可以用矩阵维护. 
- Android Emoji兼容包使用详解
			Emoji兼容性 我们经常会遇到这样的问题: 给朋友发的emoji表情, 在自己手机上展示是正常的, 但是到朋友手机上, 却没有展示出来, 或者展示出来了, 但是也跟自己手机上展示的不一样. 所以, ... 
- Nginx访问日志分析
			nginx默认的日志格式 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$sta ... 
- phpmyadmin 配置方法
			几乎所有的配置参数都在 config.inc.php 文件中.如果这个文件不存在,您可以在 libraries 目录中找到 config.default.php,将它复制到根目录,并改名为 confi ... 
- 单点登录(十一)-----遇到问题-----cas启用mongodb验证方式报错--Unable to locate Spring NamespaceHandler for XML schema na
			cas启用mongodb验证方式报错--Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.sp ... 
