sql server锁异常

RAISERROR statement. RAISERROR语句。 Figure 1 demonstrates a combination of mandatory parameters (i.e. 图1展示了为成功使用RAISERROR函数而应提供的必需参数(即msg_id/msg_str, severity, state) as well as optional parameters (i.e. msg_id / msg_str,severity,state )和可选参数(即WITH option) that ought to be provided for the purposes of successfully using the RAISERROR function. WITH选项 )的组合。

Figure 1

图1

The content of an exception message raised through the RAISERROR statement can either be hard-coded or retrieved from the sys.messages catalog view based on a corresponding error code number:

通过RAISERROR语句引发的异常消息的内容可以是硬编码的,也可以基于相应的错误代码号从sys.messages 目录视图检索:

  1. An example of declaring and raising a user-defined error message within a RAISERROR statement is illustrated in Figure 2. In this example, a SQL Server stored procedure is created under the sample AdventureWorks2012 database that, amongst other things, uses a local variable (@StringVariable) in order to declare and set a custom message to handle an exception of dividing by zero.

    图2中显示了一个在RAISERROR语句中声明和引发用户定义的错误消息的示例在此示例中,在示例AdventureWorks2012数据库下创建了一个SQL Server存储过程 ,该数据库除其他外还使用局部变量( @ StringVariable ),以便声明并设置自定义消息以处理除以零的异常。

    Figure 2

    图2

    Now, for the purposes of simulating an application calling the stored procedure created in Figure 2, Figure 3 shows a SQL Server 2012 Integration Services (SSIS) Package that uses an SSIS’s Execute SQL Task (EST) – titled RAISERROR Customer Error Messages – to execute a stored procedure that was created in Figure 2.

    现在,为了模拟调用图2中创建的存储过程的应用程序, 图3显示了一个SQL Server 2012 Integration Services (SSIS) 程序包 ,该程序包使用SSIS的Execute SQL Task (EST)(标题为RAISERROR Customer Error Messages)来执行图2中创建的存储过程。

    Figure 3

    图3

    The execution of the EST leads to an error and the error message returned to SSIS is shown in Figure 4. It can be noticed that the user-defined custom error message is returned to SSIS as a calling application.

    EST的执行导致错误,并且返回到SSIS的错误消息如图4所示。 可以注意到,用户定义的自定义错误消息作为调用应用程序返回给SSIS。

    Figure 4

    图4

  2. sys.messages引发

    Exceptions stored in the sys.messages can be retrieved by referencing ERROR_MESSAGE, ERROR_SEVERITY and ERROR_STATE system functions. Figure 5 demonstrates a stored procedure that set values of system functions to local variables and RAISERROR then references the locally declared variables.

    可以通过引用ERROR_MESSAGE , ERROR_SEVERITY和ERROR_STATE系统函数来检索sys.messages中存储的异常。 图5演示了一个存储过程,该过程将系统函数的值设置为局部变量,然后RAISERROR引用局部声明的变量。

    Figure 5

    图5

    Similarly to an example on re-throwing user-defined exceptions, the stored procedure created in Figure 5 is referenced in an SSIS Package (as shown in Figure 6) and the result of SSIS package execution is displayed in Figure 7.

    类似于重新抛出用户定义的异常的示例,在SSIS包中引用了图5中创建的存储过程( 如图6所示),在图7中显示了SSIS包执行的结果。

    Figure 6

    图6

    Figure 7

    图7

使用THROW语句SQL Server 2012异常处理 (SQL Server 2012 exception handling using THROW statement)

The preceding section demonstrated the prevalent ways of handling exceptions in versions of SQL Server prior to SQL Server 2012. This section focuses on the alternative way to exception handling as of SQL Server 2012 by using the THROW statement. Figure 8 shows the syntax that should be followed in order to successfully make use of the THROW statement.

上一节演示了在SQL Server 2012之前SQL Server版本中处理异常的普遍方法。本节重点介绍使用THROW语句从SQL Server 2012开始的异常处理的替代方法。 图8显示了成功使用THROW语句应遵循的语法。

Figure 8

图8

Noticeably in this syntax is the disappearance of mandatory parameters that dictates the usage of RAISERROR. Thus, the THROW statement is simpler and easier to use compared to RAISERROR as you have an option of not parsing any parameters. For instance, Figure 9 shows a stored procedure that, like the example given in the RAISERROR discussion, attempts to divide by zero. However, unlike the numerous local variables that were used in the RAISERROR discussion for catching exceptions, Figure 9 simply shows that it only takes a single line within the CATCH block to handle exceptions when the THROW statement is used.

值得注意的是,此语法中指示RAISERROR用法的必需参数的消失。 因此,与RAISERROR相比,THROW语句更易于使用,因为您可以选择不解析任何参数。 例如, 图9显示了一个存储过程,类似于RAISERROR讨论中给出的示例,该存储过程试图除以零。 但是,与RAISERROR讨论中用于捕获异常的大量局部变量不同, 图9仅显示了使用THROW语句时,它仅在CATCH块内使用一行来处理异常。

Figure 9

图9

Furthermore, when the stored procedure created in Figure 9 is used in an SSIS Package (as shown in Figure 10), the exception returned looks similar to the exception that was returned when RAISERROR referenced the sys.messages object (as shown in Figure 11) – except of course that it took less lines of code to achieve this using THROW than it did whilst using RAISERROR.

此外,当在SSIS包中使用图9中创建的存储过程( 如图10所示)时,返回的异常类似于RAISERROR引用sys.messages对象时返回的异常( 如图11所示)。 –当然,与使用RAISERROR相比,使用THROW花费更少的代码行来实现这一目标。

Figure 10

图10

Figure 11

图11

抛出与RAISERROR:使用不同方法警告SQL Server 2012异常处理 (THROW vs RAISERROR: Different approaches towars SQL Server 2012 exception handling)

The preceding section indicated that there is ultimately a simpler and convenient way of re-throwing exceptions when THROW statement is used as compared to RAISERROR. However, the examples demonstrated in preceding sections should not justify an absolute replacement of any T-SQL code that references RAISERROR with a THROW statement. Instead, RAISERROR can still be utilised for some of the requirements that the THROW can’t fulfil.

上一节指出,与RAISERROR相比,当使用THROW语句时,最终有一种重新抛出异常的简便方法。 但是,前几节中演示的示例不应证明用THROW语句绝对替代任何引用RAISERROR的T-SQL代码。 相反,RAISERROR仍可用于THROW无法满足的某些要求。

In this section we will take a closer look at the differences between RAISERROR versus THROW statements. Despite the two statements being used for re-throwing exceptions to calling applications, they tend to behave differently in the way they go about re-throwing exceptions. One significant difference is in the way they handle user exceptions (i.e. exceptions with error codes of 50000 or more) versus system exceptions (i.e. exceptions with error codes less than 50000). Below is a list of points that I have put together to persuade you that in some T-SQL scripts one statement maybe suitable over the other:

在本节中,我们将仔细研究RAISERROR和THROW语句之间的区别。 尽管这两个语句用于重新抛出调用应用程序的异常,但是它们在重新抛出异常的方式上往往表现出不同的行为。 他们处理用户异常(即错误代码为50000或更多的异常)与系统异常(即错误代码小于50000的异常)的方式之间的重大区别是。 下面列出了我要说服您的观点:在某些T-SQL脚本中,一条语句可能适合另一条语句:

  1. Error Line Number 错误行号进行准确的故障排除

    One of the known issues of raising an error using RAISERROR statement is often the incorrect error line number that is returned to the calling application. Noticeably, this incorrect error line number occurs when RAISERROR statement throws a user-defined exception. For instance, refer to Figure 12 whereby after the T-SQL code is executed – the error line number is given to be at 13. However, this is incorrect as the statement that causes a division by zero is actually at line number 2. This is correctly depicted in Figure 13 wherein the THROW statement is used.

    使用RAISERROR语句引发错误的已知问题之一通常是返回给调用应用程序的错误错误行号。 值得注意的是,当RAISERROR语句引发用户定义的异常时,会出现此错误的错误行号。 例如,参考图12 ,在该代码中执行T-SQL代码后-错误行号被指定为13。但是,这是不正确的,因为导致被零除的语句实际上在行号2。在图13中正确地描述了其中使用THROW语句的情况。

    Figure 12

    图12

    Figure 13

    图13

  2. Another discrepancy that has largely been attributed to the RAISERROR statement is the incorrect error number that is sometimes returned to calling applications. For instance, according to the sys.messages object, the message_id associated with an error incurred by dividing by zero is 8134 (as shown in Figure 14).

    很大程度上归因于RAISERROR语句的另一个差异是错误的错误号,该错误号有时会返回给调用应用程序。 例如,根据sys.messages对象,与除零引起的错误相关的message_id为8134( 如图14所示)。

    Figure 14

    图14

    However, the error number returned after the execution of query in Figure 15 is 50000 whereas the query that uses the THROW statement, as shown in Figure 16, is returning the correct error number as 8134.

    但是,执行图15中的查询后返回的错误号为50000,而使用THROW语句的查询( 如图16所示)返回正确的错误号8134。

    Figure 15

    图15

    Figure 16

    图16

  3. There are sometimes inconsistencies in terms of whether or not T-SQL commands should be executed after RAISERROR statement is executed. Figure 17 shows that despite the exception having being raised for dividing by zero, ‘Do More’ was still printed afterwards. However, having raised an exception as a result of referencing an invalid column, ApexSQL, in Figure 18 – the statement for printing ‘Do More’ was not executed. Fortunately, such inconsistencies are not tolerated in a THROW statement as it can be seen (in both Figures 19 and 20) that commands that appear after the THROW statement are not executed at all.

    在执行RAISERROR语句后是否应该执行T-SQL命令方面有时存在不一致之处。 图17显示,尽管引发了除以零的异常,但此后仍打印'Do More'。 但是,由于在图18中引用了无效列ApexSQL而引发了异常-未执行用于打印“ Do More”的语句。 幸运的是,这样的不一致在THROW语句中是不能容忍的,因为可以看到(在图1920中 )根本没有执行在THROW语句之后出现的命令。

    Figure 17

    图17

    Figure 18

    图18

    Figure 19

    图19

    Figure 20

    图20

  4. SQL Server uses exception severity levels as guide on whether it should return the exception to the client as just a warning or highly critical. Although RAISERROR dynamically returns severity level based on the nature of the exception encountered, the THROW statement invariably returns an exception with a severity level of 16. Figure 21 demonstrates a T-SQL query with conditional logic that throws an exception if the @ColorOfSky variable is not set to Blue. The severity level of this exception is given to be 16. However, the similar T-SQL code in Figures 22 and 23 shows the flexibility of RAISERROR statement in terms of setting and resetting the severity level of an error.

    SQL Server使用异常严重性级别作为有关是否应将异常作为警告或高度紧急返回给客户端的指南。 尽管RAISERROR根据遇到的异常的性质动态返回严重性级别,但是THROW语句始终返回严重性级别为16的异常。 图21演示了带有条件逻辑的T-SQL查询,如果@ColorOfSky变量为,则该查询将引发异常没有设置为Blue 。 将该异常的严重性级别设置为16。但是, 图2223中类似的T-SQL代码在设置和重置错误的严重性级别方面显示了RAISERROR语句的灵活性。

    Figure 21

    图21

    Figure 22

    图22

    Figure 23

    图23

    1. LOG日志
    2. NOWAIT等待
    3. SETERROR设定错误

    Figure 24 demonstrates a RAISERROR statement that makes use of the WITH LOG argument to write to Windows Application log. Figure 25 displays the application log with the exception that was raised in Figure 24.

    图24演示了RAISERROR语句,该语句利用WITH LOG参数写入Windows应用程序日志。 图25显示了应用程序日志, 图24中引发了异常。

    Figure 24

    图24

    Figure 25

    图25

  5. If you are used to getting away with writing T-SQL code without specifying GO or a semi-colon (;) to indicate the end of a statement – then you will find it difficult to adapt to using the THROW statement. Unless you don’t have any statement preceding the THROW statement, you will not get away with using a THROW statement without specifying T-SQL statement terminators. Furthermore, although RAISERROR permits the use of a RAISERROR statement that is preceded by a statement which does not contain T-SQL statement terminators (as shown in Figure 26), such practice is not tolerated in a THROW statement as shown in Figure 27.

    如果您习惯于不编写T-SQL代码而没有指定GO或分号(;)来指示语句的结尾,那么您将发现很难适应使用THROW语句。 除非在THROW语句之前没有任何语句,否则在不指定T-SQL语句终止符的情况下使用THROW语句将无处可逃。 此外,尽管RAISERROR允许使用在不包含T-SQL语句终止符的语句之后的RAISERROR语句( 如图26所示),但是如图27所示,THROW语句中不允许这种做法。

    Figure 26

    图26

    Figure 27

    图27

    Figures 28 and 29 demonstrates the acceptable way of using THROW statement with GO and semicolon when it is preceded by other T-SQL statements.

    图2829演示了在其他T-SQL语句之前使用THROW语句和GO和分号的可接受方法。

    Figure 28

    图28

    Figure 29

    图29

  6. All user-defined exceptions that do not exist in the sys.messages catalog view are automatically assigned an error number of 50000. However, should you want to assign an exception to any number greater than 50000, the exception would have to be inserted into the sys.messages catalog view prior to being referenced in your RAISERROR statement. Fortunately, the THROW statement does not require that an error number be registered prior to being cited. For instance, Figure 30 shows that error number (message_id) 56789 does not exist in the sys.messages catalog view. Yet, the THROW statement shown in Figure 31 is able to reference a non-existent error number whereas a similar RAISERROR statement is raising an error as shown in Figure 32.

    将自动为sys.messages目录视图中不存在的所有用户定义的异常分配一个错误号50000。但是,如果要将异常分配给大于50000的任何数字,则必须将异常插入到sys.messages目录视图,然后在您的RAISERROR语句中引用它。 幸运的是,THROW语句不需要在引用之前注册错误号。 例如, 图30显示sys.messages目录视图中不存在错误号( message_id )56789。 但是, 图31所示的THROW语句能够引用不存在的错误号,而类似的RAISERROR语句正在引发错误, 如图32所示。

    Figure 30

    图30

    Figure 31

    图31

    Figure 32

    图32

    Following the successfully registering of the error number (message_id) 56789 in sys.messages catalog view (shown in Figure 33), RAISERROR statement is then able to re-throw an exception with this new error number (as shown in Figure 34).

    sys.messages目录视图(如图33所示)中成功注册了错误号( message_id )56789之后,RAISERROR语句随后能够使用该新错误号重新引发异常( 如图34所示)。

    Figure 33

    图33

    Figure 34

    图34

  7. Although you can raise both user-defined and system-defined exceptions in a RAISERROR statement, system-defined exceptions can only be raised when the THROW statement is used within a CATCH block. For instance, Figure 35 shows that RAISERROR can directly invoke system-defined error number 40645 whereas the exception returned in Figure 36 indicates that only error numbers within the range of 50000 to 2147483647 can be directly invoked in THROW statement.

    尽管可以在RAISERROR语句中引发用户定义的异常和系统定义的异常,但是仅当在CATCH块中使用THROW语句时,才可以引发系统定义的异常。 例如,图35显示RAISERROR可以直接调用系统定义的错误号40645,而图36中返回的异常表示只能在THROW语句中直接调用50000到2147483647范围内的错误号。

    Figure 35

    图35

    Figure 36

    图36

    However, error number 8134 is a system exception but notice that (in Figure 37) it can be successfully re-thrown by the THROW statement when the statement is correctly referenced within a CATCH block.

    但是,错误号8134是系统异常,但请注意(在图37中 )当在CATCH块中正确引用该语句时,可以通过THROW语句成功将其重新抛出。

    Figure 37

    图37

  8. The error message retrieved from the sys.messages catalog view can be customised by setting message parameter values. In order to for that to happen, part of the error message should contain the printf function. For instance, let’s add a new message in the sys.message object as shown in Figure 38:

    通过设置消息参数值,可以自定义从sys.messages目录视图检索的错误消息。 为了做到这一点,错误消息的一部分应包含printf函数。 例如,让我们在sys.message对象中添加一条新消息, 如图38所示:

    Figure 38

    图38

    Now going back to our example of checking for the colour of the sky, Figure 39 demonstrates how RAISERROR statement re-throws a customised message that was added in Figure 38.

    现在回到检查天空颜色的示例, 图39展示了RAISERROR语句如何重新抛出在图38中添加的自定义消息。

    Figure 39

    图39

    However, substitution parameters in the message parameter are not allowed in a THROW statement. Luckily, adjustments can be made for the purposes of getting the same code to function within a THROW statement. Such adjustments include the usage of the FORMATMESSAGE function. Figure 40 demonstrates how the work around to using substitution parameters can be applied in a THROW statement.

    但是,THROW语句中不允许message参数中的替换参数。 幸运的是,可以进行调整以使同一代码在THROW语句中起作用。 此类调整包括FORMATMESSAGE函数的使用。 图40演示了如何在THROW语句中应用替代参数的解决方法。

    Figure 40

    图40

结论 (Conclusion)

The concept and practice of exception handling in SQL Server is not novel instead statements such as RAISERROR and the TRY/CATCH block has been influential in re-throwing exceptions back to calling applications such as SQL Server Integration Services. The introduction of the THROW statement in SQL Server 2012 has largely made the practice of raising exceptions much more convenient and simple: what used to take a combination of local variables and system functions to successfully re-throw an exception in RAISERROR statement is now easily achievable with a single line when the THROW statement is used. Yet, the THROW statement has various limitations that can only be mitigated by still applying the RAISERROR statement.

SQL Server中异常处理的概念和实践并不是新颖的,相反,诸如RAISERROR之类的语句和TRY / CATCH块在将异常重新引发回调用应用程序(如SQL Server Integration Services)方面具有影响力。 SQL Server 2012中THROW语句的引入已大大简化了引发异常的做法:使用局部变量和系统函数的组合成功在RAISERROR语句中成功抛出异常的操作现在可以轻松实现使用THROW语句时用单行表示。 但是,THROW语句具有各种限制,这些限制只能通过仍然应用RAISERROR语句来缓解。

翻译自: https://www.sqlshack.com/background-exception-handling-sql-server/

sql server锁异常

sql server锁异常_SQL Server中异常处理的背景相关推荐

  1. sql server新增列_SQL Server 2016安装中的新增功能?

    sql server新增列 SQL Server 2016 introduced officially on the 1st of June 2016. It comes with many new ...

  2. sql库缓存命中率_SQL Server内存性能指标–第4部分–缓冲区高速缓存命中率和页面寿命期望

    sql库缓存命中率 In SQL Server performance metrics – part 3, we presented some of the SQL Server Buffer Man ...

  3. sql服务器内存不足_SQL Server内存性能指标–第2部分–可用字节,总服务器和目标服务器内存

    sql服务器内存不足 first part of this series, we started with most important SQL Server performance memory m ...

  4. sql server高可用_SQL Server 2019常规可用性和安装概述

    sql server高可用 介绍 (Introduction) On November 4th, 2019, during the Ignite conference at Orlando, Micr ...

  5. sql server高可用_SQL Server始终在线可用性组采访问题与解答

    sql server高可用 In this article, we will discuss a number of interview questions that you could be ask ...

  6. sql server insert 锁表_SQL Server的insert执行的秘密(下) 带外键的insert分析

    上一篇文章介绍了一个最简单INSERT语句的执行计划详细情况,这一篇分析一下带外键表的INSERT的例子. 本文所用的数据表结构如上图所示:其中Blog表上BlogID是自增主键,并在CreateUs ...

  7. sql server新增列_SQL Server 2017中的新增功能

    sql server新增列 SQL Server 2017 is considered a major release in the history of the SQL Server life cy ...

  8. sql 触发器嵌套条件_SQL Server中的嵌套触发器

    sql 触发器嵌套条件 Nested Triggers in SQL Server are actions that automatically execute when a certain data ...

  9. sql隐式转换_SQL Server中的隐式转换

    sql隐式转换 This article will provide an overview of SQL Server implicit conversion including data type ...

最新文章

  1. 如何让老Mac机支持USB安装Windows
  2. 【原创】StackOverflow 20万关注的问题:如何实现异步Task超时的处理?
  3. 通过Yeoman快速搭建AngularJS webapp应用的实践
  4. Docker 服务器安装(一)
  5. java定义一个方法,返回a的b次方
  6. Docker与虚拟机技术
  7. django-xadmin隐藏菜单不显示
  8. MySQL中serial关键字的作用
  9. php7 aop,php之aop实践
  10. 2003 服务器自动重启设置,Win2003定时自动重启的完美方案
  11. 微信小程序,模板+按钮+绑定事件
  12. 基于神经网络的倒立摆控制系统设计
  13. 微信开放平台修改应用名称
  14. TP4101充电IC与锂电池保护二合一IC
  15. 表格中复制后出现空格_尝过廉江这个美食后,已经连续3天出现在下午茶名单中!...
  16. HTML中的botton type=reset标签失效(不起作用)的可能原因。
  17. PDF转图片哪个格式最清晰?PDF转高清图片的方法
  18. 输入一个字母,若是小写字母,则变为大写输出,否则,原样输出。
  19. 全志V3s USB PHY驱动分析
  20. HTML5 自动聚焦 autofocus 属性

热门文章

  1. php pdo效率,php使用mysqli和pdo扩展,测试对比mysql数据库的执行效率完整示例
  2. java消息推送怎么实现_PHP实现的消息实时推送功能
  3. Executor Framework
  4. bzoj 2821:作诗 分块
  5. 第一章:T-SQL查询与编程基础
  6. 什么是灰度发布?灰度发布方式 系统的割接 灰度部署典型的框架架构
  7. 前缀转后缀(表达式)
  8. 微信公众平台消息接口开发(27)彩票查询
  9. SmartUpload 中文API帮助
  10. LeetCode(13)——罗马数字转整数(JavaScript)