2010-06-09 12 views
7

Chúng tôi có một DLL của bên thứ ba có thể hoạt động trên một DataTable thông tin nguồn và tạo ra một số giá trị hữu ích, và chúng tôi đang cố gắng kết nối nó thông qua SQLCLR. UDF bảng giá trị trong SQL Server 2008.Truyền bảng dưới dạng tham số tới SQLCLR TV-UDF

Lấy khái niệm here thêm một bước nữa, tôi muốn lập chương trình CLR Table-Valued Function hoạt động trên bảng dữ liệu nguồn từ DB.

Tôi khá chắc chắn rằng tôi hiểu những gì cần phải xảy ra ở phía T-SQL của sự vật; nhưng, chữ ký của phương thức trông giống như thế nào trong mã .NET (C#)? Điều gì sẽ là kiểu dữ liệu tham số cho "dữ liệu bảng từ SQL Server?"

ví dụ:

/* Setup */ 
CREATE TYPE InTableType 
AS TABLE (LocationName VARCHAR(50), Lat FLOAT, Lon FLOAT) 
GO 

CREATE TYPE OutTableType 
AS TABLE (LocationName VARCHAR(50), NeighborName VARCHAR(50), Distance FLOAT) 
GO 

CREATE ASSEMBLY myCLRAssembly 
FROM 'D:\assemblies\myCLR_UDFs.dll' 
WITH PERMISSION_SET = EXTERNAL_ACCESS 
GO 
CREATE FUNCTION GetDistances(@locations InTableType) 
RETURNS OutTableType 
AS 
EXTERNAL NAME myCLRAssembly.GeoDistance.SQLCLRInitMethod 
GO 

/* Execution */ 

DECLARE @myTable InTableType 
INSERT INTO @myTable(LocationName, Lat, Lon) VALUES('aaa', -50.0, -20.0) 
INSERT INTO @myTable(LocationName, Lat, Lon) VALUES('bbb', -20.0, -50.0) 
SELECT * FROM @myTable 

DECLARE @myResult OutTableType 
INSERT INTO @myResult 
GetDistances @myTable /* SQLCLR Call: GeoDistance.SQLCLRInitMethod(@myTable) */ 

Vĩ độ/khoảng cách -> khoảng cách là một ví dụ ngớ ngẩn nên được xử lý hoàn toàn hơn trong SQL; nhưng tôi hy vọng nó minh họa ý định chung của table-in -> table-out thông qua một UDF bảng có giá trị gắn với một assembly SQLCLR.

Tôi không chắc chắn điều này là có thể; chữ ký phương thức SQLCLRInitMethod trông như thế nào trong C#?

public class GeoDistance 
{ 
    [SqlFunction(FillRowMethodName = "FillRow")] 
    public static IEnumerable SQLCLRInitMethod(<appropriateType> myInputData) 
    { 
     //... 
    } 

    public static void FillRow(...) 
    { 
     //... 
    } 
} 

Nếu đó là không thể, tôi biết tôi có thể sử dụng một "kết nối context = true" kết nối SQL trong mã C# để have the CLR component query for the necessary data cho các phím có liên quan; nhưng điều đó nhạy cảm với những thay đổi trong lược đồ DB. Vì vậy, tôi hy vọng chỉ có SQL gói tất cả các dữ liệu nguồn và chuyển nó vào hàm.

Câu hỏi bổ sung - giả sử công trình này ở tất cả, nó cũng sẽ hoạt động với nhiều hơn một bảng đầu vào?

+0

có thể trùng lặp của [Truyền bảng dưới dạng tham số vào máy chủ sql UDF] (http://stackoverflow.com/questions/1609115/pass-table-as-parameter-into-sql-server-udf) - Câu trả lời của Lukasz Lysik là giải pháp cho câu hỏi của bạn: Bạn cần sử dụng các loại bảng do người dùng xác định. –

+0

Phải, tôi nên làm rõ câu hỏi một chút. Tôi hỏi cụ thể về cách thực hiện thành phần CLR này. Tôi nhận thức được những gì cần phải xảy ra ở khía cạnh T-SQL của mọi thứ (hoặc nghĩ rằng tôi - mã t-SQL ví dụ đang được đăng để cho thấy cách tôi giả định nhu cầu này hoạt động ở bên đó, trong trường hợp tôi phạm sai lầm ở đó); nhưng, chữ ký của phương thức trông như thế nào trong C#? Các tham số phương thức cho "dữ liệu bảng từ SQL Server là gì?" – Skeolan

+1

để kiểm tra nó, cho phép một đối tượng và trả lại tên loại của nó :) –

Trả lời

7

Hóa ra rằng có một danh sách cố định đầu vào hợp lệ trên một hàm SQLCLR, xác định bởi sẵn mapping between .NET datatypes and SQL datatypes

SQL Datatype "bảng" được một cách rõ ràng gọi là có không có bản đồ qua CLR.

Ergo, không thể truyền dữ liệu có giá trị bảng INTO hàm CLR có giá trị bảng làm tham số phương thức.

Alternatives

Nó dường như có thể để có được dữ liệu bảng trong qua select ... for xml vặn vẹo để nuôi vào một tham số SqlXml.

Tôi đã sử dụng thành công SqlConnection conn = new SqlConnection("context connection = true"); trong mã .NET để cho TVF truy vấn DB cho dữ liệu dạng bảng mà nó cần.

2

Câu hỏi này có vẻ là (chủ yếu) là một bản sao của:

CLR Table-valued function with array argument

Như ghi chú nhanh, trong câu hỏi mà tôi đề nghị: danh sách được phân định, XML, hoặc CLR UDT.

Ngoài ra còn có tùy chọn điền bảng và tải DataTable từ nó trong hàm.Việc sử dụng một bảng thật có thể không được khuyến khích vì nó sẽ đòi hỏi thêm nỗ lực để làm cho nó "an toàn luồng" (không phải dữ liệu chéo với các SPID khác) và sẽ yêu cầu thêm một quá trình dọn sạch vì Hàm sẽ không thể thực hiện DML tuyên bố để làm sạch nó lên một khi nó đã được thực hiện với dữ liệu. Trong những tình huống nhất định, điều này có thể được ưa thích nhưng có lẽ không phải cho trường hợp cụ thể này. May mắn thay, các Bảng tạm thời có thể truy cập trong các hàm SQLCLR (dưới dạng chỉ đọc, nhưng chúng không thể truy cập được trong tất cả các hàm T-SQL). Sử dụng Temp Tables sẽ có những lợi thế tương tự như sử dụng Bảng vĩnh viễn nhưng không phải là nhược điểm của va chạm với SPID khác hoặc cần phải được làm sạch riêng biệt. Yêu cầu duy nhất là bạn sử dụng kết nối ngữ cảnh vì đó là cách duy nhất để truy cập các đối tượng dựa trên phiên (tức là bảng tạm thời).

Vì vậy, đối với trường hợp cụ thể này, tôi khuyên bạn nên thử sử dụng tùy chọn Bảng Temp hoặc XML.