Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 为什么T-SQL在出现错误时不停止_Sql Server_Tsql - Fatal编程技术网

Sql server 为什么T-SQL在出现错误时不停止

Sql server 为什么T-SQL在出现错误时不停止,sql-server,tsql,Sql Server,Tsql,如果我执行以下查询 EXEC spFoo PRINT 'TEST' 并且spFoo抛出一个错误,它仍然执行print语句 然而,如果我这样做 BEGIN TRY EXEC cdb.spFoo PRINT 'TEST' END TRY BEGIN CATCH THROW; END CATCH 它的行为与我预期的一样,在出现错误后不会继续 有人能给我解释一下这种行为吗?即使我将其封装在事务中,它仍然会继续。它不仅与打印语句有关,还与任何其他内容有关。我最初的想法是,这是一

如果我执行以下查询

EXEC spFoo
PRINT 'TEST'
并且
spFoo
抛出一个错误,它仍然执行print语句

然而,如果我这样做

BEGIN TRY
    EXEC cdb.spFoo
    PRINT 'TEST'
END TRY
BEGIN CATCH
    THROW;
END CATCH
它的行为与我预期的一样,在出现错误后不会继续

有人能给我解释一下这种行为吗?即使我将其封装在事务中,它仍然会继续。它不仅与打印语句有关,还与任何其他内容有关。我最初的想法是,这是一个严重的问题,但严重程度是16级。这是正常的T-SQL行为吗?如果是这样的话,是什么促使这种设计与我使用过的所有其他语言相矛盾,直接导致错误升级


我曾在SQL Server 2012、2014和2017中尝试过并在多台不同的机器上看到过相同的行为。所讨论的存储过程链接到SQL CLR。

您应该在此处给出解释

TRY…CATCH构造捕获具有 严重性高于10,不关闭数据库连接

在SQL中,TRY..CATCH的工作方式与C#/VB等非常不同,因此根据严重程度,它可以工作

若您需要查看上一条语句中是否出现任何错误,请使用

例如,
IF@@ERROR 0打印“TEST”

尝试打印结果@给出错误。它可能会给你任何暗示

如果上一个Transact-SQL语句未遇到错误,则返回0

(从上面的链接中)@@ERROR在上一条语句遇到错误时返回错误号 错误。如果错误是sys.messages目录中的错误之一 视图,则@@ERROR包含sys.messages.message\u id中的值 列中的错误。您可以查看与文件关联的文本 @@sys.messages中的错误号

检查是否从@错误中找到任何有用的信息

试试。。抓住


不会停止查询过程。如果捕获错误后不想继续,请使用
RETURN
。这将停止该过程。另外,如果您正在使用
开始事务
,请在从流程返回之前使用
回滚
。否则,它将以未提交的事务结束。

严重性级别为16是警告级别。用户需要处理任何错误,包括定义何时需要终止

第一个例子是:

EXEC spFoo
PRINT 'TEST'
这些是独立的语句,虽然
spFoo
可能会失败,但服务器将转到下一个语句。这是因为严重性小于20,批次未自动终止

第二个例子

BEGIN TRY
    EXEC cdb.spFoo
    PRINT 'TEST'
END TRY
BEGIN CATCH
    THROW;
END CATCH
你已经决定了什么与什么相关

由于
TRY
块中的一项失败,因此它不会移动到下一项

THROW
始终终止批处理

一旦调用了
THROW
,如果之后有任何代码继续,则不会执行该操作。如果这很重要,您可以使用
RAISERROR
继续


这似乎不是问题的答案。@AswaniMadhavan,这要看情况而定。由于严重性较低,它不会进入Catch并继续执行。@AswaniMadhavan,我想我需要删除这个答案:)SQL Server错误机制不等于面向对象编程语言,在Catch最终处理它之前,错误不会(总是)冒出来。例如,如果错误严重性为20或更高,会话将立即终止,即使有捕获。您应该尝试阅读有关事务(和xact_abort)和常见错误严重性级别(外键失败、tempdb完全失败等)的信息。不幸的是,每个错误的行为都可能不同。因此,您从未遇到过,比如说,VisualBasic臭名昭著的语言或任何带有带外错误信号的API的C风格语言(
GetLastError
-style)。您不熟悉一些较旧的语言如何处理错误,这并不意味着t-SQL在这方面是独一无二的。可能重复了非常旧的问题,但答案中提供的链接非常详细:在上述答案的评论中提供了更为最新的链接:并且: