2010-09-19 5 views

Trả lời

13

Trừ khi bạn chuẩn bị phân tích nội dung của ROUTINE_DEFINITION trong INFORMATION_SCHEMA.ROUTINES, thì đặt cược tốt nhất của bạn sẽ là thực hiện các thủ tục và đọc thông tin cột từ các bản ghi được trả về.

Trong .NET, bạn có thể thực hiện điều này bằng cách đọc kết quả của quy trình được lưu trữ vào một DataTable và truy vấn thuộc tính Columns.

Lý do không có cách dễ dàng để làm điều này là một thủ tục được lưu trữ có khả năng có thể trả về các tập kết quả khác nhau dựa trên các tham số. Không có định dạng tập kết quả cố định nào giống như có các hàm do người dùng định nghĩa.

Sửa

Như đã đề cập trong câu trả lời khác, bạn sẽ cần phải sử dụng SET FMTONLY ON để đảm bảo không có dữ liệu được trả về. Có một số tình huống mà SET FMTONLY sẽ không hoạt động, ví dụ: khi sử dụng các bảng #temp trong các thủ tục được lưu trữ của bạn, nhưng có một số workaround.

+0

Đối với SQL2012, hãy làm theo lời khuyên trong bài đăng này: http://stackoverflow.com/a/14575114/569662 –

+0

Nếu Microsoft không muốn sử dụng DataTable trong .NET Core, phương pháp này sẽ ngừng hoạt động nếu bạn chuyển sang Core. –

9

Tôi chỉ chạy Profiler để xem cách Visual Studio thực hiện điều này cho việc kéo và thả tập dữ liệu mạnh mẽ.

Đây là mã được gửi.

SET NO_BROWSETABLE ON; 
SET FMTONLY ON; 

exec dbo.aspnet_Roles_GetAllRoles @ApplicationName=NULL 

Vì vậy, tôi cho rằng có thể không có cách nào "chính thức hơn" để thực hiện.

Rõ ràng bạn cần lưu ý rằng một thủ tục được lưu trữ duy nhất có thể trả về nhiều bộ kết quả hoặc các tập kết quả khác nhau phụ thuộc vào các tham số được truyền.

Đối với những người trên 2012+ cách tiếp cận khác có thể được sử dụng sp_describe_first_result_set

1

cách của tôi để làm điều này: Chỉnh sửa các thủ tục lưu trữ để có một VÀO khoản:

Thay đổi

Select * from tablename 

để

Select * INTO _tablename FROM tablename 

Điều này tạo ra bảng trong cơ sở dữ liệu. Sau đó, sử dụng SELECT * FROM INFORMATION_SCHEMA WHERE TABLE_NAME = '_tablename'

Đừng quên hoàn tác sửa đổi đối với sproc.