none
エラー「同時実行違反」への対処法? RRS feed

  • 質問

  • エラー「同時実行違反」への対処法についてお尋ねします。
    「強制的に2桁入力させるには?」の続きですが,入力したデータで更新しようとすると,
      同時実行違反:UpdateCommandによって,処理レコード1レコードのうち0件が処理されました。
    とのエラーになってしまいました。
    <試した対策>
    わからないなりに,「パラメータコレクションエディタ」でSouceColumnNullプロパティをtrueに設定してみましたが,状況は変わりませんでした。

    どの様な対処が必要なのでしょうか。お教え願います。

    UPDATE  学力
    SET  ID = ?, 学年 = ?, 回数 = ?, 国語 = ?, 数学 = ?, 社会 = ?, 理科 = ?, 英語 = ?, 合計 = ?, 平均 = ?, 級順 = ?, 年順 = ?
    WHERE  (ID = ?) AND (学年 = ?) AND (回数 = ?) AND (国語 = ?) AND (数学 = ?) AND (社会 = ?) AND (理科 = ?) AND (英語 = ?) AND (合計 = ?) AND (平均 = ?) AND (級順 = ?) AND (年順 = ?)
       
       private void btnUodate_Click(object sender, EventArgs e)
            {
                //this.BindingContext[dsGakuInp.学力入力].EndCurrentEdit();
                try
                {
                    int iRows = odaGakuInp.Update(dsGakuInp.学力入力);
                    MessageBox.Show("Update " + iRows.ToString());
                }
                catch(Exception eUP)
                {
                    MessageBox.Show(eUP.Message);
                }
            }

    2006年8月31日 23:11

回答

  • やっと解決することができました。
    空白のフィールドがあると「同時実行違反」になることを確かめることができました。
    それで対策としてすべてのフィールドを仮文字”/”で埋めることにしました。

    それにしても,Accessでテーブルを作る際に,<空文字列の許可=はい>とあらかじめ設定してありましたので「空白」が原因ではないと思い込んでしまっていたのが失敗の原因でした。

    しかし,データグリッドのすべてのセルが"/"で埋まっているのをみると,「きれいでない」と思ってしまいます。

    別の対策をお持ちの方がいらっしゃいましたら,ぜひご紹介願います。

    最後になりましたが,trapemiyaさん,ありがとうございました。

    *このメッセージの投稿後に気づいたのですが,ダミーの文字は" "でもOKでした。

     

    2006年9月3日 8:33

すべての返信

  • まず、同時実行違反とはどういうものかを確認しておきます。
    同時実行違反とは、自分がレコードを読んできた時と同じ値をwhere条件にしてレコードを更新に行ったとき、更新対象のレコードが無く、更新できなかった状態のことを言います。自分がレコードを読んできた時と同じ値をwhere条件にした時、更新するレコードが無かったわけですから、誰かが違う値に変更しているということになります。
    一般的に、

    Update table set hoge=新しいhoge where hoge = 自分が読んできた時のhoge

    になります。

    よく問題になるのは、この新旧のパラメータの指定です。zen73さんは?(無名パラメータ)というプレースフォルダを使われているので、OleDb、たぶんmdbを使われているのだと思いますが、無名パラメータですので、パラメータを指定する順序が非常に大事になります。指定した順番に?にあてはめられていくからです。
    この辺りを確認してみて下さい。

    #将来的なことを考えれば、SQL Server 2005 Express Editionとか使うことを検討してみてはいかがでしょうか? ストアドプロシージャを使えるというのは大きいです。

    2006年9月1日 1:04
    モデレータ
  • 毎度お手を煩わせてしまい申し訳ありません。

     trapemiya さんからの引用
    無名パラメータですので、パラメータを指定する順序が非常に大事になります。指定した順番に?にあてはめられていくからです。
    この辺りを確認してみて下さい。

    どの順で指定していくのか,見当もつきません。
     trapemiya さんからの引用
    将来的なことを考えれば、SQL Server 2005 Express Editionとか使うことを検討してみてはいかがでしょうか? ストアドプロシージャを使えるというのは大きいです。

    ストアドプロシージャについて勉強してみます。

    2006年9月1日 2:04
  • TableAdapterとか使われてないような感じでしたので、ご自分でパラメータの指定をされているのかと思いましたが、違うのでしょうか?
    更新周りのソースを見せていただけませんか?
    2006年9月1日 2:19
    モデレータ
  • すみません。よろしくお願いします。

    データソース dsGakuInp
    データバインディングソース bsGakuInp
    テーブルアダプタ odaGakuInp

    SELECT   学力.ID, Meibo.ID AS Expr1, 学力.学年, 学力.回数, Meibo.年, Meibo.組,
           Meibo.[NO], Meibo.氏名, 学力.国語, 学力.数学, 学力.社会, 学力.理科,
           学力.英語, 学力.合計,   学力.平均
    FROM     (Meibo LEFT OUTER JOIN 学力 ON Meibo.ID = 学力.ID)

    //DataViewの設定
    private DataView dvMeibo = new DataView();

    private void frmGakuInp_Load(object sender, EventArgs e)
    {
        //データを取得
        odaGakuInp.Fill(dsGakuInp.学力入力);

        //Viewを取得
        dvMeibo.Table = dsGakuInp.学力入力;

        //dataGridViewの設定
        dataGridView1.DataSource = dvMeibo;
        GridWidth();

       ComboBoxList();
        classFilter();
    }

    private void cmbKai_SelectedIndexChanged(object sender, EventArgs e)
    {
        classFilter();
    }

    private void cmbNen_SelectedIndexChanged(object sender, EventArgs e)
    {
        classFilter();
    }

    private void cmbKumi_SelectedIndexChanged(object sender, EventArgs e)
    {
        classFilter();
    }

    private void classFilter()
    {
       string nen = Convert.ToString(cmbNen.SelectedIndex + 1);
        string kumi = Convert.ToString(cmbKumi.SelectedIndex + 1);
        string kai = Convert.ToString(cmbKai.SelectedIndex + 1);

        dvMeibo.RowFilter = string.Format("年='{0}' AND 組='{1}'", nen, kumi);
        dataGridView1.DataSource = dvMeibo;
    }

    private void ComboBoxList()
    {
        cmbKai.Text = Convert.ToString(cmbKai.Items[0]);
        cmbNen.Text = Convert.ToString(cmbNen.Items[0]);
        cmbKumi.Text = Convert.ToString(cmbKumi.Items[0]);
    }

    2006年9月1日 3:34
  • えっと、見たいのはDataAdapterのUpdate文と、それのパラメータ定義と、そのパラメータに値を設定しているところです。このパラメータに新旧の値がそれぞれ正しく設定されていないと、同時実行エラーになります。
    2006年9月1日 4:11
    モデレータ
  • 失礼しました。

    <DataAdapterのUpdate文>
    UPDATE  学力
    SET        ID = ?, 学年 = ?, 回数 = ?, 国語 = ?, 数学 = ?, 社会 = ?, 理科 = ?,
           英語 = ?, 合計 = ?, 平均 = ?, 級順 = ?, 年順 = ?
    WHERE  (ID = ?) AND (学年 = ?) AND (回数 = ?) AND (国語 = ?) AND
           (数学 = ?) AND (社会 = ?) AND (理科 = ?) AND (英語 = ?) AND
           (合計 = ?) AND (平均 = ?) AND (級順 = ?) AND (年順 = ?)
    <パラメータ定義>
    長い文(自動生成)ですので一部だけですけど・・・
    this._adapter.UpdateCommand.Parameters.Add
    (new System.Data.OleDb.OleDbParameter
    ("ID", System.Data.OleDb.OleDbType.WChar, 50,
    System.Data.ParameterDirection.Input, ((byte)(0)), ((byte)(0)), "ID", System.Data.DataRowVersion.Current, false, null));

    ID, 学年, 回数, 国語, 数学, 社会, 理科,英語, 合計, 平均, 級順, 年順
    のパラメータ
    ParameterName ID
    AllowDbNull     true
    ColumnName    ID
    DbType        String
    Direction       Input
    Precition       0
    ProviderType   WChar
    Scale         0
    Size          50
    SourceColumn  ID
    SourceColumnNullMapping true
    SourceVirsion           Current

    Original_ID, (学年, 回数, 国語, 数学, 社会, 理科,英語, 合計, 平均, 級順, 年順)
    のパラメータ
    ParameterName Original_ID
    AllowDbNull     true
    ColumnName    ID
    DbType        String
    Direction       Input
    Precition       0
    ProviderType   WChar
    Scale         0
    Size          50
    SourceColumn  ID
    SourceColumnNullMapping true
    SourceVirsion           Original






    2006年9月1日 5:40
  • DataAdapterの自動生成をされているんですね。どこに問題があるのか絞り込まなければなりません。Update文のパラメータにどのような値が実際にセットされているのか、確認してみて下さい。
    ブレークポイントで止めて、_adapter.UpdateCommand.CommandTextや、_adapter.UpdateCommand.Parametersの中を見てみてください。
    <DataAdapterのUpdate文>で書かれているUpdate文は、自動生成された_adaperのUpdateCommand.CommandTextなんですよね?

    2006年9月1日 8:49
    モデレータ
  •  trapemiya さんからの引用
    <DataAdapterのUpdate文>で書かれているUpdate文は、自動生成された_adaperのUpdateCommand.CommandTextなんですよね?

    そうです。クエリビルダでつくってます。

    いろいろとやってはいるのですが,頭がぐじゃぐじゃに混乱して何をやっているのかを説明するのも難しくて・・・。

    しばらくはもう少し整理して考えて見ます。

    2006年9月1日 22:34
  • やっと解決することができました。
    空白のフィールドがあると「同時実行違反」になることを確かめることができました。
    それで対策としてすべてのフィールドを仮文字”/”で埋めることにしました。

    それにしても,Accessでテーブルを作る際に,<空文字列の許可=はい>とあらかじめ設定してありましたので「空白」が原因ではないと思い込んでしまっていたのが失敗の原因でした。

    しかし,データグリッドのすべてのセルが"/"で埋まっているのをみると,「きれいでない」と思ってしまいます。

    別の対策をお持ちの方がいらっしゃいましたら,ぜひご紹介願います。

    最後になりましたが,trapemiyaさん,ありがとうございました。

    *このメッセージの投稿後に気づいたのですが,ダミーの文字は" "でもOKでした。

     

    2006年9月3日 8:33