2012-04-16 3 views
1

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

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 [email protected]"); // How can I use the values of the current row (that the da is updating) as the parameters (@newVal1, @newVal2, id....)? 

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

答えて

2

データアダプタデータテーブルと連携して動作することができます。そういうわけで、私は実際に私のクラスを一緒に包み込み、とてもうまく働いています。私のものの複雑さを除いて、ここにあなたを助けるかもしれないスニペットがあります。パラメータを追加するときは、DataTableからデータが来ている列ソースを特定できます。このように、レコードが内部的に「追加」または「更新」(または「削除済み」)として識別されると、SQL挿入/更新/削除コマンドを作成すると、それぞれの行の列からデータが取り出されます。

たとえば、 DataTableを持っていて、主キーが "MyID"で、列が "ColX、ColY、ColZ"であるとします。私は今、それぞれがそれぞれの「パラメータ」を持たなければならない

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 = ?"; 

私のDataAdapterを作成して、私の選択、更新を構築、コマンドに何かなどを削除...(?はパラメータのプレースホルダーです)。パラメータは、対応する「?」と同じ順序で追加する必要があります。プレースホルダー。

//私はパラメータを準備するために偽の値を入れていますが、それはちょうど //データ型の目的です。それは

繰り返しますが、私は次のように持っているものは何でも

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型、ダブルに基づいて、パラメータの残りの部分についても同様行う変更を適用する場合には、データアダプタを介して変更を取得しませんテーブルごとに管理を処理するラッパークラス...簡単

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

    protected void SaveChanges() 
    { 
    } 
} 

ちょうどこのよりそのより複雑ではなく、「SaveChangesメソッド」の間に、データテーブルおよびデータアダプターが自分の目的のために同期しています。今、データをフラッシュします。私はテーブルの状態を確認し、更新するためにテーブル全体をdataAdapterに渡すことができます。そして、変更されたすべてのレコードを循環してそれぞれの変更をプッシュします。あなたは可能なデータエラーのためにトラップする必要があります。

myAdapter.Update(this.MyTable); 

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

うまくいけば、これにより、あなたはあなたが走っているものに大きな飛躍をもたらしたと思います。

---- FEEDBACK PER COMMENT ----

私はのtry/catch内のあなたの更新を入れて、例外が何であるかを確認するためにプログラムにステップです。エラーのメッセージadn /または内部例外は、より多くの情報を与えるかもしれません。ただし、UPDATEを単純化して、WHERE "Key"要素を含むFEWフィールドのみを含めるようにしてください。

さらに、最初の部分の回答からこれを逃しました。データテーブルの「PrimaryKey」列を識別する必要があります。これを実行するには、テーブルの主キーを表す列を必要とするDataTableのプロパティを設定します。私がしたことは...

あなたの完全な更新文字列とそのすべてのパラメータをあなたのUPDATEにコメントします。彼らは、その後、データ型変換のための課題の少なくとも確率を持っているので、その後、同じような単純な私の唯一の2~3列を設定するサンプルおよび句int型またはcharなどの

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"と "character"列を追加してから、他のものを追加してみてください。また、どのデータベースに対処していますか。いくつかのデータベースは "?"プレースホルダのコマンドではなく「名前付き」のパラメータ、これはこぶの上にあなたを取得いくつか使用して

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

希望を使用するよう...

+0

ありがとうございます。私はまだUpdateメソッドの実行に問題があります。それは私がパラメータの1つの価値を見逃していると言います。問題は私がデータセットを使用していない可能性がありますか? (私はちょうどDataTableを使用して、それをDataGridViewにBindingSourceオブジェクトでバインドしています)。 – gavra

+0

@gavra、拡張答えを参照してください。 – DRapp

+0

ありがとうございました!今回は、主キー列を更新しようとしたときの問題でした。今はうまくいきます。それは私のプロジェクトです。素敵な一日を! – gavra

1

あなたは[コメントあたりEidt]

はあなたのようなループを必要とするrow[1]row[0]を、処理するためにこのda.UpdateCommand = new OleDbCommand(String.Format("UPDATE TABLE_NAME SET (COL1, COL2, ...) VALUES ({0}, {1}, ...) WHERE [email protected]",OBJECT_ARRAY_CONTAINING_VALUES_FROM_THEDG));

のように、あなたのコードで@newVal1, @newVal2, ...を置き換えるためにString.Format Methodを使用することができますfor(i=0; i<rows.Count; i++) {

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

        da.Update(dt);

}

+0

は、ご返信いただきありがとうございます。私はこの方法を知っています。問題は、データテーブル内のすべての行を更新することであり、更新は1つだけです。たとえば、パラメータrows [0] .myColumnとしてパラメータを使用し、その後にパラメータをrows [1] .myColumnにする必要があります。また、更新コマンドを定義しなくても更新する方法があることに気付きました。ちょっと分かりません。 – gavra

+0

Microsoftの[DataAdapter.Update](http://msdn.microsoft.com/en-us/library/system.data.common.dataadapter.update.aspx)ドキュメントを見ましたか? –

関連する問題