1

OleDbDataAdapterを使用してDataTableを更新しようとしましたが、コマンドについて混乱しました。私は時々別のテーブルから情報を取得するので、CommandBuilder を使用できません。そのため、自分でコマンドを作成しようとしましたが、パラメーターで難しいことがわかりました。DataTable.GetChanges は、INSERT または UPDATE コマンドを使用する必要がある行を返します。それらを区別できないと思います。次のことを完了する必要があります。

DataTable dt = new DataTable();
OleDbDataAdapter da = new OleDbDataAdapter();
// Here I create the SELECT command and pass the connection.
da.Fill(dt);
// Here I make changes (INSERT/UPDATE) to the DataTable (by a DataGridView).
da.UpdateCommand = new OleDbCommand("UPDATE TABLE_NAME SET (COL1, COL2, ...) VALUES (@newVal1, @newVal2, ...) WHERE id=@id"); // How can I use the values of the current row (that the da is updating) as the parameters (@newVal1, @newVal2, id....)?

どうもありがとうございました!

4

2 に答える 2

2

データ アダプタは、データ テーブルと連携して動作できます。そのため、私は実際に自分のものをクラスにまとめて、非常にうまく機能しています。私のものの複雑さは別として、ここにあなたを助けるかもしれないスニペットがあります. パラメーターを追加すると、データが DataTable から取得された列ソースを識別できます。このように、レコードが「追加」または「更新」(または「削除」) として内部的に識別される場合、SQL 挿入/更新/削除コマンドを作成すると、それぞれの行の列からデータが取得されます。

例えば。DataTable があるとします。主キーは「MyID」で、列は「ColX、ColY、ColZ」です。DataAdapter を作成し、select、update、delete コマンドを構築します... (? はパラメーターのプレースホルダーです)

DataAdapter myAdapter = new DataAdapter()

myAdapter.SelectCommand = new OleDbCommand();
myAdapter.InsertCommand = new OleDbCommand();
myAdapter.UpdateCommand = new OleDbCommand();
myAdapter.DeleteCommand = new OleDbCommand();

myAdapter.SelectCommand.CommandText = "select * from MyTable where MyID = ?";
myAdapter.InsertCommand.CommandText = "insert into MyTable ( ColX, ColY, ColZ ) values ( ?, ?, ? )";
myAdapter.UpdateCommand.CommandText = "update MyTable set ColX = ?, ColY = ?, ColZ = ? where MyID = ?";
myAdapter.DeleteCommand.CommandText = "delete from MyTable where MyID = ?";

ここで、それぞれにそれぞれの「パラメーター」が必要です。パラメータは、対応する「?」と同じ順序で追加する必要があります。プレースホルダー。

// パラメータを準備するために偽の値を入れていますが、これは単なるデータ型のためです。変更を適用すると、データ アダプターを介して変更されます。

OleDbParameter oParm = new OleDbParameter( "myID", -1 );
oParm.DbType = DbType.Int32;
oParm.SourceColumn = "myID";  // <- this is where it looks back to source table's column
oParm.ParameterName = "myID";  // just for consistency / readability reference

myAdapter.SelectCommand.Parameters.Add( oParm );

タイプに基づいて残りのパラメーターについても同様に行います... char、int、double、何でも

繰り返しますが、テーブルごとに管理を処理するラッパークラスが好きです...簡単に言えば

public myClassWrapper
{
    protected DataTable myTable;
    protected DataAdapter myAdapter;
    ... more ...

    protected void SaveChanges()
    {
    }
}

これよりも複雑ですが、「SaveChanges」の間、datatable と dataAdapter はそれぞれの目的のために同期されます。さて、データをフラッシュします。テーブルのステータスを確認すると、更新のためにテーブル全体を dataAdapter に渡すことができます。変更されたすべてのレコードを循環し、それぞれの変更をプッシュします。ただし、考えられるデータエラーをトラップする必要があります。

myAdapter.Update( this.MyTable );

「変更された」各レコードを見つけると、処理のためにアダプターに渡されるテーブルで見つかったパラメーターによって識別される列ソースから値をプルします。

うまくいけば、これはあなたが遭遇しているものに大きな飛躍をもたらしました.

---- フィードバックごとのコメント ----

あなたの更新をtry/catch内に置き、プログラムにステップインして例外が何であるかを確認します。エラーのメッセージまたは内部例外で詳細情報が得られる場合があります。ただし、UPDATE を単純化して、WHERE "Key" 要素を持ついくつかのフィールドのみを含めるようにしてください。

さらに、おっと、最初の部分の回答からこれを逃しました。データテーブルの「PrimaryKey」列を特定する必要がある場合があります。これを行うには、テーブルの主キーを表す列の配列を期待する DataTable のプロパティです。私がしたことは...

// set the primary key column of the table
DataColumn[] oCols = { myDataTbl.Columns["myID"] };
myDataTbl.PrimaryKey = oCols;

UPDATE の完全な更新文字列とそのすべてのパラメーターをコメントアウトします。次に、2〜3列とwhere句のみを設定するサンプルと同じくらい簡単に構築します

myAdapter.UpdateCommand.CommandText = "update MyTable set ColX = ?, ColY = ? where MyID=?";
Add Parameter object for "X"
Add Parameter object for "Y"
Add Parameter object for "MyID"

int や char などのフィールドを選択して、データ型変換の問題が発生する可能性を最小限に抑えます。それが機能したら、すべての「int」列と「character」列を追加してみてください...次に、他の列を追加します。また、どのデータベースに反対しますか。「?」を使用しないデータベースもあります。コマンドのプレースホルダーとして使用しますが、「名前付き」パラメーターを使用します。

"actualColumn = @namedCol"
or even
"actualColumn = :namedCol"

これで問題が解決することを願っています...

于 2012-04-17T13:09:49.863 に答える
1

このように、 String.Formatメソッドを使用@newVal1, @newVal2, ...してコード内のを置き換えることができます。da.UpdateCommand = new OleDbCommand(String.Format("UPDATE TABLE_NAME SET (COL1, COL2, ...) VALUES ({0}, {1}, ...) WHERE id=@id",OBJECT_ARRAY_CONTAINING_VALUES_FROM_THEDG));

[コメントごとのEidt]

を処理するrow[0]には、row[1]次のようなループが必要です。

for(i=0; i<rows.Count; i++) {

    da.UpdateCommand = new OleDbCommand(String.Format("UPDATE..。",row[i]);

    da.Update(dt);

}

于 2012-04-16T13:21:58.760 に答える