15

This page from SQL Server 2008 BOL, nói về CLR Thủ tục lưu trữ và có phần được gắn nhãn "Tham số bảng giá trị", nói về cách chúng có thể thuận lợi. Điều đó thật tuyệt - Tôi rất thích sử dụng TVP trong phần mềm CLR của mình, nhưng tiếc là điều này có vẻ là tham chiếu duy nhất trong vũ trụ cho khả năng như vậy, và phần không mô tả cú pháp sẽ là gì (cũng như không có thêm thông tin được liên kết ở cuối đoạn)Các tham số bảng giá trị cho các thủ tục CLR trong SQL Server 2008 - có thể?

Chắc chắn, tôi có thể dễ dàng tìm thấy mô tả về cách sử dụng TVP từ procs T-SQL hoặc cách thực hiện các trình diễn CLR nói chung. Nhưng viết một proc CLR mà có một TVP? Không có gì. Điều này là tất cả cao unusal kể từ khi đi qua dữ liệu đa hàng để một proc được lưu trữ là một vấn đề phổ biến.

Điều này khiến tôi tự hỏi liệu sự hiện diện của phần trên trang đó có phải là lỗi hay không. Ai đó xin vui lòng cho tôi biết nó không phải và chỉ cho tôi để biết thêm thông tin/ví dụ.

[EDIT]

tôi sắp sửa đăng bài này lên một trong những diễn đàn MS quá khi tôi đi qua this, which seems to be the final nail in the coffin. Có vẻ như không thể làm được.

Trả lời

5

Tôi có thể tìm thấy lotmorereferences. Tuy nhiên, đây là tất cả để truyền các tham số có giá trị bảng tới các thủ tục TSQL, vì vậy đó là sử dụng ít.

Tuy nhiên, tôi đã đi đến kết luận rằng điều đó là không thể. Đầu tiên, có list of mappings giữa các kiểu CLR và SQL. Đối với các loại bảng không có bản đồ, vì vậy sau đây không hoạt động, ví dụ:

[SqlProcedure] 
public static void StoredProcedure(DataTable tvp, out int sum) 
{ 
    return 42; 
} 

và sau đó

CREATE TYPE MyTableType AS TABLE 
(
    Id INT NOT NULL PRIMARY KEY, 
    [Count] INT NOT NULL 
) 
GO 
CREATE ASSEMBLY ClrTest FROM '<somePath>' 
GO 
CREATE PROCEDURE ClrTest 
AS EXTERNAL NAME ClrTest.StoredProcedures.StoredProcedure 
GO 

Bất cứ loại bạn cố gắng (DataTable, DbDataReader, IEnumerable), cuộc gọi CREATE PROCEDURE giữ tạo ra một lỗi 6552: TẠO THỦ TỤC TẠO cho "ClrTest" không thành công vì kiểu T-SQL và CLR cho tham số "@tvp" không khớp.

Thứ hai, các tài liệu trên trang web bạn liên kết đến nói: Một loại bảng người dùng định nghĩa không thể được thông qua như một tham số bảng giá trị, hoặc được trả lại từ một thủ tục lưu trữ được quản lý hoặc chức năng thực hiện trong SQL Quá trình máy chủ.

Tôi dường như không thể tìm thấy bất kỳ nơi nào để tạo kiểu bảng do người dùng xác định trong C#, nhưng điều này cũng có vẻ là một kết thúc chết.

Có thể bạn có thể đặt câu hỏi của mình ở đâu đó trên diễn đàn Microsoft. Nó vẫn còn kỳ quặc mà họ đề cập đến các tham số có giá trị bảng trên trang sproc CLR nhưng không bao giờ giải thích làm thế nào để thực hiện điều này. Nếu bạn tìm thấy bất kỳ giải pháp, tôi muốn biết.

+0

Tôi vừa đọc toàn bộ câu hỏi của bạn một cách chi tiết. CLR sprocs, không phải là TSQL. Xin lỗi cho câu trả lời này trong trường hợp đó, tôi sẽ cố gắng tìm một số giải pháp tốt hơn ... –

+0

lol, np - thanks. Tôi sẽ giữ-giữ phiếu bầu của tôi cho đến khi bạn trở lại, sau đó ;-) – philsquared

+0

Cảm ơn rw. Có vẻ như đoạn văn đó trong tài liệu (được thêm gần đây) không chính xác. Tôi sẽ theo dõi tại một số điểm trên diễn đàn MS. – philsquared

1

Trong khi nó trông giống như đi qua bảng trực tiếp đến thủ tục CLR hiện là không thể, tôi có một kết quả, mặc dù tối ưu sub bởi:

  • xác định một bảng TSQL giá trị UDT FooTable
  • định nghĩa một hàm TSQL mà mất FooTable như một param và trả về XML sử dụng FOR XML EXPLICIT
  • qua XML kết quả với chức năng CLR/thủ tục thay vì bảng chính nó

Không id eal, nhưng nó gần hơn một chút.

2

Giải pháp là tuần tự hóa dữ liệu dạng bảng của bạn thành chuỗi có định dạng Json, sau đó chuyển chuỗi vào trong CLR của bạn. Trong proc proc hoặc function của bạn, bạn sẽ phân tích cú pháp json thành một đối tượng IEnumerable, list hoặc tableular. Sau đó, bạn có thể làm việc với dữ liệu giống như bất kỳ loại dữ liệu bảng nào khác.

Tôi đã viết một số tiện ích có khả năng tuần tự hóa bất kỳ bảng sql nào thành chuỗi có định dạng Json. Tôi rất sẵn lòng chia sẻ chúng với bất kỳ ai cung cấp địa chỉ e-mail của họ. Phil Factor đã viết một trình phân tích cú pháp T-SQL Json tốt đẹp mà ông gọi là parseJson. Tôi đã thích nghi giải pháp của mình với clr mà thực hiện nhanh hơn nhiều. Cả hai chấp nhận một chuỗi định dạng Json và tạo ra một bảng từ chuỗi. Tôi cũng có một loạt các tiện ích Json tôi sử dụng với cả T-SQL và CLR có khả năng tuần tự hóa, phân tích cú pháp, chèn, xóa và cập nhật các chuỗi có định dạng Json được lưu trữ trong các cột sql.

3

Bạn có thể sử dụng bảng tạm thời được tạo và điền trước khi bạn gọi thủ tục và đọc bảng bên trong quy trình clr.

+0

Tính năng thêm vào câu trả lời hiện được chấp nhận là gì? Đây phải là một bình luận, không phải là một câu trả lời. Kiểm tra [câu hỏi metaSO] này (http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question) và [Jon Skeet: Blog mã hóa] (http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx) về cách đưa ra câu trả lời đúng. – Yaroslav

+1

Câu trả lời này là tuyệt vời vì nó là viết tắt bởi vì nó chạm vào một phương tiện hoàn toàn khác nhau của truyền dữ liệu giữa các thủ tục lưu trữ hơn so với những người được đề cập trong các câu trả lời khác. Xem bài đăng blog cổ điển, dứt khoát của Erland Sommerskog tại http://www.sommarskog.se/share_data.html#temptables về những ưu và khuyết điểm của từng phương pháp cụ thể, nơi anh ta thảo luận về các trường hợp sử dụng cụ thể cho từng trường hợp.Giải pháp bảng tạm thời có các trường hợp sử dụng riêng của nó; nó hóa ra là giải pháp cho vấn đề tôi đang tìm cách giải quyết khi tôi gặp phải chủ đề này. – SQLServerSteve

1

Nếu bạn sử dụng C# (như trái ngược với VB, mà thiếu lặp tùy chỉnh), bạn có thể viết mã ADO.NET để gọi ExecuteNonQuery() và chạy một thủ tục lưu trữ với một SqlDbType.Structured tham số (ví dụ, một TVP).

Bộ sưu tập được truyền dưới dạng giá trị của TVP phải triển khai IEnumerable<SqlDataRecord>. Mỗi lần yield return của IEnumerable này được thực thi, một SqlDataRecord “hàng” được pipelined tới tham số "bảng".

Xem this article để biết chi tiết.