MFCのアプリケーションでデータベースの削除を行いたいのですが、
Deleteすると、「構文エラーまたはアクセス違反です」というエラー
メッセージが返ってきます。
CanUpdateすると0以外が返るので、更新可能状態にあると思うので、
Delete出来ない理由が分かりません。
初心者なもので、どなたかご教授お願いします。
-環境-
Windows XP
VC++6.0 MFC ダイアログベース
ODBC 3.525.1132.0
-ソース-
m_Recordset.Open();
if(m_Recordset.CanUpdate()!=0)
{
m_Recordset.MoveFirst();
m_Recordset.Delete(); ←ここでエラー発生
m_Recordset.MoveNext();
}
m_Recordset.Close();
データが一つもない状態かもしれません。
Deleteする前にIsEOFかIsBOF関数でチェックした方がいいです。
データが1つもない状態でもAddNewは可能であるためCanUpdateはTRUEを返します。
すみません。
少し忙しくて、返信が遅くなってしまいました。
> Deleteする前にIsEOFかIsBOF関数でチェックした方がいいです。
確認してみたのですが、両方とも0を返したので、データが1つもないわけでは、
ないようです。
接続先のDBって何を使っているのでしょう。
接続に使っているDBのアカウントに削除権限が無いと削除できないとか
ないですねぇ。あと、接続先のDBの中身を Query Browserのようなソフトで
確認できるのであれば、レコードが存在しているかどうかは確認できると
思うのですが、確認手段が無いのでしょうか?
あと、マルチサイトポストをするのであれば、
ポストした先の全ての掲示板のケアもちゃんと行ってくださいね。
マルチサイトポストが嫌がられるのはこのケアをちゃんとしない人が
多いからです。
全てのサイトのケアをする自信が無いのであれば、
マルチサイトポストをするべきでは有りません。
個人的な感想ですが、このCRecordset::Deleteの使い方は
あまり好きではないです。
使った事がないので、何となくですがMSDNによると
>カレントレコードを削除します。うにゃうにゃ
となっているので目的の削除とは微妙に違う気がします。
また
>バルク行フェッチをインプリメントした場合、Delete は呼び出せません。
>呼び出すと、アサートします。
この辺ではないでしょうか?
どうせSQLを書いて削除するなら
CDatabaseのExeceuteSQLを使う方が簡単かも知れません。
DBFETCH: MFC ODBC データベース クラスでの複数行フェッチ
も参照してみて下さい。
提示のサンプルだけではこちらでは再現出来ないので
こんな所でどうでしょう。
PATIOさん、もにさん、レスありがとうございます。
> レコードが存在しているかどうかは・・・
レコードが存在しているのは間違いないと思います。
実際にカレントレコードを取得することは可能でした。
> マルチサイトポストをするのであれば・・・
大変失礼しました。。。
他の掲示板のケアも行っておきます。
> バルク行フェッチをインプリメントした場合、Delete は呼び出せません。
「バルク行フェッチ」は私も気になったので、以前上記のサイトを確認したのですが、
いまいち理解できませんでした。
なんとなくですが、データベースを更新したいなら、「バルク行フェッチ」は
使用してはいけないのだと解釈し、
> AddNew、Edit、Delete、または Update の各メンバ関数を呼び出すと、
> アサーションは失敗します。
と書いてあったのですが、AddNewは可能だったので、「バルク行フェッチ」は
使用していないと判断したのですが、間違っていますか?
ポスト先: http://homepage1.nifty.com/MADIA/
PATIOさんの言われるように、使っているDB等の環境と、
可能であれば再現出来る最小のコードを提示するのが
解決の近道かと思います。
#整理するだけで意外と解決したりします。
また、CDatabase::ExecuteSQL(DELETE TABLENAME WHERE 条件)
も検討してみては?(レコードセットと同じ条件のSQL書くだけですし)
どういう条件でそのエラーが出るか試す事も出来ないので
回答がつきにくいのかと思います。
SQL文も使っているDBによって違いますね。
同じDELETE文もDBによってはエラーになる可能性が大きいです。
SQL文は使っているDBに従ったほうがいいです。
テスト用のテーブルを作ってもらって、そのDBのクライアント用ソフトから
DELETE文を送って実際に削除できるか試してみるのもいいですね。
こんな例題でよい?
void CSSMDLTView::On_Delete()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してくださ
い
UpdateData(TRUE);
CSSMDLTDoc* pDoc = GetDocument();
CSSMDLTSet oSet(&pDoc->m_database);
oSet.m_strFilter.Format(COP_ID = %d AND DTL_EDA = %2.2d
,Owner_No,atoi
(m_EDA));
if(oSet.Open(CRecordset::dynaset,NULL)) {
if(!oSet.IsEOF()){
oSet.Delete();
m_EDIT1 = _T( );
m_EDIT2 = _T( );
m_EDIT3 = _T( );
UpdateData(FALSE);
MessageBox( 正常終了, 削除処理, MB_OK );
}
else{
MessageBox( 削除対象なし, 削除処理, MB_OK );
}
}
oSet.Close();
}