ฉันจะรับหมายเลขบรรทัดโพรซีเดอร์ที่เก็บไว้จริงจากข้อความแสดงข้อผิดพลาดได้อย่างไร?


112

เมื่อฉันใช้ SQL Server และมีข้อผิดพลาดข้อความแสดงข้อผิดพลาดจะให้หมายเลขบรรทัดที่ไม่มีความสัมพันธ์กับหมายเลขบรรทัดในโพรซีเดอร์ที่เก็บไว้ ฉันคิดว่าความแตกต่างเกิดจากพื้นที่สีขาวและความคิดเห็น แต่มันจริงเหรอ?

ฉันจะเชื่อมโยงตัวเลขสองชุดนี้เข้าด้วยกันได้อย่างไร ถ้าใครสามารถชี้ทิศทางที่ถูกต้องให้ฉันได้ฉันจะขอบคุณจริงๆ

ฉันใช้ SQL Server 2005


1
ฉันคิดว่าหมายเลขบรรทัดเกี่ยวข้องกับเนื้อความของ proc เช่นละเว้นส่วนหัว
Martin Smith

บางทีstackoverflow.com/questions/4550342/…จะช่วยได้
John Saunders

ส่วนหัวสิ้นสุดที่ใด หลังจากเริ่มต้นที่เป็นไปตามขั้นตอนการเปลี่ยนแปลง ... AS?
ชามา

ดูเหมือนว่าจะเริ่มนับจากcreate procบรรทัดในการทดสอบของฉัน ฉันถือว่าคุณกำลังเห็นบางอย่างที่แตกต่างออกไป
Martin Smith

1
อธิบายไว้ในคำตอบของฉันที่นี่: stackoverflow.com/questions/2947173/…
gbn

คำตอบ:


114

IIRC จะเริ่มนับบรรทัดจากจุดเริ่มต้นของชุดงานที่สร้าง proc นั้น นั่นหมายถึงการเริ่มต้นของสคริปต์หรืออื่น ๆ คำสั่ง "GO" สุดท้ายก่อนคำสั่ง create / alter proc

วิธีที่ง่ายกว่าในการดูนั่นคือการดึงข้อความจริงที่ SQL Server ใช้เมื่อสร้างวัตถุ เปลี่ยนเอาต์พุตของคุณเป็นโหมดข้อความ (CTRL-T ด้วยการแมปคีย์เริ่มต้น) และเรียกใช้

sp_helptext proc_name

คัดลอกวางผลลัพธ์ลงในหน้าต่างสคริปต์เพื่อรับการเน้นไวยากรณ์ ฯลฯ และใช้ฟังก์ชัน goto line (ฉันคิดว่า CTRL-G) เพื่อไปที่บรรทัดข้อผิดพลาดที่รายงาน


14
เมื่อฉันทำสิ่งนี้ในโหมด Grid-Output มันก็ติดหมายเลขบรรทัดไว้ด้วยเช่นกัน
codeulike

2
@codeulike - จุดที่ดีถ้าคุณใช้ Grid เอาท์พุทหมายเลขแถวจะตรงกับหมายเลขบรรทัดดังนั้นคุณไม่จำเป็นต้องใช้ CTRL + G ปัญหาเดียวของฉันกับผลลัพธ์ Grid คือเปลี่ยนอักขระ TAB เป็น SPACE เดียวดังนั้นคุณจึงสูญเสียการจัดรูปแบบทั้งหมด
Rick

33

ออกจากสถานที่ที่ฉันนิสัยLINENO 0โดยตรงหลังจากBEGINในขั้นตอนการเก็บของฉัน ซึ่งจะรีเซ็ตหมายเลขบรรทัด - เป็นศูนย์ในกรณีนี้ จากนั้นเพิ่มหมายเลขบรรทัดที่รายงานโดยข้อความแสดงข้อผิดพลาดไปยังหมายเลขบรรทัดใน SSMS ที่คุณเขียนLINENO 0และบิงโก - คุณมีหมายเลขบรรทัดของข้อผิดพลาดตามที่แสดงในหน้าต่างแบบสอบถาม


4
ทำไมไม่ใส่ "LineNo X" โดยที่ X = หมายเลขบรรทัดที่คุณใส่คำสั่งเพื่อที่จะเพิ่มไปยังหมายเลขบรรทัดที่รายงานโดยอัตโนมัติ
LarryBud

8

หากคุณใช้ Catch Block และใช้ RAISERROR () สำหรับการตรวจสอบรหัสใด ๆ ภายใน Try Block จะมีการรายงาน Error Line ว่า Catch Block อยู่ที่ใดและไม่ใช่จุดที่เกิดข้อผิดพลาดจริง ฉันใช้แบบนี้เพื่อล้างสิ่งนั้น

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 (Batch Separator) สุดท้ายดังนั้นหากคุณไม่ได้ใช้ช่องว่าง 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 / Stored Procedures

คุณอาจได้รับข้อผิดพลาดเช่น:

ข่าวสารเกี่ยวกับ 206, ระดับ 16, สถานะ 2, ขั้นตอน myproc, บรรทัดที่ 177 [Batch Start Line 7]

ซึ่งหมายความว่าข้อผิดพลาดอยู่ในบรรทัด 177 ในชุดงาน ไม่ใช่ 177 ใน SQL คุณควรดูว่าชุดของคุณเริ่มต้นที่หมายเลขบรรทัดใดในกรณีของฉัน [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 () สามารถใช้ได้เฉพาะในส่วน CATCH ของ TRY / CATCH ภายในกระบวนงานที่จัดเก็บ หมายเลขบรรทัดที่รายงานเป็นหมายเลขเดียวกับที่ SQL Server ส่งกลับหากคุณไม่พบข้อผิดพลาด ดังนั้นแม้ว่าจะมีประโยชน์ แต่ก็ไม่ได้ช่วยแก้ปัญหานี้
Rick

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 block ดังนี้:

'Ms Sql Server Error: - ' + ERROR_MESSAGE() + ' - Error occured at: ' + CONVERT(VARCHAR(20),  ERROR_LINE())
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.