10

次のような SQL CLR 関数があります。

public partial class UserDefinedFunctions {
    [Microsoft.SqlServer.Server.SqlFunction(TableDefinition = "number int", FillRowMethodName = "FillRow")]
    public static IEnumerable MyClrFunction(object obj) {
        // read obj array input and then
        var result = new ArrayList();
        result.Add((SqlInt32)1);
        result.Add((SqlInt32)2);
        result.Add((SqlInt32)3);
        return result;
    }

    public static void FillRow(object obj, out SqlInt32 number) {
        number = (SqlInt32)obj;
    }

}

このように使用したいと思います:

DECLARE @x arrayOfInt

INSERT INTO @x VALUES (10)
INSERT INTO @x VALUES (20)
INSERT INTO @x VALUES (30)

SELECT * FROM dbo.MyClrFunction(@x)

arrayOfIntは次のとおりです。

CREATE TYPE [dbo].[arrayOfInt] AS TABLE(
[item] [int] NOT NULL,
PRIMARY KEY CLUSTERED 
    (
    [item] ASC
    ) WITH (IGNORE_DUP_KEY = OFF)
)

問題は、arrayOfIntが sql_variant と互換性がないことです。配列 (テーブル) 引数を持つ CLR テーブル値関数を記述できますか?

4

1 に答える 1

11

SQLCLR は、テーブル値パラメーター (TVP) をサポートしていません。

  • 手順の作成

    [ type_schema_name. ] data_type
    ...
    CLR プロシージャのガイドライン:

    • テーブル値またはカーソルデータ型はパラメーターとして使用できません。
  • 関数の作成

    [ type_schema_name. ] parameter_data_type ... CLR 関数の場合、 textntextimage、ユーザー定義のテーブル型、およびタイムスタンプ
    データ型 を除く、CLR ユーザー定義型を含むすべてのデータ型が許可されます。

ただし、いくつかのオプションがあります。

  1. 配列が数値および/または文字列の単純なリストである場合は、(SqlString / NVARCHAR(MAX) を介して) 区切られた値のリストをいつでも送信し、String.Split() を使用してアンパックできます。

  2. 配列がより複雑な場合 (つまり、複数のフィールド)、データを XML でラップし、それを SqlXml として渡すことができます。

  3. または、複雑な配列がある場合は、好きな構造の CLR UDT を作成し、それを関数に渡すことができます。ただし、これにはもう少し努力が必要です。

  4. また、テーブル値パラメーターは単なるテーブル (テーブル変数) であり、配列やコレクションなどのメモリ内データ構造ではないことに注意してください。TVP の主な利点と使用例は、アプリケーションから SQL Server にデータを送信する際の複雑さを軽減し、パフォーマンスを向上させることです。テーブル変数を作成し、それを CLR ストアド プロシージャ (または関数) に渡したいなど、既に SQL Server 内にいる場合は、問題を少し異なる方法で見るだけで済みます。同じ基本的なことを達成できます:

    • テーブル変数の代わりに一時テーブルを使用する
    • 一時テーブル名を CLR ストアド プロシージャに渡す
    • "Context Connection = true;"ローカルの一時オブジェクトにアクセスできるため、インプロセス接続 (つまり、接続文字列 = ) を使用します。
    • 渡されたテーブル名を使用して実行する任意の SQL で一時テーブルを使用できます。
    • 渡されたテーブル名に対して単純な操作を行うことで、そのテーブルから .NET コンテキストにデータを取得し、 and を介してSELECT *各行を読み取ることができます。SqlCommand.ExecuteReader()SqlDataReader.Read()
于 2011-01-22T04:09:10.513 に答える