MS SQL 2008:sql_variant(まだ?)のような列を持つテーブルタイプはADO.NETと互換性がありません
sql_variant -SQL Serverでサポートされているさまざまなデータ型の値を格納するデータ型。
これは、開発されたデータベースのいくつかの一般的な側面に役立つ場合があります。 たとえば、アプリケーション設定テーブルで、またはオブジェクトの動的プロパティを維持するとき。
ADO.NETの場合、ここで考えられる便利な点は、sql_variantをマネージコードからストアドプロシージャに転送できることです。ストアドプロシージャは、渡される値に一般化されます。 送信された値に従ってロジックを分岐する場合、実際の型は
SQL_VARIANT_PROPERTY関数を介して認識できます。
実際、単一のパラメーターで問題はありません。 パラメータのリストを渡す必要がある場合に問題が発生します。
アイデアはシンプルです。
この記事から判断すると、パラメーターのリストをユーザー定義の表タイプにマップすることが最善です。 .NETのオブジェクトタイプは、パラメータータイプ
SqlDbType.Variantまたは
DbType.Objectに対応することに留意して、管理スタジオとビジュアルスタジオを実行します。
- ジェネリック型を作成します。
CREATE TYPE [dbo].[GenericList] AS TABLE([value] [sql_variant] NOT NULL)
- このパラメーターを処理するプロシージャを作成します。
CREATE PROCEDURE [dbo].[ParseGenericList]
@list GenericList readonly
AS
BEGIN
SET NOCOUNT ON;
SELECT value from @list
END
- 結果を見越してハンドルを元気にこすり、データベースにパラメータを渡すための.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用)がインストールされています。 しかし、あまり結果はありません。 議論自体は、バグは非常に複雑な問題であると思われるため、さらに調査する必要があると述べています。
ここにそのような不快な物語があります。 いくつかの方法で問題を回避することができます(クランチ):
- 単一の汎用sql_variantリストの代わりに、特定のタイプ(datetime、int、floatなど)を持つ複数のリストを渡します。
- ペアのリスト(string_value、value_type)を渡し、ストアドプロシージャで直接sql_variantに値をキャストします。
- Rを除き、CRUDで渡されたパラメーターが適用できないことを想定します。その後、行のリストを転送し、既存のsql_variantフィールドのキャストの結果を送信された行と比較できます。
- xml-structuresを支持してsql_variantの使用を拒否します。
残念だ。 実際、最大のinりは、問題に対するボルトの詰まりです。
All Articles