dbExpress コンポーネント (Delphi 7) を使用して、データベース プログラムに取り組んでいます。データは、TSQLDataSet -> TDataSetProvider -> TClientDataSet -> TDatasource -> TDBEdit コンポーネントを介してデータベースから取得されます。今まで、フォームは正しく機能していました。TSQLDataset のクエリは次のとおりです。
select id, name, byteken, timeflag from scales where id = :p1
データベース テーブルに大きな (2048) varchar フィールドを追加しました。このフィールドを上記のクエリに追加して(そして TDBMemo または TDBRichEdit を TDatasource に接続して)、新しいテキスト フィールドの値を編集しようとすると、次のメッセージが表示されます。
Unable to find record. No key specified.
フォームに TDBMemo がない場合 (ただし、クエリに varchar フィールドがある場合) に同じエラーが発生します。クエリから varchar フィールドを削除するとすぐに、すべてが再び正常に機能します。
この問題の原因は何ですか?
==== 詳細情報 ====
これで、フォームに永続フィールドを定義しました。テーブルへのキーを保持するフィールドのプロバイダー フラグは [pfInUpdate,pfInWhere,pfInKey] に設定されていますが、他のすべてのフィールドのフラグは [pfInUpdate,pfInWhere] に設定されています。これでは問題は解決しません。
永続フィールドは clientdataset で定義されました。TSQLDataSet でそれらを定義すると、「キーが指定されていません」というエラー メッセージは表示されません。プログラムはまだこのエラー メッセージを表示します (これについては前に触れませんでした)。
EDatabase error: arithmetic exception, numeric overflow or string truncation
大きな文字列フィールドには、'displaywidth' と 'size' の正しい値があります。
==== さらに詳しい情報 ====
非データ認識コンポーネントを使用するようにフォームを書き直しました。1 つのクエリでデータベースからデータを取得します (TSQLDataSet で使用しているものとまったく同じクエリ文字列を使用)。その後、データはコントロールに転送されます。ユーザーがフォームの [OK] ボタンを押すと、更新または挿入を実行する別のクエリを介してデータがデータベースに戻されます。これは正しく機能するため、データ認識コンポーネントの問題が何であるかはわかりません。
==== さらに別の情報スニペット ====
同様の問題に対処しているように見えるスタックオーバーフローでこの質問を見つけました。クエリを次のように変更しました
select id, name, name, byteken, timeflag,
cast (constext as varchar (2048)) as fconstext
from scales
where id = :p1
dbMemo のデータフィールドを「fconstext」に設定します。テキストを dbMemo に追加した後、「applyupdates」呼び出しが次のメッセージで失敗するようになりました
column unknown 'fconstext'
その名前で作成された永続フィールドがあるという事実にもかかわらず。
これが助けになるのか、単に水を濁らせるのかはわかりません。
==== 詳細情報、4 月 23 日 ====
データベース テーブルからフィールドを削除し、再度追加しました。問題のあるデータ フィールドに入力される文字列が約 260 文字未満である限り、書かれたプログラムは問題なく動作します。文字列の長さが256になるまで、一度に10文字を問題なく数回追加しました。次に、さらに文字を追加し(数えずに)、保存しようとしましたが、エラーが発生しました。この時点から、さらに1 文字追加しようとすると、エラー メッセージが表示されます (これは clientdataset の「applyupdates」メソッドで表示されます)。
もともと、フィールドには 832 文字が含まれていたため、正常に保存できる文字数に厳密な制限はありません。しかし、エラー メッセージが表示されると、あたかもデータベースがエラーがあることを記憶しているかのように、常に表示されます。
==== 詳細情報、4 月 24 日 ====
もう一度、データベースからフィールドを削除してから追加し直しました。文字セットは WIN1251 ですが、理由は今のところわかりません (キリル文字は必要ありません)。フィールド自体の定義方法に関係なく、データベース対応コントロールを使用して入力できる最大文字数は約 280 のようです。
その後、この問題が発生する実際のプログラムで非データ認識コントロールを使用するようになりましたが、この制限が存在しないことを保証できます。したがって、提案されているように、問題が文字サイズの不一致によるものではないことはかなり確信しています。Unicode 文字列を持たない Delphi 7 を使用していることを忘れないでください。コンポーネントの1つにバグがあると思いますが、古いバージョンを使用しているため、問題は解決されていると思いますが、使用しているバージョンでは解決されていません。
==== できれば最終編集、25/04/12 ====
蚊のアドバイスに従って、デフォルトの文字セットが WIN1252 の新しいデータベースを作成しました (UTF-8 は選択肢として表示されず、とにかく私のプログラムは Unicode ではありません)。このクリーンなデータベースで、'constext' 文字列の文字セットも WIN1252 として定義された 1 つのテーブルを定義しました。問題のあるフォームのデータベース対応バージョンを実行したところ、問題なくテキストを入力できました (現在 1700 文字以上)。
したがって、データベース用に 1 つの文字セットを定義し、フィールド用に 1 つの文字セットを定義することによって、問題が発生したように思われます。データベースのデフォルトの文字セットがどのように定義されているかを振り返って確認する方法がわからないため、これを確認できません。
新しいデータベース (50 以上のテーブルがあります) を定義し、元のデータベースからデータをコピーするという小さな問題があります。このデータベースは顧客の主力製品にサービスを提供するため、これを行うには少し警戒しています....