2008-11-06 105 views
59

Tại sao câu lệnh PRINT trong T-SQL dường như chỉ đôi khi hoạt động? Các ràng buộc khi sử dụng nó là gì? Dường như đôi khi một tập hợp kết quả được tạo ra, nó trở thành một hàm rỗng, tôi giả định để ngăn chặn việc làm hỏng resultset, nhưng có thể đầu ra của nó không đi ra ngoài trong một tập kết quả khác, chẳng hạn như đếm hàng không?Câu lệnh IN trong T-SQL

+2

Bạn có thể cho ví dụ về một số mã đôi khi in và đôi khi không. Tôi không nghĩ rằng tôi hiểu câu hỏi. –

Trả lời

85

Vì vậy, nếu bạn có tuyên bố như sau, bạn đang nói rằng bạn không nhận được kết quả 'in'?

select * from sysobjects 
PRINT 'Just selected * from sysobjects'

Nếu bạn đang sử dụng SQL Query Analyzer, bạn sẽ thấy có hai tab ở dưới cùng, một trong số đó là "Messages" và đó là nơi các câu lệnh 'print' sẽ xuất hiện.
Nếu bạn lo ngại về thời gian nhìn thấy những điều khoản in, bạn có thể muốn thử sử dụng một cái gì đó giống như

raiserror ('My Print Statement', 10,1) with nowait

này sẽ cung cấp cho bạn thông điệp ngay lập tức như báo cáo kết quả đạt được, chứ không phải đệm đầu ra, như Query Analyzer sẽ làm theo hầu hết các điều kiện.

+1

Thỏa thuận tuyệt vời. Vui mừng điều này đã làm việc cho bạn. Tôi thường nói với bộ phân tích truy vấn để cung cấp cho tôi văn bản đầu ra, để tôi có thể nhìn thấy các thông điệp nội tuyến (Ctrl + T). Thưởng thức! –

+1

Các đối số 10 và 1 trong ví dụ về raiserror là gì? –

+0

10, 1 thực sự chỉ nói "không có gì để xem ở đây" với máy chủ. Xem https://docs.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql#arguments để biết chi tiết về ý nghĩa của chúng. –

34

Bản in trong TSQL là một sinh vật bị hiểu lầm, có thể là do tên của nó. Nó thực sự gửi một thông báo tới cơ chế xử lý lỗi/tin nhắn, sau đó chuyển nó tới ứng dụng gọi. IN là khá câm. Bạn chỉ có thể gửi 8000 ký tự (4000 ký tự unicode). Bạn có thể gửi một chuỗi chữ, một biến chuỗi (varchar hoặc char) hoặc một biểu thức chuỗi. Nếu bạn sử dụng RAISERROR, thì bạn bị giới hạn trong một chuỗi chỉ 2.044 ký tự. Tuy nhiên, nó dễ dàng hơn nhiều khi sử dụng nó để gửi thông tin đến ứng dụng gọi điện vì nó gọi một hàm định dạng tương tự như printf cũ trong thư viện C chuẩn. RAISERROR cũng có thể chỉ định một số lỗi, mức độ nghiêm trọng và mã trạng thái ngoài tin nhắn văn bản và nó cũng có thể được sử dụng để trả về các thông điệp do người dùng định nghĩa được tạo bằng thủ tục lưu sẵn của hệ thống sp_addmessage. Bạn cũng có thể buộc các thông điệp được ghi lại.

Các thói quen xử lý lỗi của bạn sẽ không tốt cho việc nhận thư, mặc dù thư và lỗi rất giống nhau. Kỹ thuật thay đổi, tất nhiên, theo cách thực tế bạn kết nối với cơ sở dữ liệu (OLBC, OLEDB, vv). Để nhận và xử lý thư từ Cơ sở dữ liệu máy chủ SQL, khi bạn đang sử dụng System.Data.SQLClient, bạn sẽ cần phải tạo một đại biểu SqlInfoMessageEventHandler, xác định phương thức xử lý sự kiện, để nghe sự kiện InfoMessage trên lớp SqlConnection. Bạn sẽ thấy rằng thông tin ngữ cảnh thông báo như mức độ nghiêm trọng và trạng thái được chuyển làm đối số cho hàm gọi lại, vì từ góc độ hệ thống, các thông báo này giống như lỗi. Nó luôn luôn là một ý tưởng tốt để có một cách để nhận được những tin nhắn này trong ứng dụng của bạn, ngay cả khi bạn chỉ là spooling vào một tập tin, bởi vì sẽ luôn có được một sử dụng cho họ khi bạn đang cố gắng để đuổi theo một vấn đề thực sự mơ hồ. Tuy nhiên, tôi không thể nghĩ rằng tôi muốn người dùng cuối xem chúng trừ khi bạn có thể đặt trước mức thông tin hiển thị nội dung trong ứng dụng.

2

Vì lợi ích của bất kỳ ai khác đọc câu hỏi này thực sự thiếu báo cáo in từ đầu ra của họ, thực tế có trường hợp bản in thực thi nhưng không được trả lại cho khách hàng. Tôi không thể nói cụ thể họ là gì. Tôi có thể nói với bạn rằng nếu đặt câu lệnh đi ngay trước và sau bất kỳ câu lệnh in nào, bạn sẽ thấy nó nếu nó được thực thi.

+0

Tôi cũng đã gặp phải các trường hợp trong đó một lệnh in không ghi vào cửa sổ tin nhắn khi được mong đợi. Nó xảy ra với tôi sau một cam kết hoặc một rollback. –

21

Thông báo bộ đệm phân tích truy vấn. Các câu lệnh PRINT và RAISERROR đều sử dụng bộ đệm này, nhưng câu lệnh RAISERROR có tùy chọn WITH NOWAIT.Để in tin nhắn ngay lập tức, hãy sử dụng các thông tin sau:

RAISERROR ('Your message', 0, 1) WITH NOWAIT 

RAISERROR sẽ chỉ hiển thị 400 ký tự của bạn và sử dụng cú pháp tương tự như chức năng C printf để định dạng văn bản.

Xin lưu ý rằng việc sử dụng RAISERROR với tùy chọn WITH NOWAIT sẽ xóa bộ đệm thư, vì vậy tất cả các thông tin đệm trước đó cũng sẽ được xuất.

+1

Cú pháp RAISERROR là một nỗi đau, nhưng đặt một lỗ trống sau khi PRINT của tôi thực hiện công việc, cảm ơn thông tin! – Cobusve

18

Gần đây tôi đã gặp phải vấn đề này và cuối cùng là vì tôi đã có câu lệnh chuyển đổi trên biến số không. Vì điều đó gây ra lỗi, toàn bộ lệnh in được hiển thị dưới dạng null và không in được.

Ví dụ - Đây sẽ thất bại:

declare @myID int=null 
print 'First Statement: ' + convert(varchar(4), @myID) 

Ví dụ - Đây sẽ in:

declare @myID int=null 
print 'Second Statement: ' + coalesce(Convert(varchar(4), @myID),'@myID is null') 
+0

Không chỉ PRINT: sử dụng toán tử + với bất kỳ giá trị null nào trong T-SQL kết quả bằng một giá trị rỗng, bất kể nếu có những thứ khác được nối với nhau không phải là rỗng. Sử dụng ISNULL (@myID, '') hoặc COALESCE như bạn đã cho phép null có thể nối với chuỗi. – troy

0

Bạn có các biến có liên quan đến các báo cáo in được đầu ra? nếu vậy, tôi đã thấy rằng nếu biến không có giá trị thì câu lệnh in sẽ không được sử dụng.

+0

Bạn có vẻ như bạn không hiểu tác dụng của việc ghép nối 'NULL' bằng một chuỗi. 'PRINT 'a' + CAST (NULL AS VARCHAR (MAX));' hoạt động chính xác như tôi mong đợi. – binki

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