10

ソース情報のDataTableを操作していくつかの有用な値を生成できるサードパーティのDLLがあり、SQLServer2008でテーブル値のUDFとして呼び出せるようにSQLCLRを介して接続しようとしています。

ここでの概念をさらに一歩進めて、DBからのソースデータのテーブルを操作するCLRテーブル値関数をプログラムしたいと思います。

T-SQL側で何が必要かを理解していると確信しています。しかし、メソッドシグネチャは.NET(C#)コードではどのように見えるべきでしょうか?「SQLServerからのテーブルデータ」のパラメータデータ型は何でしょうか。

例えば

/* 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) */

lat / lon-> distanceはばかげた例であり、もちろんSQLで完全に処理する方がよいでしょう。しかし、SQLCLRアセンブリに関連付けられたテーブル値UDFを介したテーブルイン->テーブルアウトの一般的な意図を示していることを願っています。

これが可能かどうかはわかりません。SQLCLRInitMethodメソッドのシグネチャはC#ではどのようになりますか?

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

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

それが不可能な場合は、C#コード内で「contextconnection = true」SQL接続を使用して、関連するキーを指定して必要なデータをCLRコンポーネントにクエリさせることができます。ただし、これはDBスキーマの変更に敏感です。したがって、SQLにすべてのソースデータをバンドルさせて、それを関数に渡すことを望んでいます。

ボーナスの質問-これがまったく機能すると仮定すると、複数の入力テーブルでも機能しますか?

4

2 に答える 2

9

.NETデータ型とSQLデータ型の間の利用可能なマッピングによって決定される、SQLCLR関数の有効な入力の固定リストがあることがわかりました。

SQLデータ型「テーブル」は、CLRを介したマッピングがないものとして明示的に呼び出されます。

エルゴ、テーブル値のデータをメソッドパラメータとしてテーブル値のCLR関数に渡すことはできません。

代替案

ゆがみを介して表形式のデータを取得し、パラメータselect ... for xmlにフィードすることは可能のようです。SqlXml

.NETコードで正常に使用SqlConnection conn = new SqlConnection("context connection = true");して、TVFが必要な表形式データをDBに照会できるようにしました。

于 2010-06-17T00:50:28.063 に答える
3

この質問は(ほとんど)重複しているようです:

配列引数を持つCLRテーブル値関数

簡単に言うと、その質問では、区切りリスト、XML、またはCLRUDTをお勧めします。

テーブルにデータを入力し、そこから関数にDataTableをロードするオプションもあります。実際のテーブルを使用することは、「スレッドセーフ」(他のSPIDとデータを交差させないため)にするために余分な労力が必要であり、関数がDMLを実行できないため、追加のクリーンアッププロセスが必要になるため、推奨されない可能性があります。データの処理が完了したら、クリーンアップするステートメント。特定の状況では、これが望ましい場合もありますが、この特定のケースではおそらくそうではありません。幸いなことに、一時的なテーブルSQLCLR関数内でアクセス可能(読み取り専用ですが、T-SQL関数ではまったくアクセスできません)。一時テーブルを使用すると、永続テーブルを使用する場合と同じ利点がありますが、他のSPIDとの衝突や、個別にクリーンアップする必要があるという欠点はありません。唯一の要件は、コンテキスト接続を使用することです。これは、セッションベースのオブジェクト(つまり、一時テーブル)にアクセスする唯一の方法です。

したがって、この特定のケースでは、TempTableまたはXMLオプションのいずれかを試すことをお勧めします。

于 2011-01-22T04:42:27.447 に答える