none
请问插入记录到表中,因字段长度不够,为什么数据库不报错,只是终止了该语句? RRS feed

  • 问题

  • 在事务处理中 

       begin tran
        insert into aaa(str) values('a1234567890')
        insert into aaa(str) values('a1')
      commit tran

    第一句执行有问题被终止后,第二句仍然执行

    请问如何将第二句也不执行呢?

     
    2012年11月8日 8:39

答案

  • 查询分析器和 managent studio 是遇到错误时,继续执行,除非是会导致批处理中断的严重错误

    所以后面的语句继续执行了

    如果你在程序中去执行,那是出错中止,不会执行后面的语句

    如果你要确保出错终止的话,你可以用 try catch, 或者在语句的最前面加上 set xact_abort on (打开这个的话,出错时会终止并回滚事务)

    • 已标记为答案 尺蠖 2012年11月9日 3:03
    2012年11月8日 9:28
  •  DECLARE @error_message    NVARCHAR(256)
    DECLARE @error_serverity    INT
    DECLARE @error_state        INT

     
     BEGIN TRY
         begin tran
        insert into aaa(a) values('a1234567890')
        insert into aaa(a) values('a1')
      commit tran
    END TRY
    BEGIN CATCH
           rollback

         SET @error_message    = ERROR_MESSAGE()
        SET @error_serverity    = ERROR_SEVERITY()
        SET @error_state        = ERROR_STATE()
        RAISERROR(@error_message,@error_serverity,@error_state) 

    END CATCH

    • 已编辑 Michael CS 2012年11月8日 8:59
    • 已标记为答案 尺蠖 2012年11月9日 3:03
    2012年11月8日 8:48
  • 如果是sqlserver2000,没有try catch的话可以:

    SET XACT_ABORT on

    begin tran

     insert into aaa(str) values('a1234567890')
        insert into aaa(str) values('a1')
      commit tran


    当 SET XACT_ABORT 为 ON 时,如果执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚。

    当 SET XACT_ABORT 为 OFF 时,有时只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。如果错误很严重,那么即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。



    • 已编辑 znscott1 2012年11月8日 9:29 error
    • 已标记为答案 尺蠖 2012年11月9日 3:03
    2012年11月8日 9:28

全部回复

  • 表aaa 的str字段长度是10位,这样第一句写入就失败了
    2012年11月8日 8:40
  •  DECLARE @error_message    NVARCHAR(256)
    DECLARE @error_serverity    INT
    DECLARE @error_state        INT

     
     BEGIN TRY
         begin tran
        insert into aaa(a) values('a1234567890')
        insert into aaa(a) values('a1')
      commit tran
    END TRY
    BEGIN CATCH
           rollback

         SET @error_message    = ERROR_MESSAGE()
        SET @error_serverity    = ERROR_SEVERITY()
        SET @error_state        = ERROR_STATE()
        RAISERROR(@error_message,@error_serverity,@error_state) 

    END CATCH

    • 已编辑 Michael CS 2012年11月8日 8:59
    • 已标记为答案 尺蠖 2012年11月9日 3:03
    2012年11月8日 8:48
  • 查询分析器和 managent studio 是遇到错误时,继续执行,除非是会导致批处理中断的严重错误

    所以后面的语句继续执行了

    如果你在程序中去执行,那是出错中止,不会执行后面的语句

    如果你要确保出错终止的话,你可以用 try catch, 或者在语句的最前面加上 set xact_abort on (打开这个的话,出错时会终止并回滚事务)

    • 已标记为答案 尺蠖 2012年11月9日 3:03
    2012年11月8日 9:28
  • 如果是sqlserver2000,没有try catch的话可以:

    SET XACT_ABORT on

    begin tran

     insert into aaa(str) values('a1234567890')
        insert into aaa(str) values('a1')
      commit tran


    当 SET XACT_ABORT 为 ON 时,如果执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚。

    当 SET XACT_ABORT 为 OFF 时,有时只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。如果错误很严重,那么即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。



    • 已编辑 znscott1 2012年11月8日 9:29 error
    • 已标记为答案 尺蠖 2012年11月9日 3:03
    2012年11月8日 9:28
  • 非常感谢,之前从来没在sql中使用过try catch

    2012年11月8日 9:42
  • 非常感谢,原来还有SET XACT_ABORT on 这样的用法,长知识了。

    我正纳闷为什么有的错误回滚,有的不回滚呢

    另外想问一下,插入值字符串长度超过字段定义,系统能否有办法自动切断字符串长度,达到字段定义的长度,来完成插入动作?

    2012年11月8日 13:39
  • Better to use variable length data type like varchar.
    2012年11月8日 13:52
  • 另外我想准确告诉你一下,这样的语句在程序执行是报错了,但是后面的语句是执行了的,要是不执行,我就不用来求助了。

    谢谢你的回复!

    2012年11月8日 13:53
  • If you still got insert error with varchar(8000), may need put it in blob column like varchar(max). By the way, you didn't post table schema. People just guess what happened and tried to help.
    2012年11月8日 14:06
  • 提前做显式的数据类型转换可以做自动截断

    比如 convert(char(2), 'aaaaaaaaaaaaa'), 这个会自动截断,而不会报错

    2012年11月8日 23:28
  • 我知道了,谢谢诸位
    2012年11月9日 1:41
  • 我知道了,谢谢诸位

    你好,

    那现在问题解决了吗?

    Thanks,
    Amy peng


    Description: Description: TechNet 论坛好帮手立刻免费下载TechNet论坛好帮手

    • 已标记为答案 尺蠖 2012年11月9日 3:02
    • 取消答案标记 尺蠖 2012年11月9日 3:03
    2012年11月9日 2:04
    版主