2008-11-20 37 views
183

Tôi có một thủ tục lưu trữ rất dài trong SQL Server 2005 mà tôi đang cố gắng gỡ lỗi và tôi đang sử dụng lệnh 'in' để thực hiện. Vấn đề là, tôi chỉ nhận được các thông điệp từ SQL Server ở cuối của sproc của tôi - Tôi muốn có thể xóa bộ đệm tin nhắn và xem các thông điệp này ngay lập tức trong thời gian chạy của sproc, chứ không phải ở chính kết thúc.Làm cách nào để xóa bộ đệm IN trong TSQL?

Trả lời

260

Sử dụng RAISERROR chức năng:

RAISERROR('This message will show up right away...',0,1) WITH NOWAIT 

Bạn không nên thay thế hoàn toàn tất cả các bản in của bạn với RAISERROR. Nếu bạn có một vòng lặp hoặc con trỏ lớn ở đâu đó, hãy thực hiện nó một lần hoặc hai lần cho mỗi lần lặp hoặc thậm chí chỉ là một vài lần lặp lại.

Ngoài ra: lần đầu tiên tôi biết về RAISERROR tại liên kết này, mà tôi bây giờ xem xét nguồn dứt khoát về Lỗi xử lý SQL Server và chắc chắn đáng đọc:
http://www.sommarskog.se/error-handling-I.html

+33

Lưu ý rằng TRY/CATCH trong SQL sẽ chỉ bắt lỗi với mức độ nghiêm trọng> 10, vì vậy việc sử dụng RAISERROR theo cách này sẽ không chuyển vào câu lệnh CATCH của bạn. Đó là tuyệt vời, vì nó có nghĩa là bạn vẫn có thể sử dụng RAISERROR như thế này với TRY/CATCH. ref: http://msdn.microsoft.com/en-us/library/ms175976.aspx – Rory

+8

Lưu ý rằng điều này không hoạt động sau 500 tin nhắn đầu tiên; một khi bạn in nhiều hơn nó đột nhiên bắt đầu đệm! – GendoIkari

+0

@GendoIkari Tôi gặp vấn đề tương tự. Bạn đã giải quyết nó? –

15

Có ... Tham số đầu tiên của RAISERROR chức năng cần một biến NVARCHAR. Vì vậy, hãy thử những điều sau đây;

-- Replace PRINT function 
DECLARE @strMsg NVARCHAR(100) 
SELECT @strMsg = 'Here''s your message...' 
RAISERROR (@strMsg, 0, 1) WITH NOWAIT 

HOẶC

RAISERROR (n'Here''s your message...', 0, 1) WITH NOWAIT 
+9

Nhìn vào tab Tin nhắn ở phía dưới, bên cạnh tab Kết quả hoặc chuyển sang chế độ Kết quả Đến Văn bản. –

+0

Để chuyển sang chế độ Kết quả thành Văn bản, trong SSMS, Công cụ menu -> Tùy chọn -> Kết quả Truy vấn -> Máy chủ SQL -> Chung -> Đích mặc định cho Kết quả, và chọn "Kết quả thành Văn bản" thay vì "Kết quả thành Lưới", mở lại cửa sổ truy vấn và sau đó bạn sẽ không ngồi ở đó nhìn vào một tab Kết quả trống như một hình giả trong khi đầu ra RAISERROR chuyển đến tab Tin nhắn. – Adam

3

Chỉ cần cho các tài liệu tham khảo, nếu bạn làm việc trong các kịch bản (xử lý hàng loạt), không phải trong thủ tục lưu trữ, đỏ bừng đầu ra được kích hoạt bởi lệnh GO, ví dụ

print 'test' 
print 'test' 
go 

Nhìn chung, kết luận của tôi là như sau: sản lượng thực hiện MSSQL kịch bản, thực hiện trong SMS GUI hoặc với sqlcmd.exe, là đỏ ửng nộp, stdoutput, cửa sổ gui trên tuyên bố GO đầu tiên hoặc cho đến khi kết thúc kịch bản.

Tuôn ra bên trong các hàm thủ tục được lưu trữ khác nhau, vì bạn không thể đặt GO bên trong.

tham khảo: tsql Go statement

+0

'go' không chỉ là đầu ra tuôn ra, nó kết thúc lô theo liên kết bạn cung cấp. Bất cứ điều gì bạn 'declare'd được loại bỏ, vì vậy không phải là rất có thể sử dụng để gỡ lỗi. 'declare @test int print" Tôi muốn đọc cái này! " go set @ test = 5' mặc dù bạn có lỗi khi xác nhận '@ test' là không xác định vì nó nằm trong một lô mới. – funkwurm

+1

Tôi đồng ý, đây không phải là câu trả lời đúng cho câu hỏi này, nhưng tôi đặt câu trả lời (xem tuyên bố từ chối khi bắt đầu) vì nó có thể hữu ích cho người khác - ví dụ: một người chạy hàng loạt sql. –

9

Một lựa chọn tốt hơn là để không phụ thuộc vào PRINT hoặc RAISERROR và chỉ cần nạp "in" của bạn báo cáo vào một bảng ## Temp trong tempdb hoặc một bảng vĩnh viễn trong cơ sở dữ liệu của bạn mà sẽ cung cấp cho bạn tầm nhìn cho dữ liệu ngay lập tức thông qua câu lệnh SELECT từ cửa sổ khác. Điều này làm việc tốt nhất cho tôi. Sử dụng một bảng thường xuyên sau đó cũng phục vụ như một bản ghi cho những gì đã xảy ra trong quá khứ. Các báo cáo in có ích cho lỗi, nhưng sử dụng bảng nhật ký, bạn cũng có thể xác định điểm chính xác của lỗi dựa trên giá trị đăng nhập cuối cùng cho thực thi cụ thể đó (giả sử bạn theo dõi thời gian bắt đầu thực hiện tổng thể trong bảng nhật ký.)

+1

Điều này có thể là một vấn đề nếu bạn đang viết một kịch bản giao dịch thực sự với cam kết và rollback. Tôi không tin rằng bạn sẽ có thể truy vấn bảng tạm thời của bạn trực tiếp - và nó sẽ biến mất nếu giao dịch của bạn không thành công. – SteveJ

+0

@SteveJ bạn có thể truy vấn trực tiếp bằng cách sử dụng 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;' trong phiên theo dõi của bạn – TheConstructor

+0

@TheConstructor; Đó là một mẹo hữu ích - tôi sẽ tận dụng điều đó, cảm ơn. Tuy nhiên, không phải chúng tôi vẫn còn lại với bảng tạm thời đi xa trên rollback? Nếu phân tích thất bại, có vẻ như đó sẽ là một thiếu sót lớn. – SteveJ

3

Xây dựng dựa trên câu trả lời của @JoelCoehoorn, cách tiếp cận của tôi là để lại tất cả các câu lệnh PRINT của tôi tại chỗ, và chỉ cần làm theo chúng với câu lệnh RAISERROR để gây ra sự tuôn ra.

Ví dụ:

PRINT 'MyVariableName: ' + @MyVariableName 
RAISERROR(N'', 0, 1) WITH NOWAIT 

Ưu điểm của phương pháp này là những điều khoản PRINT có thể nối dây, trong khi RAISERROR không thể. (Vì vậy, cả hai cách bạn có cùng một số dòng mã, vì bạn phải khai báo và thiết lập một biến để sử dụng trong RAISERROR).

Nếu, như tôi, bạn sử dụng AutoHotKey hoặc SSMSBoost hoặc công cụ tương đương, bạn có thể dễ dàng thiết lập một phím tắt như "] flush" để nhập dòng RAISERROR cho bạn.Điều này giúp bạn tiết kiệm thời gian nếu đó là cùng một dòng mã mỗi lần, tức là không cần phải được tùy chỉnh để giữ văn bản cụ thể hoặc một biến.

Các vấn đề liên quan