4

c#、.net 2.0、および SQLServer 2012 Express を使用して、DataTable をストアド プロシージャに送信しようとしています。

これはおおよそ私がやっていることです:

        //define the DataTable
        var accountIdTable = new DataTable("[dbo].[TypeAccountIdTable]");

        //define the column
        var dataColumn = new DataColumn {ColumnName = "[ID]", DataType = typeof (Guid)};

        //add column to dataTable
        accountIdTable.Columns.Add(dataColumn);

        //feed it with the unique contact ids
        foreach (var uniqueId in uniqueIds)
        {
            accountIdTable.Rows.Add(uniqueId);
        }

        using (var sqlCmd = new SqlCommand())
        {
            //define command details
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlCmd.CommandText = "[dbo].[msp_Get_Many_Profiles]";
            sqlCmd.Connection = dbConn; //an open database connection

            //define parameter
            var sqlParam = new SqlParameter();
            sqlParam.ParameterName = "@tvp_account_id_list";
            sqlParam.SqlDbType = SqlDbType.Structured;
            sqlParam.Value = accountIdTable;

            //add parameter to command
            sqlCmd.Parameters.Add(sqlParam);

            //execute procedure
            rResult = sqlCmd.ExecuteReader();

            //print results
            while (rResult.Read())
            {
                PrintRowData(rResult);
            }
        }

しかし、次のエラーが表示されます。

ArgumentOutOfRangeException: No mapping exists from SqlDbType Structured to a known DbType.
Parameter name: SqlDbType

(MSDN、SO、およびその他の場所で) さらに調査すると、.net 2.0 がデータベースへの DataTable の送信をサポートしていないように見えます (などの欠落SqlParameter.TypeName)。この機能は .net 2.0 では利用できないと主張している

これは本当ですか?

もしそうなら、データのコレクションをデータベースに送信する別の方法はありますか?

前もって感謝します!

4

2 に答える 2

1

初期設定では、ADO.NET は正当な理由でこれをサポートしていません。DataTable は、データベース内の実際のテーブルにマップされる場合とマップされない場合がある、ほぼ任意の数の列を取ることができます。

あなたが何をしたいのかを理解している場合 - DataTable の内容を、同じ構造を持つ事前定義された実際のテーブルにすばやくアップロードする場合は、SQLBulkCopyを調査することをお勧めします。

ドキュメントから:

Microsoft SQL Server には、bcp という名前の一般的なコマンド プロンプト ユーティリティが含まれており、単一のサーバー上またはサーバー間で、あるテーブルから別のテーブルにデータを移動できます。SqlBulkCopy クラスを使用すると、同様の機能を提供するマネージ コード ソリューションを作成できます。SQL Server テーブルにデータを読み込む方法は他にもありますが (たとえば、INSERT ステートメント)、SqlBulkCopy はそれらよりもパフォーマンスが大幅に向上します。

SqlBulkCopy クラスは、SQL Server テーブルにのみデータを書き込むために使用できます。ただし、データ ソースは SQL Server に限定されません。データを DataTable インスタンスに読み込むか、IDataReader インスタンスで読み取ることができる限り、任意のデータ ソースを使用できます。

SqlDateTime 型の DataTable 列を、SQL Server 2008 で追加された日付/時刻型の 1 つである SQL Server 列に一括ロードすると、SqlBulkCopy が失敗します。

ただし、それ以降のバージョンの SQL Server でテーブル値パラメーターを定義し、それを使用して、要求しているメソッドでテーブル (DateTable) を送信できます。http://sqlwithmanoj.wordpress.com/2012/09/10/passing-multipledynamic-values-to-stored-procedures-functions-part4-by-using-tvp/に例があります

于 2013-01-01T16:44:28.257 に答える
0

私の経験によると、C# でコードをコンパイルできれば、それは ADO.Net がその型をサポートしていることを意味します。ただし、コードの実行時に失敗した場合は、ターゲット データベースがサポートしていない可能性があります。あなたの場合、[Sql Server 2012 Express] について言及しているため、サポートされていない可能性があります。私の理解では、テーブル タイプは [Sql Server 2005] からサポートされていましたが、データベース互換モードを 99 以上に保つ必要がありました。私はそれを使用し、ストアド プロシージャの in-parameter として[ User Defined Table Types ] (別名 UDTT)を使用して、ストアド プロシージャを介して一括更新を行うために広く使用しているため、2008 年に動作することを 100%確信しています。一括更新に MERGE コマンドを使用するには、データベースの互換性を 99 以上に保つ必要があります。

もちろん、SQLBulkCopy を使用することもできますが、それがどれほど信頼できるかはわかりません。

于 2015-02-02T18:06:05.727 に答える