MS SQL 2008:sql_variant(まだ?)のような列を持つテーブルタイプはADO.NETと互換性がありません

sql_variant -SQL Serverでサポートされているさまざまなデータ型の値を格納するデータ型。

これは、開発されたデータベースのいくつかの一般的な側面に役立つ場合があります。 たとえば、アプリケーション設定テーブルで、またはオブジェクトの動的プロパティを維持するとき。

ADO.NETの場合、ここで考えられる便利な点は、sql_variantをマネージコードからストアドプロシージャに転送できることです。ストアドプロシージャは、渡される値に一般化されます。 送信された値に従ってロジックを分岐する場合、実際の型はSQL_VARIANT_PROPERTY関数を介して認識できます。

実際、単一のパラメーターで問題はありません。 パラメータのリストを渡す必要がある場合に問題が発生します。



アイデアはシンプルです。 この記事から判断すると、パラメーターのリストをユーザー定義の表タイプにマップすることが最善です。 .NETのオブジェクトタイプは、パラメータータイプSqlDbType.VariantまたはDbType.Objectに対応することに留意して、管理スタジオとビジュアルスタジオを実行します。

  1. ジェネリック型を作成します。
    CREATE TYPE [dbo].[GenericList] AS TABLE([value] [sql_variant] NOT NULL)
  2. このパラメーターを処理するプロシージャを作成します。
    CREATE PROCEDURE [dbo].[ParseGenericList]
    @list GenericList readonly
    AS
    BEGIN
    SET NOCOUNT ON;
    SELECT value from @list
    END

  3. 結果を見越してハンドルを元気にこすり、データベースにパラメータを渡すための.NETコードを記述します。
    DataTable table = new DataTable("GenericList");
    table.Columns.Add("value", typeof(object));

    table.Rows.Add("string");
    table.Rows.Add(DateTime.Now);
    table.Rows.Add(145);

    using (SqlCommand command = connection.CreateCommand()) // created before
    {
    command.CommandText = "dbo.ParseGenericList";
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddWithValue("@list", table);
    conn.Open();
    using (SqlDataReader r = command.ExecuteReader())
    while (r.Read())
    Console.WriteLine(r.GetValue(0));
    }

開始後、予想される3行の代わりに、オブロミンゴ鳥は例外としてコンソール内を飛行します。
"value" . "Object"

公平を期すために、データ型をそれぞれobject \ sql_variantからstring \ nvarcharまたはfloat \ floatに変更すると、すべてが正常に機能することに注意する価値があります。

データベースのクエリにも問題はありません。
declare @list dbo.GenericList;
insert into @list(value) select cast(0 as bit);
insert into @list(value) select cast('bla' as nvarchar(3));
insert into @list(value) select cast(0.15 as float);

exec dbo.ParseGenericList @list


数分間のグーグル検索で、Microsoftテクニカルサポートで公開レポートを見つけます。
クラック

通信内で、MSは私がインストールするパッチへのリンクを提供します。 1つ(ホイスト用)がインストールされておらず、もう1つ(.net用)がインストールされています。 しかし、あまり結果はありません。 議論自体は、バグは非常に複雑な問題であると思われるため、さらに調査する必要があると述べています。

ここにそのような不快な物語があります。 いくつかの方法で問題を回避することができます(クランチ):

残念だ。 実際、最大のinりは、問題に対するボルトの詰まりです。

Source: https://habr.com/ru/post/J101326/


All Articles