加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQL Server 事务、异常和游标

发布时间:2020-12-12 09:03:42 所属栏目:MsSql教程 来源:网络整理
导读:建议先阅读存储过程: ? 事务 在数据库中有时候需要把多个步骤的指令当作一个整体来运行,这个整体要么全部成功,要么全部失败,这就需要用到事务。 ??? 1、 事务的特点 ??????? 事务有若干条T-SQL指令组成,并且所有的指令昨晚一个整体提交给数据库系统,执

建议先阅读存储过程:

? 事务

在数据库中有时候需要把多个步骤的指令当作一个整体来运行,这个整体要么全部成功,要么全部失败,这就需要用到事务。

??? 1、 事务的特点

??????? 事务有若干条T-SQL指令组成,并且所有的指令昨晚一个整体提交给数据库系统,执行时,这组指令要么全部执行完成,要么全部取消。因此,事务是一个不可分割的逻辑单元。

?

??????? 事务有4个属性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)以及持久性(Durability),也称作事务的ACID属性。

??????? 原子性:事务内的所有工作要么全部完成,要么全部不完成,不存在只有一部分完成的情况。

??????? 一致性:事务内的然后操作都不能违反数据库的然后约束或规则,事务完成时有内部数据结构都必须是正确的。

??????? 隔离性:事务直接是相互隔离的,如果有两个事务对同一个数据库进行操作,比如读取表数据。任何一个事务看到的所有内容要么是其他事务完成之前的状态,要么是其他事务完成之后的状态。一个事务不可能遇到另一个事务的中间状态。

??????? 持久性:事务完成之后,它对数据库系统的影响是持久的,即使是系统错误,重新启动系统后,该事务的结果依然存在。

?

??? 2、 事务的模式

??????? a、 显示事务

??????? 显示事务就是用户使用T-SQL明确的定义事务的开始(begin transaction)和提交(commit transaction)或回滚事务(rollback transaction)

??????? b、 自动提交事务

??????? 自动提交事务是一种能够自动执行并能自动回滚事务,这种方式是T-SQL的默认事务方式。例如在删除一个表记录的时候,如果这条记录有主外键关系的时候,删除就会受主外键约束的影响,那么这个删除就会取消。

??????? 可以设置事务进入隐式方式:set implicit_transaction on;

??????? c、 隐式事务

??????? 隐式事务是指当事务提交或回滚后,SQL Server自动开始事务。因此,隐式事务不需要使用begin transaction显示开始,只需直接失业提交事务或回滚事务的T-SQL语句即可。

??????? 使用时,需要设置set implicit_transaction on语句,将隐式事务模式打开,下一个语句会启动一个新的事物,再下一个语句又将启动一个新事务。

?

??? 3、 事务处理

??????? 常用T-SQL事务语句:

??????? a、 begin transaction语句

??????? 开始事务,而@@trancount全局变量用来记录事务的数目值加1,可以用@@error全局变量记录执行过程中的错误信息,如果没有错误可以直接提交事务,有错误可以回滚。

??????? b、 commit transaction语句

??????? 回滚事务,表示一个隐式或显示的事务的结束,对数据库所做的修改正式生效。并将@@trancount的值减1;

??????? c、 rollback transaction语句

??????? 回滚事务,执行rollback tran语句后,数据会回滚到begin tran的时候的状态

?

??? 4、 事务的示例

tran_bank; @tran_error ; @tran_error = 0; try bank totalMoney = totalMoney - 10000 userName = ; @tran_error = @tran_error + @@error; bank totalMoney = totalMoney + 10000 userName = ; @tran_error = @tran_error + @@error; try catch + (,error_number()) + + error_message(); @tran_error = @tran_error + 1; catch (@tran_error > 0) --执行出错,回滚事务 ; ; --没有异常,提交事务 ; ;go

? 异常

???? 在程序中,有时候完成一些Transact-SQL会出现错误、异常信息。如果我们想自己处理这些异常信息的话,需要手动捕捉这些信息。那么我们可以利用try catch完成。

TRY…CATCH 构造包括两部分:一个 TRY 块和一个 CATCH 块。如果在 TRY 块中所包含的 Transact-SQL 语句中检测到错误条件,控制将被传递到 CATCH 块(可在此块中处理该错误)。

???? CATCH 块处理该异常错误后,控制将被传递到 END CATCH 语句后面的第一个 Transact-SQL 语句。如果 END CATCH 语句是存储过程或触发器中的最后一条语句,控制将返回到调用该存储过程或触发器的代码。将不执行 TRY 块中生成错误的语句后面的 Transact-SQL 语句。

???? 如果 TRY 块中没有错误,控制将传递到关联的 END CATCH 语句后紧跟的语句。如果 END CATCH 语句是存储过程或触发器中的最后一条语句,控制将传递到调用该存储过程或触发器的语句。

???? TRY 块以 BEGIN TRY 语句开头,以 END TRY 语句结尾。在 BEGIN TRY 和 END TRY 语句之间可以指定一个或多个 Transact-SQL 语句。CATCH 块必须紧跟 TRY 块。CATCH 块以 BEGIN CATCH 语句开头,以 END CATCH 语句结尾。在 Transact-SQL 中,每个 TRY 块仅与一个 CATCH 块相关联。

???? # 错误函数

???? 示例

(object_id() ) proc_error_info proc_error_info error_number() , error_message() , error_severity() , error_state() , error_line() , error_procedure() ;

?

???? # 示例:用异常处理错误信息

try 1 / 0; try catch proc_error_info; --调用错误消息存储过程 catch

?

???? # 示例:异常能处理的错误信息

try * * student; try catch proc_error_info; catch try * st; try catch proc_error_info; catch (object_id() ) proc_select proc_select * st; try proc_select; try catch proc_error_info; catch

???? 异常不能处理编译期的错误,如语法错误。以及重编译造成部分名称对象得不到正确解析的时候所出现的错误。

?

???? # 示例:无法提交的事务

(object_id(,) ) temp_tab temp_tab( id (100000,1), name (200)) try ; --没有createTime字段 temp_tab createTime; ; try catch proc_error_info;--显示异常信息 (xact_state() = -1) + + + ; (xact_state() = 0) ; (xact_state() = 1) ; catch

?

???? # 示例:处理异常日志信息

(object_id(,) ) errorLog errorLog( errorLogID (100,--ErrorLog 行的主键。 errorTime datetime getDate(),--发生错误的日期和时间。 userName sysname ,--执行发生错误的批处理的用户。 errorNumber ,--发生的错误的错误号。 errorSeverity ,--发生的错误的严重性。 errorState ,--发生的错误的状态号。 errorProcedure nvarchar(126),--发生错误的存储过程或触发器的名称。 errorLine ,--发生错误的行号。 errorMessage nvarchar(4000)) (object_id(,) ) proc_add_exception_log proc_add_exception_log(@logId = 0 ) nocount ; @logId = 0; try (error_number() ); (xact_state() = -1) + + + ; (xact_state() = 0) ; (xact_state() = 1) ; --添加日志信息 insert errorLog (getDate(),,error_number(), error_severity(),error_state(), error_procedure(), error_line(),error_message()); --设置自增值 @logId = @@; try catch ; proc_error_info;--显示错误信息 -1; catch @id ; try ; --删除带有外键的记录信息 classes id = 1; ; try catch proc_error_info;--显示错误信息 (xact_state() <> 0) ; proc_add_exception_log @id catch * errorLog errorLogID = @id;

?

? 游标

???? 游标可以对一个select的结果集进行处理,或是不需要全部处理,就会返回一个对记录集进行处理之后的结果。

???? 1、游标实际上是一种能从多条数据记录的结果集中每次提取一条记录的机制。游标可以完成:

????????? # 允许定位到结果集中的特定行

????????? # 从结果集的当前位置检索一行或多行数据

????????? # 支持对结果集中当前位置的进行修改

???? 由于游标是将记录集进行一条条的操作,所以这样给服务器增加负担,一般在操作复杂的结果集的情况下,才使用游标。SQL Server 2005有三种游标:T-SQL游标、API游标、客户端游标。

?

???? 2、游标的基本操作

????????? 游标的基本操作有定义游标、打开游标、循环读取游标、关闭游标、删除游标。

???? A、 定义游标

cursor_name --游标名称 [ | ] --全局、局部[forward | ] --游标滚动方式[read_only | scroll_locks | optimistic] --读取方式 select_statements --查询语句[ | column_name ...] --修改字段

???? 参数:

???? forward only | scroll:前一个参数,游标只能向后移动;后一个参数,游标可以随意移动

???? read_only:只读游标

???? scroll_locks:游标锁定,游标在读取时,数据库会将该记录锁定,以便游标完成对记录的操作

???? optimistic:该参数不会锁定游标;此时,如果记录被读入游标后,对游标进行更新或删除不会超过

?

???? B、 打开游标

????????? open cursor_name;

????????? 游标打开后,可以使用全局变量@@cursor_rows显示读取记录条数

?

???? C、 检索游标

????????? fetch cursor_name;

????????? 检索方式如下:

???????????? fetch first; 读取第一行

???????????? fetch next; 读取下一行

???????????? fetch prior; 读取上一行

???????????? fetch last; 读取最后一行

???????????? fetch absolute n; 读取某一行

??????????????? 如果n为正整数,则读取第n条记录

??????????????? 如果n为负数,则倒数提取第n条记录

??????????????? 如果n为,则不读取任何记录

???????????? fetch pelative n

??????????????? 如果n为正整数,则读取上次读取记录之后第n条记录

??????????????? 如果n为负数,则读取上次读取记录之前第n条记录

??????????????? 如果n为,则读取上次读取的记录

?

???? D、 关闭游标

????????? close cursor_name;

?

???? E、 删除游标

????????? deallocate cursor_name;

?

???? 3、游标操作示例

cursor_stu id,name,age student;--打开游标 cursor_stu;--存储读取的值 @id , @name nvarchar(20), @age (20);--读取第一条记录 cursor_stu @id,@name,@age;--循环读取游标记录 ;--全局变量 (@@fetch_status = 0) + ((5),@id) + + @name + + @age; --继续读取下一条记录 cursor_stu @id,@age;--关闭游标 area_cursor;--删除游标-- area_cursor;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读