SQLServer数据库笔记(三)

[size=large][b]批处理的错误处理[/b][/size]
联机丛书中关于批处理的介绍已经很清晰了,摘录如下:
[quote]批处理是包含一个或多个 Transact-SQL 语句的组,从应用程序一次性地发送到SQL Server执行。SQL Server 将批处理语句编译成一个可执行单元,此单元称为执行计划。执行计划中的语句每次执行一条。
编译错误(如语法错误)使执行计划无法编译,从而导致批处理中的任何语句均无法执行。
运行时错误(如算术溢出或违反约束)会产生以下两种影响之一:
大多数运行时错误将停止执行批处理中当前语句和它之后的语句。少数运行时错误(如违反约束)仅停止执行当前语句。而继续执行批处理中其它所有语句。
在生成错误的批处理、存储过程或触发器中,@@ERROR 是唯一可用部分。@@ERROR用来标记SQL语句的执行状况。@@ERROR=0,表示执行成功,否则,表示执行错误。由于 @@ERROR 在每一条语句执行后被清除并且重置,应在语句执行后立即检查它。
错误的所有其它部分,都只返回到那些能够用 API 错误处理机制进行错误处理的应用程序中。
[/quote]
关于上述说明的含义如下:
对于SQLServer服务器而言,虽然对于批处理执行过程中的语句错误情况,服务器已返回足够的错误信息。但SQLServer2000的T-SQL语言并没有提供类似Java的Try catch机制来捕获和处理这些错误。T-SQL需要用户在每一条语句执行后通过@@error来判断是否有语句执行错误。或者是在开启事务的情况下,打开XACT_ABORT开关,这样,当批处理中任意语句出现错误时,都将停止所有后续语句的执行并回滚事务。
对于JDBC程序而言,底层的数据库驱动在得到错误消息返回时,会产生并抛出SQLException异常。XACT_ABORT开关的状态不影响事务正确的被提交或者回滚。
联机丛书的说明如下(但还有些疑惑?):
[quote]对于大多数 OLE DB 提供程序(包括 SQL Server),隐性或显式事务中的数据修改语句必须将 XACT_ABORT 设置为 ON。唯一不需要该选项的情况是提供程序支持嵌套事务时。
SET XACT_ABORT { ON | OFF }指定当 Transact-SQL 语句产生运行时错误时,SQL Server是否自动回滚当前事务。当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为 OFF 时,只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。
[/quote]
比如对于下面的SQL语句:
insert into cat values('11', 'aaa')
insert into cat values(null, 'bbb')//违反约束
insert into cat values('33', 'ccc')
GO

SQL查询分析器返回:
[quote](所影响的行数为 1 行)
服务器: 消息 515,级别 16,状态 2,行 1
无法将 NULL 值插入列 'id',表 'test.dbo.cat';该列不允许空值。INSERT 失败。
语句已终止。
(所影响的行数为 1 行)
[/quote]
而对于JDBC程序,第2条SQL语句将导致抛出异常:
public static void main(String[] args) throws Exception {
Properties info = new Properties();
info.put(Messages.get(Driver.BATCHSIZE), 30);
info.put("USER", "sa");
info.put("PASSWORD", "");
Connection conn = null;
Statement stmt = null;
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:jtds:sqlserver://localhost:1433/test", info);
conn.setAutoCommit(false);
stmt = conn.createStatement();
stmt.addBatch("insert into cat values('11', 'aaa')");
stmt.addBatch("insert into cat values(null, 'bbb')");
stmt.addBatch("insert into cat values('33', 'ccc')");
stmt.executeBatch();
conn.commit();
} catch (Exception e) {
e.printStackTrace();
if (conn != null) conn.rollback();
} finally {
if (stmt != null) stmt.close();
if (conn != null) conn.close();
}
}

[img]http://dl.iteye.com/upload/attachment/471460/5b2f212a-8835-37bf-9ae3-765ae4d291a4.jpg[/img]
java.sql.Statement.executeBatch()的API说明如下:
[quote]int[] executeBatch() throws SQLException将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
如果批量更新中的命令之一无法正确执行,则此方法抛出 BatchUpdateException,并且 JDBC 驱动程序可能继续处理批处理中的剩余命令,也可能不执行。无论如何,驱动程序的行为必须与特定的 DBMS 一致,要么始终继续处理命令,要么永远不继续处理命令。
[/quote]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值