web-dev-qa-db-ja.com

行が変更されたDataRowコレクションを渡す場合、更新には有効なUpdateCommandが必要です

だから私は先週これを機能させました。少なくとも、やったと思った! DataGridView Update

それから私は今日再びプロジェクトに取り組み始め、

行が変更されたDataRowコレクションを渡す場合、更新には有効なUpdateCommandが必要です。

オン

scDB.SSIS_Configurations_StagingDataTable table = (scDB.SSIS_Configurations_StagingDataTable)stagingGrid.DataSource;
myStagingTableAdapter.Update(table);

StagingTableAdapterには、「filter」をパラメーターとして受け取る追加のクエリがあります。これは、DataGridViewを埋めるために使用されました。そのクエリを作成するためのウィザードに、「更新が生成されました」と表示されます。このエラーのあるほとんどの投稿では、コマンドビルダーを使用して更新ステートメントを生成する必要があります。私は何をしますか?

15
Sam

エラーは非常に文字通りです。アダプタには有効なSQL更新ステートメントが必要です。データセットデザイナとCommandBuilderがこれらを生成しますが、SQLを少し手作りしても問題はありません。

とにかく、Updateステートメントがまだ構成されていることと実際に何であるかを確認(デバッガー)する必要があります。これは、C#の問題というよりもSQLの問題である可能性があります。

編集:コマンドビルダーツールは、まっすぐな単一のテーブルのSelectステートメントのみを処理します。結合またはその他の凝ったものを使用すれば、あなたは自分でやっています。

7
Henk Holterman

このメッセージは、更新するテーブルに主キーが定義されていない場合にも表示されます。

21
Jason

私はサムと同じ問題に遭遇しました。突然機能しなくなったコードが機能していました。いつ書いたのかわかりませんでしたが、自動的に更新コマンドを推測して停止していたに違いありません。おそらく、私たちが気づかなかったバージョン間のMSからのサービスパック。とにかく、私が遭遇した解決策は、(私の場合はOracleの場合)OracleCommandBuilderを使用して、DataAdapter(fillを呼び出した後)をコンストラクターへのパラメーターとして受け取り、GetUpdateCommand()を呼び出してDataAdapterのUpdateCommandに割り当てることです。

pseudocode:

DataAdapter da = new DataAdapter(...)
...
da.Fill();
da.UpdateCommand = new OracleCommandBuilder(da).GetUpdateCommand();
...
da.Update();
14
Dan

Danの回避策は私には有効ですが、OracleCommandBuilderの代わりにSqlCommandBuilderを使用できます。

DataAdapter da = new DataAdapter(...)
...
da.Fill();
da.UpdateCommand = new SqlCommandBuilder(da).GetUpdateCommand();
...
da.Update();
6
Hoang

常に主キーで定義された列フィールドが必要です。そうでなければ、問題は常に存在します。主キーフィールドがない場合、SqlCommandBuilderは役に立ちません。

1
Md Shahriar

私はちょうど同じ問題を経験しました、そしてジェイソンの答えは私のために働きました:私は私のテーブルに主キーを割り当てるのを忘れました。

追加するもう1つのリマインダー:テーブルの問題を修正した後、Visual Studioに戻ったときに、データセットを含む.xsdファイルで、元のテーブルを削除して、サーバーエクスプローラーまたはデータベースから再度追加してください。冒険者。それ以外の場合、エラーは引き続き存在します。

1
LaBird

他の人が言っているように、自動生成された更新コードを作成するには、テーブルに主キーが設定されていることを確認する必要があります。私はこれをしましたが、それでも同じメッセージを見ていました

行が変更されたDataRowコレクションを渡す場合、更新には有効なUpdateCommandが必要です。

次に、テーブルアダプタも更新する必要があることを発見しました(考えてみると理にかなっています!)。

これを行っている間、Generate Insert、Update and Deleteステートメントオプションが選択されていることを再確認する価値があるかもしれません(以下のように)。

enter image description here

次に、ウィザードをクリックするだけで、最後の画面で、必要なコードをやり直すことが確認されます(現在は主キーを使用)。

enter image description here

1
d219

ページから:

注メインクエリに十分な情報がある場合、TableAdapterの生成時に、InsertCommand、UpdateCommand、およびDeleteCommandコマンドがデフォルトで作成されます。 TableAdapterのメインクエリが複数のテーブルSELECTステートメントである場合、デザイナがInsertCommand、UpdateCommand、およびDeleteCommandを生成できない可能性があります。これらのコマンドが生成されない場合、TableAdapter.Updateメソッドの実行時にエラーが発生する可能性があります。

したがって、私が言えることから、これらのステートメントは生成されているはずです。私は単一のテーブルを使用しています。

0
Sam

私も同じ問題に直面し、次の解決策を得ました。それを試してみてください。

private void btnSave_Click(object sender, EventArgs e)
{
    ConnStr = "Data Source=FIN03;Initial Catalog=CmsTest;Integrated Security=True";
    cn = new SqlConnection(ConnStr);
    cn.Open();
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = cn;
    mytran = cn.BeginTransaction(IsolationLevel.Serializable );

    cmd.Transaction = mytran;
    try
    {

        scb = new SqlCommandBuilder(da);
        da.Update(ds, "tblworker");
        mytran.Commit ();
        MessageBox.Show("Data update successfully"); 

    }
    catch (Exception err)
    {

           mytran.Rollback();

            MessageBox.Show(err.Message.ToString());           
    }
}
0
MulugetaLegesse