(1)用BEGIN TRANSACTION明确指定事务的开始
(2)最常用的事务类型
(1)通常会设置SET IMPLICIT_TRANSACTIONS ON语句将隐式事务模式设置为打开
(2) 其后的T-SQL语句会自动启动一个新事务
(3)提交或回滚一个事务后,下一个T-SQL语句又将启动 一个新事务
(1)SQL Server的默认模式
(2)每条单独的T-SQL语句可理解为一个事务
--银行转账业务
DECLARE @ZHA INT=11004,@ZHB INT=11005,@Money INT=10,@errorSum INT=0
BEGIN TRANSACTION
BEGIN
UPDATE [User] SET CurrentMoney-=@Money WHERE ID=@ZHA
SET @errorSum+=@@ERROR --对错误进行累计
UPDATE [User] SET CurrentMoney+=@Money WHERE ID=@ZHB
SET @errorSum+=@@ERROR
IF(@errorSum>0)
BEGIN
PRINT '转账失败!'
ROLLBACK TRANSACTION ---事务回滚
END
ELSE
BEGIN
PRINT '转账成功!'
COMMIT TRANSACTION ----事务提交
END
END
开始事务
BEGIN TRAN[SACTION]
提交事务
COMMIT TRANSACTION
回滚事务(撤销事务)
ROLLBACK TRANSACTION
一旦事务被提交或者被回滚,则该事务都结束
(五)事务处理中的关键问题对事务中的INSERT、UPDATE、DELETE语句实时跟踪
(六)判断某条语句执行是否出错的方法 使用全局变量@@ERROR @@ERROR只判断当前一条T-SQL语句执行是否有错 为了判断事务中所有T-SQL语句是否有错,可以对错误进行累计 (七)事务的使用CREATE PROC sp_BankZhuanZhang
@ZHA INT,
@ZHB INT,
@Money INT
AS
DECLARE @errorSum INT=0
BEGIN TRAN
BEGIN
UPDATE [User] SET CurrentMoney-=@Money WHERE ID=@ZHA
SET @errorSum+=@@ERROR
UPDATE [User] SET CurrentMoney+=@Money WHERE ID=@ZHB
SET @errorSum+=@@ERROR
IF(@errorSum>0)
BEGIN
PRINT '转账失败!'
ROLLBACK TRANSACTION ---事务回滚
END
ELSE
BEGIN
PRINT '转账成功!'
COMMIT TRANSACTION ----事务提交
END
END
二、索引
(一)索引概念
索引是为了加速对表中数据行的检索而创建的一种分散存储结构。它是针对一个表而建立的,每个索引页面中的行都含有逻 辑指针,指向数据表中的物理位置,以便加速检索物理数据。因此,对表中的列是否创建索引,将对查询速度有很大的影响。一个表的存储是由两部分组成的,一部分用来存放表的数据页,另一部分存放索引页。从中找到所需数据的指针,然后直接通过该指针从数据页面中读取数据,从而提高查询速度
(二)索引类型 1.聚集索引表中各行的物理顺序与键值的逻辑顺序相同
(1)主键索引:为表定义一个主键将自动创建主键索引,主要索引是唯一索引的特殊类型
(2)主键索引要求主键中的每个唯一的,并且不能为空
非聚集索引指定表的逻辑顺序
(1)数据存储在一个位置,索引存储在另一位置,索引中包含指向数据存储位置的指针
(2)可以有多个,但小于249个
(3)唯一索引:唯一索引不允许两行具有相同的索引值
CREATE UNIQUE INDEX 索引名称 ON 表名(列名) [WITH FILLFACTOR=X][填充因子]
聚集索引:
CREATE CLUSTERED INDEX 索引名称
非聚集索引:
CREATE NONCLUSTERED INDEX 索引名称
(四)删除索引
DROP INDEX 表名,索引名
删除表时,该表的索引同时被删除
(五)索引的优点1.创建唯一性索引,保证数据库表中每一行数据的唯一性。
2.大大加快数据的检索速度,这也是创建索引的最主要原因。
3.加速表与表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
4.在使用分组和排序子句进行数据检索时,同样可以减少查询中分组和排序的时间。
5.通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能。
1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
2.索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚集索引,那么需 要的空间就会更大。
3.当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,降低了数据的维护速度。
触发器是一种特殊类型的存储过程,当指定表中的数据发生变化时触发器自动生效。它与表紧密相连,可以看做是表定义的一部分。触发器不能通过名称被直接调用,更不允许设置参数。
在SQL Server中一张表可以有多个触发器。用户可以使用INSERT、UPDATE或DELETE语句对触发器进行设置,也可以对一张表上的特定操作设置多个触发器。触发器可以包含复杂的Transact-SQL语句。不论触发器所进行的操作有多复杂,触发器都只作为一个独立的单元被执行,被看作是一个事务。如果在执行触发器的过程中发生了错误,则整个事务将会自动回滚。
1.触发器是自动的。当对表中的数据做了任何修改之后立即被激活。
2.触发器可以通过数据库中的相关表进行层叠修改。
3.触发器可以强制限制。这些限制比用CHECK约束所定义的更复杂。与CHECK约束不同的是,触发器可以引用其他表中的列。
触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂参照完整性和数据的一致性,它能够对数据库中的相关表进行级联修改,提高比CHECK约束更复杂的的数据完整性,并自定义错误消息。触发器的主要作用主要有以下接个方面:
强制数据库间的引用完整性
级联修改数据库中所有相关的表,自动触发其它与之相关的操作
跟踪变化,撤销或回滚违法操作,防止非法修改数据
返回自定义的错误消息,约束无法返回信息,而触发器可以
触发器可以调用更多的存储过程
SqlServer包括三种常规类型的触发器:DML触发器、DDL触发器和登录触发器。
1.DML(数据操作语言,Data Manipulation Language)触发器DML触发器是一些附加在特定表或视图上的操作代码,当数据库服务器中发生数据操作语言事件时执行这些操作。SqlServer中的DML触发器有三种:
insert触发器:向表中插入数据时被触发;
delete触发器:从表中删除数据时被触发;
update触发器:修改表中数据时被触发。
当遇到下列情形时,应考虑使用DML触发器:
通过数据库中的相关表实现级联更改
防止恶意或者错误的insert、update和delete操作,并强制执行check约束定义的限制更为复杂的其他限制。
评估数据修改前后表的状态,并根据该差异才去措施。
DDL触发器是当服务器或者数据库中发生数据定义语言(主要是以create,drop,alter开头的语句)事件时被激活使用,使用DDL触发器可以防止对数据架构进行的某些更改或记录数据中的更改或事件操作。
3.登录触发器登录触发器将为响应 LOGIN 事件而激发存储过程。与 SQL Server 实例建立用户会话时将引发此事件。登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前激发。因此,来自触发器内部且通常将到达用户的所有消息(例如错误消息和来自 PRINT 语句的消息)会传送到 SQL Server 错误日志。如果身份验证失败,将不激发登录触发器。
(五)触发器的工作原理触发器触发时:
系统自动在内存中创建deleted表或inserted表;
只读,不允许修改,触发器执行完成后,自动删除。
inserted表:
临时保存了插入或更新后的记录行;
可以从inserted表中检查插入的数据是否满足业务需求;
如果不满足,则向用户发送报告错误消息,并回滚插入操作。
deleted表:
临时保存了删除或更新前的记录行;
可以从deleted表中检查被删除的数据是否满足业务需求;
如果不满足,则向用户报告错误消息,并回滚插入操作。
inserted表和deleted表对照:
修改操作记录 | inserted表 | deleted表 |
---|---|---|
增加(insert)记录 | 存放新增的记录 | 无 |
删除(deleted)记录 | 无 | 存放被删除的记录 |
修改(update)记录 | 存放更新后的记录 | 存放更新前的记录 |
触发器参考文章链接
四、游标 (一)游标概念游标提供了一种从表中检索数据并进行操作的灵活手段,游标主要用在服务器上,处理由客户端发送给服务器端的SQL语句,或是批处理、存储过程、触发器中的数据处理请求。游标的优点在于它可以定位到结果集中的某一行,并可以对该行数据执行特定操作,为用户在处理数据的过程中提供了很大方便。
(二)游标分类SQL Server提供了4种类型的游标,静态游标、动态游标、只进游标和键集驱动游标。这些游标检测结果集变化的能力和内存占用的情况都有所不同,数据源没有办法通知游标当前提取行的更改。游标检测这些变化的能力也受事务隔离级别的影响。
1.静态游标静态游标的完整结果集在游标打开时建立在tempdb中。静态游标总是按照游标打开时的原样显示结果集。静态游标在滚动期间很少或根本检测不到变化,虽然它在tempdb中存储了整个游标,但消耗的资源很少。尽管动态游标使用tempdb的程度最 低,在滚动期间它能够检测到所有变化,但消耗的资源也更多。键集驱动游标介于二者之间,它能检测到大部分的变化,但比动态游标消耗更少的资源。
2.动态游标动态游标与静态游标相对。当滚动游标时,动态游标反映结果集中做的所有更改。结果集中的行数据值、顺序和成员在每次 提取时都会改变。所有用户做的全部UPDATE、INSERT和DELETE语句均通过游标可见
3.只进游标只进游标不支持滚动,它只支持游标从头到尾顺序提取。只在从数据库中提取出来后才能进行检索。对所有由当前用户发出或由其他用户提交、并影响结果集中的行的INSERT、UPDATE和DELETE语句,其效果在这些行从游标中提取时是可见的。
4.键集驱动游标打开游标时,键集驱动游标中的成员和行顺序是固定的。键集驱动游标由一套被称为键集的惟一标识符(键)控制。键由以 惟一方式在结果集中标识行的列构成。键集是游标打开时来自所有适合SELECT语句的行中的一系列键值。键集驱动游标的键集在游标打开时建立在tempdb中。对非键集列中的数据值所做的更改(由游标所有者更改或其他用户提交)在用户滚动游标 时是可见的。在游标外对数据库所做的插入在游标内是不可见的,除非关闭并重新打开游标