4

请看下面的 t-sql 代码

   DECLARE @iError INT
   EXEC('select * from sysobj')
   SELECT @iError = @@ERROR
   PRINT 'Error = ' + CAST(@iError AS VARCHAR(10))

在我运行它之后,它会返回错误消息,这就是我想要的。

消息 208,级别 16,状态 1,第 1 行
无效的对象名称“sysobj”。
错误 = 208

但是,如果我更改查询

   DECLARE @iError INT
   EXEC('select * from sysobjects where ''c'' = 1')
   SELECT @iError = @@ERROR
   PRINT 'Error = ' + CAST(@iError AS VARCHAR(10))

输出将是

消息 245,级别 16,状态 1,行 1
将 varchar 值“c”转换为数据类型 int 时转换失败。

问题是 EXEC() 之后的任何代码都没有执行。

在真正的存储过程中,我有一些代码来处理 PRINT 之后的错误。并且这些代码都没有在第二种情况下执行。

有人可以让我知道为什么会这样吗?

我在 SQL Server 2008 和 2005 上都对其进行了测试。

谢谢

4

3 回答 3

3

不同的错误会有不同的中止级别,其中一些可以通过使用设置来控制,例如 ARITHIGNORE 和 ANSI_WARNINGS。

我建议阅读以下详细解释所有这些的文章。

http://www.sommarskog.se/error-handling-I.html#whathappens

语句终止和批量中止

这两组包括常规运行时错误,例如唯一索引中的重复项、磁盘空间不足等。正如我已经讨论过的,事先并不总是容易预测哪个错误会导致哪个操作。此表列出了一些常见错误,以及它们是中止当前语句还是中止整个批处理。

在此处输入图像描述

于 2012-04-13T21:29:27.630 回答
1

研究为您的错误处理实施TRY...CATCH 。然后,您应该能够将所有错误处理放在 CATCH 块中。

于 2012-04-13T20:49:25.157 回答
1

msdn 上有一篇关于此的文章。它与EXEC()运行语句的上下文有关。如果您在传递给的参数中包含错误陷阱EXEC(),您可以将其填充到临时表中,然后查看。

这是他们的例子:

DECLARE @cmd VARCHAR(1000), @ExecError INT

CREATE TABLE #ErrFile (ExecError INT)

SET @cmd = 'EXEC GetTableCount ' + 
'''pubs.dbo.authors''' + 
'INSERT #ErrFile VALUES(@@ERROR)'

EXEC(@cmd)

SET @ExecError = (SELECT * FROM #ErrFile)

SELECT @ExecError AS '@@ERROR'
于 2012-04-13T21:59:35.293 回答