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