Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.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 如何从错误消息中获取实际的存储过程行号?_Sql_Sql Server 2005 - Fatal编程技术网

Sql 如何从错误消息中获取实际的存储过程行号?

Sql 如何从错误消息中获取实际的存储过程行号?,sql,sql-server-2005,Sql,Sql Server 2005,当我使用SQL Server时出现错误,错误消息给出的行号与存储过程中的行号没有关联。我假设差异是由于空白和注释造成的,但这真的是吗 如何将这两组行号相互关联?如果有人能给我一个指向正确方向的指针,我会非常感激 我使用的是SQL server 2005。IIRC,它从创建该过程的批处理开始计算行数。这意味着要么是脚本的开始,要么是create/alter proc语句之前的最后一个GO语句 更简单的方法是提取SQL Server在创建对象时使用的实际文本。使用默认键映射将输出切换到文本模式CTR

当我使用SQL Server时出现错误,错误消息给出的行号与存储过程中的行号没有关联。我假设差异是由于空白和注释造成的,但这真的是吗

如何将这两组行号相互关联?如果有人能给我一个指向正确方向的指针,我会非常感激


我使用的是SQL server 2005。

IIRC,它从创建该过程的批处理开始计算行数。这意味着要么是脚本的开始,要么是create/alter proc语句之前的最后一个GO语句

更简单的方法是提取SQL Server在创建对象时使用的实际文本。使用默认键映射将输出切换到文本模式CTRL-T,然后运行

sp_helptext proc_name
将结果复制粘贴到脚本窗口中,以获得语法突出显示等,并使用转到行函数CTRL-G,我认为可以转到报告的错误行。

您可以使用此选项

CAST(ERROR_LINE() AS VARCHAR(50))
如果要创建错误日志表,可以使用以下命令:

INSERT INTO dbo.tbname( Source, Message) VALUES ( ERROR_PROCEDURE(), '[ ERROR_SEVERITY : ' + CAST(ERROR_SEVERITY() AS VARCHAR(50)) + ' ] ' + '[ ERROR_STATE : ' + CAST(ERROR_STATE() AS VARCHAR(50)) + ' ] ' + '[ ERROR_PROCEDURE : ' + CAST(ERROR_PROCEDURE() AS VARCHAR(50)) + ' ] ' + '[ ERROR_NUMBER : ' + CAST(ERROR_NUMBER() AS VARCHAR(50)) + ' ] ' +  '[ ERROR_LINE : ' + CAST(ERROR_LINE() AS VARCHAR(50)) + ' ] ' + ERROR_MESSAGE())
事实上,这个错误数字非常有效

此函数从最后一个GO批处理分隔符语句开始计数,因此,如果您没有使用任何GO空格,并且它仍然显示错误的行号,则向其添加7,因为在第7行的存储过程中,会自动使用批处理分隔符。所以如果你使用
选择CastError\u Number+7作为Int作为[Error\u Number]-您将得到所需的答案。

长答案:行号从CREATE PROCEDURE语句中计算,加上实际运行CREATE语句时可能在其上方的任何空行或注释行,但不计算GO语句之前的任何行

我发现制作一个存储过程来确认以下内容要容易得多:

GO

-- =============================================
-- Author:          <Author,,Name>
-- Create date: <Create Date,,>
-- Description:     <Description,,>
-- =============================================
CREATE PROCEDURE ErrorTesting
       -- Add the parameters for the stored procedure here
AS
BEGIN
       -- SET NOCOUNT ON added to prevent extra result sets from
       -- interfering with SELECT statements.
       SET NOCOUNT ON;

       -- Insert statements for procedure here
       SELECT 1/0

END
GO
创建后,可以将其切换到ALTER PROCEDURE,并在注释上方和first GO语句上方和下方添加一些空行,以查看效果


我注意到的一件非常奇怪的事情是,我必须在一个新的查询窗口中运行EXEC ErrorTesting,而不是在同一窗口的底部突出显示它并运行…当我这样做时,行号一直在上升!不知道为什么会发生这种情况。

出于习惯,我在存储过程的BEGIN之后直接放置LINENO 0。在这种情况下,这会将行号重置为零。然后,只需将错误消息报告的行号添加到您在SSMS中写入LINENO 0和bingo的行号中即可-您拥有查询窗口中表示的错误行号。

您可以在catch块中获得如下错误消息和错误行:

'Ms Sql Server Error: - ' + ERROR_MESSAGE() + ' - Error occured at: ' + CONVERT(VARCHAR(20),  ERROR_LINE())

如果您使用Catch块并在Try块内的任何代码验证中使用RAISERROR,则会报告错误行Catch块所在的位置,而不是实际错误发生的位置。我用它来澄清这一点

BEGIN CATCH
  DECLARE @ErrorMessage NVARCHAR(4000);
  DECLARE @ErrorSeverity INT;
  DECLARE @ErrorState INT;

  SELECT 
     @ErrorMessage = ERROR_MESSAGE() + ' occurred at Line_Number: ' + CAST(ERROR_LINE() AS VARCHAR(50)),
     @ErrorSeverity = ERROR_SEVERITY(),
     @ErrorState = ERROR_STATE();

  RAISERROR (@ErrorMessage, -- Message text.
     @ErrorSeverity, -- Severity.
     @ErrorState -- State.
  );

END CATCH

在TSQL/存储过程中

您可能会遇到以下错误:

Msg 206,16级,状态2,程序myproc,第177行[批次开始第7行]


这意味着错误在批处理的第177行。在SQL中不是177。在我的例子[7]中,您应该查看批处理开始的行号,然后将该值添加到行号中,以查找错误的语句

关于此问题的有用文章:


如果改为使用ManagementStudio生成脚本,则会自动添加USE dbname语句以及ANSI_null和QUOTED_标识符的设置。删除这些语句9行以在脚本窗口中获得正确的行号:

只需将以下代码添加到存储过程中,就可以用行号xx指示绝对行号,其中xx是在SQL Mgt Studio中打开SP时的实际行号

比如说,

USE [Northwind]
GO
/****** Object:  StoredProcedure [automate].[workorders_exceptions_generate]    Script Date: 03/03/2021 8:49:23 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*

Here are some comments here
Which are white spaces
But the actual line after the "BEGIN" statement is 21

*/
CREATE PROCEDURE dbo.something
    @ChildWOID varchar(30)
    , @DontByPass bit = 0
    , @BillingStatus varchar(30) = null OUTPUT
AS
BEGIN
    LINENO 21
    
    PRINT 'HELLO WORLD'
END

我认为行号与进程的主体有关。i、 忽略标题。也许会有帮助。标题在哪里结束?在遵循alter程序的开始之后。。。在我的测试中,它似乎是从create proc行开始计数的。我假设您看到的是不同的情况。我在这里的回答中描述:请注意,错误行仅在存储过程中TRY/CATCH的CATCH部分可用。它报告的行号与SQL Server在未捕获错误时返回的行号相同。因此,虽然这可能有用,但无助于解决这个问题。当我在网格输出模式下执行此操作时,它会将行号固定在屏幕上too@codeulike-很好,如果使用网格输出,行号将与行号匹配,因此不需要使用CTRL+G。网格输出的唯一问题是它将制表符更改为单个空格,因此,您将丢失所有格式。如果您没有使用任何Go空格,但它仍然显示错误的行号,请将7添加到其中,如第7行的存储过程中所示,批处理分隔符将自动使用。-这是什么意思?为什么不把李放进去
neNo X,其中X=您将语句放在其上的行号,以便它自动添加到报告的行号中?@LarryBud可能是由于存储过程中的注释造成的?