2011-09-30 40 views
10

Tôi có một UDT CLR rằng sẽ có lợi rất nhiều từ phương pháp bảng giá trị, ala xml.nodes():Có thể tạo các phương thức * có giá trị * trong một kiểu SQL CLR do người dùng định nghĩa không?

-- nodes() example, for reference: 
declare @xml xml = '<id>1</id><id>2</id><id>5</id><id>10</id>' 
select c.value('.','int') as id from @xml.nodes('/id') t (c) 

Tôi muốn một cái gì đó tương tự cho UDT của tôi:

-- would return tuples (1, 4), (1, 5), (1, 6)....(1, 20) 
declare @udt dbo.FancyType = '1.4:20' 
select * from @udt.AsTable() t (c) 

Có ai có bất kỳ kinh nghiệm w/điều này? Mọi sự trợ giúp sẽ rất được trân trọng. Tôi đã thử một vài điều và tất cả đều thất bại. Tôi đã tìm tài liệu và ví dụ và không tìm thấy. Có, tôi biết tôi có thể tạo UDF bảng có giá trị mà lấy UDT của tôi như là một tham số, nhưng tôi đã hy vọng để bó tất cả mọi thứ bên trong một loại duy nhất, phong cách OO.

EDIT

Russell Hart tìm thấy the documentation states that table-valued methods are not supported, và cố định cú pháp của tôi để tạo ra lỗi runtime dự kiến ​​(xem dưới đây).

Trong VS2010, sau khi tạo một UDT mới, tôi đã thêm này vào cuối của định nghĩa struct:

[SqlMethod(FillRowMethodName = "GetTable_FillRow", TableDefinition = "Id INT")] 
public IEnumerable GetTable() 
{ 
    ArrayList resultCollection = new ArrayList(); 
    resultCollection.Add(1); 
    resultCollection.Add(2); 
    resultCollection.Add(3); 
    return resultCollection; 
} 

public static void GetTable_FillRow(object tableResultObj, out SqlInt32 Id) 
{ 
    Id = (int)tableResultObj; 
} 

này được xây dựng và triển khai thành công. Nhưng sau đó trong SSMS, chúng tôi nhận được lỗi thời gian chạy như mong đợi (nếu không phải từng từ):

-- needed to alias the column in the SELECT clause, rather than after the table alias. 
declare @this dbo.tvm_example = '' 
select t.[Id] as [ID] from @this.GetTable() as [t] 

Msg 2715, Level 16, State 3, Line 2 
Column, parameter, or variable #1: Cannot find data type dbo.tvm_example. 
Parameter or variable '@this' has an invalid data type. 

Vì vậy, có vẻ như sau cùng thì không thể. Và thậm chí nếu có thể, nó có thể sẽ không được khôn ngoan, với những hạn chế về việc thay đổi các đối tượng CLR trong SQL Server.

Điều đó nói rằng, nếu có ai biết hack để vượt qua giới hạn cụ thể này, tôi sẽ tăng một khoản tiền thưởng mới cho phù hợp.

Trả lời

6

Bạn đã đặt bí danh bảng chứ không phải các cột. Hãy thử,

declare @this dbo.tvm_example = '' 
select t.[Id] as [ID] from @this.GetTable() as [t] 

Theo tài liệu, http://msdn.microsoft.com/en-us/library/ms131069(v=SQL.100).aspx#Y4739, điều này sẽ thất bại trên một lỗi runtime liên quan đến loại không chính xác.

Lớp SqlMethodAttribute thừa kế từ lớp SqlFunctionAttribute, vì vậy SqlMethodAttribute kế thừa các trường FillRowMethodName và TableDefinition từ SqlFunctionAttribute. Điều này ngụ ý rằng nó có thể viết một phương pháp có giá trị bảng, mà không phải là trường hợp. Phương thức biên dịch và assembly triển khai, nhưng một lỗi về kiểu trả về IEnumerable được tăng lên khi chạy với thông báo sau: "Phương thức, thuộc tính hoặc trường" trong lớp '' trong assembly '' có kiểu trả về không hợp lệ. "

Có thể họ đang tránh hỗ trợ phương pháp như vậy. Nếu bạn thay đổi assembly bằng cách cập nhật phương thức, điều này có thể gây ra các vấn đề cho dữ liệu trong các cột UDT. Một giải pháp thích hợp là có một UDT tối thiểu, sau đó là một lớp riêng biệt của các phương pháp để đi cùng với nó. Điều này sẽ đảm bảo các phương pháp linh hoạt và đầy đủ tính năng.

phương pháp nút xml sẽ không thay đổi do đó không phải tuân theo các giới hạn triển khai tương tự.

Hy vọng điều này sẽ giúp Peter và chúc may mắn.

+0

Cảm ơn Russ, vâng, điều đó có ích. –

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