2010-12-30 14 views
85

Khi tôi sử dụng Sql Server và có lỗi, thông báo lỗi cho biết số dòng không có tương quan với số dòng trong quy trình được lưu trữ. Tôi cho rằng sự khác biệt là do không gian trắng và bình luận, nhưng nó thực sự?Làm cách nào tôi có thể nhận được số dòng quy trình được lưu trữ thực tế từ thông báo lỗi?

Làm cách nào để liên kết hai bộ số dòng này với nhau? Nếu bất cứ ai có thể cho tôi ít nhất một con trỏ đúng hướng, tôi thực sự sẽ đánh giá cao nó.

Tôi đang sử dụng máy chủ sql 2005.

TIA!

+1

Tôi nghĩ số dòng liên quan đến phần thân của proc. tức là bỏ qua tiêu đề. –

+0

Có thể http://stackoverflow.com/questions/4550342/possible-to-get-the-line-number-of-the-currently-executing-sproc-in-sql-server sẽ trợ giúp. –

+0

Tiêu đề kết thúc ở đâu? Sau khi bắt đầu theo quy trình thay đổi ... AS? – chama

Trả lời

88

IIRC, nó bắt đầu đếm các dòng từ đầu lô đã tạo proc đó. Điều đó có nghĩa là sự khởi đầu của tập lệnh, hoặc câu lệnh "GO" cuối cùng trước câu lệnh tạo/thay đổi proc.

Cách dễ dàng hơn để xem đó là kéo văn bản thực tế mà SQL Server được sử dụng khi tạo đối tượng. Chuyển sang đầu ra của bạn sang chế độ văn bản (Ctrl-T với ánh xạ phím mặc định) và chạy

sp_helptext proc_name 

Sao chép dán kết quả vào một cửa sổ kịch bản để có được nổi bật cú pháp vv, và sử dụng chức năng dòng goto (Ctrl-G tôi nghĩ) để đi đến dòng báo cáo lỗi.

+10

Khi tôi thực hiện điều này trong chế độ Lưới-Đầu ra, nó sẽ mắc kẹt số dòng trên – codeulike

+1

@codeulike - Tốt, nếu bạn sử dụng lưới đầu ra số hàng sẽ khớp với số dòng, vì vậy bạn không cần phải sử dụng CTRL + G . Vấn đề duy nhất của tôi với Grid đầu ra là nó thay đổi ký tự TAB thành một không gian duy nhất, vì vậy bạn mất tất cả các định dạng. – Rick

2

bạn có thể sử dụng

CAST(ERROR_LINE() AS VARCHAR(50)) 

và nếu bạn muốn thực hiện bảng đăng nhập lỗi mà bạn có thể sử dụng này:

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

Lưu ý rằng ERROR_LINE() chỉ có sẵn trong phần CATCH của TRY/CATCH trong quy trình được lưu trữ. Số dòng nó báo cáo là số mà SQL Server trả về nếu bạn không gặp lỗi. Vì vậy, trong khi đó có thể hữu ích, nó không giúp giải quyết câu hỏi này. – Rick

7

Thực ra đây Error_number() hoạt động rất tốt.

Chức năng này bắt đầu đếm từ câu lệnh GO (Batch Separator) cuối cùng, vì vậy nếu bạn không sử dụng bất kỳ dấu cách nào và nó vẫn hiển thị số dòng sai - sau đó thêm số 7 vào, như trong quy trình được lưu trữ trong số dòng 7 bộ tách hàng được sử dụng tự động. Vì vậy, nếu bạn sử dụng chọn Cast (Error_Number() + 7 as Int) dưới dạng [Error_Number] - bạn sẽ nhận được câu trả lời mong muốn.

+5

Bạn có nghĩa là 'ERROR_LINE()', phải không? –

+0

'nếu bạn không sử dụng bất kỳ không gian Go nào và nó vẫn hiển thị số dòng sai - sau đó thêm 7 vào nó, như trong thủ tục lưu sẵn trong dòng số 7, dấu phân cách hàng loạt được sử dụng tự động.' - điều này có nghĩa là gì? –

0

Câu trả lời dài: số dòng được tính từ báo cáo kết quả CREATE PROCEDURE, cộng với bất kỳ dòng trống hoặc dòng chú thích bạn có thể đã có ở trên nó khi bạn thực sự chạy báo cáo kết quả CREATE, nhưng không kể bất kỳ dòng trước một tuyên bố GO ...

tôi tìm thấy nó dễ dàng hơn nhiều để thực hiện một proc lưu trữ để chơi xung quanh với để xác nhận:

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 

Sau khi bạn đã tạo ra nó, bạn có thể chuyển nó để ALTER PROCEDURE và thêm một số dòng trống trên các ý kiến ​​và ở trên và bên dướiđầu tiêntuyên bố để xem hiệu quả.

Một điều rất lạ tôi nhận thấy là tôi phải chạy EXEC ErrorTesting trong cửa sổ truy vấn mới thay vì làm nổi bật nó ở cuối cùng cửa sổ và chạy… Khi tôi làm như vậy, số dòng vẫn tiếp tục tăng lên! Không chắc chắn lý do tại sao điều đó xảy ra ..

16

Thói quen tôi đặt LINENO 0 trực tiếp sau BEGIN trong các thủ tục được lưu trữ của tôi. Điều này đặt lại số dòng - bằng 0, trong trường hợp này.Sau đó, chỉ cần thêm số dòng được báo cáo bởi thông báo lỗi vào số dòng trong SSMS nơi bạn đã viết LINENO 0 và bingo - bạn có số dòng của lỗi như được trình bày trong cửa sổ truy vấn.

1

bạn có thể nhận được thông báo lỗi và dòng lỗi trong khối catch như thế này:

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

Nếu bạn sử dụng một khối catch và sử dụng một RAISERROR() cho bất kỳ xác nhận mã trong khối try thì Error Line được báo cáo nơi Catch Block là và không phải là nơi xảy ra lỗi thực sự. Tôi đã sử dụng nó như thế này để làm rõ điều đó.

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 
Các vấn đề liên quan