DBGridに表示したTableのレコードをDBNavigatorの[レコードの削除]で
削除するとDBGrid上ではそのレコードのみ消えます。
更新しようとClientDataSet.ApplyUpdates(0)をすると
通常は問題ないのですが
Table内にまったく同じ値のレコードがあった場合、
アドレスの書き込み違反のエラーになります。
後でTableを確認すると同じ値のレコードは全て消えています。
このあたりの仕組みを教えていただけないでしょうか。
そして回避する方法はあるでしょうか。
そもそもTableに同じレコードがあることの是非はあると思いますが
試作中なので。
なお接続はdbExpressで
SQLConnection
SQLDataSet
DataSetProvider
ClientDataSet
DataSource
です。
DBはMySQLです。
情報不足なら補いますのでよろしくお願いします。
この動作は全く正しいと思います。
逆にデーターベースに同じ値のレコードがある方がおかしいので、
このようなレコードを登録できなくする方が先決と思います。
一般的にはキー違反で登録できませんよね。
そうですね・・・
運用としてはもちろん正規化して主キーなりを設定して
レコードの重複を排除すべきなんでしょうが
MySQLでTableを作成するときに主キーを設定しなくても
Tableは作成できるし、重複レコードもいれられるんですよね。
そういうものなのですかね。他のDBはどうなんでしょうか。
Delphiではこのような想定はしてないのでしょうか?
コードで回避するしかないですか。
このままでは、書き込み違反のエラーを起こしているのが、
DelphiなのかMySQLなのか判定しにくいですね。
多分、DelphiのApplyUpdatesでDeleteSQLを発行しているのでしょう。
その場合、同じ値のレコードは消されてしまします。
デバッグ時のエラーメッセージは
「プロジェクトC:\test\project1.exeが例外により実行を停止しました。
'access violation at 0x0367be25:write of address 0x00030ebc'」
です。
http://forum.nifty.com/fdelphi/faq/00247.htm
これに書いてあるのを読むとDelphiでのプログラムに問題があるようです。
現在はSQLDataSet1.CommandTypeをctTableにして
CommandTextをテーブル名にしてテーブルを表示していますが
ほかの方法も試しながら何かわかればまた書き込みます。
もしヒントなどありましたら引き続きお願いいたします。
FDelhiのFAQに書いてあるのは、Delphiでのプログラムに問題があると
いうことで、Delphiが起こしていることではありません。
あくまで、プログラムが問題だといっているのです。
この場合は、DELETEするレコードが1レコードと想定したプログラムですが、
実際は複数レコードであったのでエラーが出ているのでしょう。
でも、実際問題全く同じレコードがあって、そのレコードを削除するのは、
他のレコードも不要だということではないでしょうか?
このようにキーがなければキー違反が出ませんが、その扱いは微妙です。
同じレコードが有れば、一つにまとめるのがRDBMSを使う利点と思いますので、
キーを付けることをおすすめします。
いろいろアドバイスありがとうございました。
やはりDB側でキー設定するようにし
また、クライアント側でもチェックをかけて
削除を回避するように考えてみます。
ツイート | ![]() |