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


110

当我使用SQL Server时出现错误,错误消息给出的行号与存储过程中的行号没有关联。我认为差异是由于空白和注释引起的,是真的吗?

如何将这两组线号相互关联?如果有人能够至少向我提供正确方向的指点,我将非常感激。

我正在使用SQL Server 2005。


1
我认为行号与proc的主体有关。即忽略标题。
马丁·史密斯


标头在哪里结束?更改程序开始后... AS?
chama 2010年

create proc在我的测试中,它似乎从线开始计算。我认为您看到的是不同的东西。
马丁·史密斯

1
描述在这里我的答案:stackoverflow.com/questions/2947173/...
GBN

Answers:


113

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

一种更简单的查看方法是提取创建对象时SQL Server使用的实际文本。将输出切换到文本模式(使用默认键映射的CTRL-T)并运行

sp_helptext proc_name

将结果复制粘贴到脚本窗口中以突出显示语法等,然后使用goto行功能(我认为是CTRL-G)转到报告的错误行。


14
当我这样做的并网输出模式,它停留的行号就太
codeulike

2
@codeulike-好点,如果您使用Grid输出,则行号将与行号匹配,因此您无需使用CTRL + G。网格输出的唯一问题是它将TAB字符更改为单个SPACE,因此您丢失了所有格式。
瑞克(Rick)

32

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


4
为什么不只在其中X =放置语句的行号上放置“ LineNo X”,以便将其自动添加到报告的行号上?
拉里·布德(LarryBud)

8

如果您使用捕获块并在尝试块中使用RAISERROR()进行任何代码验证,则将报告错误行在捕获块所在的位置,而不是实际发生错误的位置。我用它来清除它。

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

6

实际上,这Error_number()很好。

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


1
if you have not used any Go spaces and it is still showing a wrong line number - then add 7 to it, as in stored procedure in line number 7 the batch separator is used automatically.-这是什么意思?
underscore_d

4

在TSQL /存储过程中

您可能会收到如下错误:

消息206,级别16,状态2,过程myproc,第177行[批处理开始第7行]

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


2

你可以用这个

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())

4
请注意,ERROR_LINE()仅在存储过程的TRY / CATCH的CATCH部分中可用。如果您没有发现错误,它报告的行号与SQL Server返回的行号相同。因此,尽管这很有用,但无助于解决这个问题。
里克

1

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

我发现制作一个存储的proc进行确认要容易得多:

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完之后,您可以将其切换到并在注释上方以及第一个注释的上方和下方添加一些空白行。GO语句以查看效果。

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


1

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

'Ms Sql Server Error: - ' + ERROR_MESSAGE() + ' - Error occured at: ' + CONVERT(VARCHAR(20),  ERROR_LINE())
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.