我正在使用 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]。这并不能解决问题。
持久字段是在客户端数据集上定义的。当我在 TSQLDataSet 上定义它们时,不会出现有关“未指定键”的错误消息。该程序仍然会发出此错误消息(我之前忽略了):
EDatabase error: arithmetic exception, numeric overflow or string truncation
大字符串字段在“displaywidth”和“size”中具有正确的值。
==== 更多信息 ====
我重写了表单以使用非数据感知组件。一个查询从数据库中检索数据(使用与我在 TSQLDataSet 中使用的完全相同的查询字符串);然后将数据传输到控件。在用户按下表单上的 OK 按钮后,数据将通过另一个执行更新或插入的查询传递回数据库。由于这可以正常工作,我看不出数据感知组件有什么问题。
==== 又一个信息片段 ====
我在 Stack Overflow 上发现了这个问题,似乎解决了类似的问题。我将查询更改为
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。然后我添加了更多字符(不计算),尝试保存 - 并得到了错误。从这一点开始,尝试再添加一个字符会导致错误消息(出现在 clientdataset 的“applyupdates”方法中)。
最初,该字段包含 832 个字符,因此我可以成功存储的字符数没有硬性限制。但是一旦出现错误信息,它总是出现,好像数据库记得有错误一样。
==== 更多信息,4 月 24 日 ====
再一次,我从数据库中删除了该字段,然后将其添加回来;字符集是 WIN1251,原因我现在还不清楚(我不需要西里尔字符)。无论字段本身是如何定义的,我可以使用数据感知控件输入的最大字符数似乎约为 280。
此后,我开始在发生此问题的实际程序中使用非数据感知控件,并且我可以向您保证,那里不存在此限制。因此,我相当确定问题不是由于字符大小不匹配造成的,正如所建议的那样。不要忘记我使用的是 Delphi 7,它没有 unicode 字符串。我认为其中一个组件存在错误,但由于我使用的是旧版本,我想问题已经解决,但不是在我使用的版本中。
==== 希望最终编辑,25/04/12 ====
按照蚊子的建议,我创建了一个默认字符集为 WIN1252 的新数据库(UTF-8 没有作为选项出现,而且无论如何我的程序不是 unicode)。在这个干净的数据库中,我定义了一个表,其中“constext”字符串的字符集也被定义为 WIN1252。我运行了有问题表单的数据感知版本,并且能够毫无问题地输入文本(目前超过 1700 个字符)。
因此,问题似乎是由为数据库定义一个字符集和为字段定义一个字符集造成的。我不知道如何回顾数据库的默认字符集被定义为什么,所以我无法确认这一点。
我现在有定义一个新数据库(有 50 多个表)并从原始数据库复制数据的小问题。由于这个数据库是为客户的旗舰产品服务的,所以我对这样做有些谨慎......