No'*_*man 6 delphi firebird dbexpress delphi-7
我正在使用dbExpress组件(Delphi 7)开发数据库程序.通过以下组件从数据库中检索数据:TSQLDataSet - > TDataSetProvider - > TClientDataSet - > TDatasource - > TDBEdit.到目前为止,表格已正常运作.TSQLDataset中的查询是
select id, name, byteken, timeflag from scales where id = :p1
Run Code Online (Sandbox Code Playgroud)
我在数据库表中添加了一个大的(2048)varchar字段; 当我将此字段添加到上面的查询(并将TDBMemo或TDBRichEdit连接到TDatasource)时,当我尝试编辑新文本字段中的值时,我收到以下消息
Unable to find record. No key specified.
Run Code Online (Sandbox Code Playgroud)
当表单上没有TDBMemo时(但在查询中使用varchar字段),我得到相同的错误.一旦从查询中删除varchar字段,一切都可以正常工作.
可能是造成这个问题的原因是什么?
====更多信息====
我现在已经在表单中定义了持久字段.保存表的键的字段的提供者标志设置为[pfInUpdate,pfInWhere,pfInKey],而所有其他字段的标志为[pfInUpdate,pfInWhere].这并没有解决问题.
持久字段在clientdataset上定义.当我在TSQLDataSet上定义它们时,不会出现关于"未指定密钥"的错误消息.程序仍然会显示此错误消息(我之前忽略了这一点):
EDatabase error: arithmetic exception, numeric overflow or string truncation
Run Code Online (Sandbox Code Playgroud)
大字符串字段在'displaywidth'和'size'中具有正确的值.
====更多信息====
我重写了表单以使用非数据感知组件.一个查询从数据库中检索数据(使用与我在TSQLDataSet中使用的查询字符串完全相同的查询字符串); 然后将数据传输到控件.在用户按下表单上的"确定"按钮后,数据将通过执行更新或插入的另一个查询传递回数据库.由于这可以正常工作,我不知道数据感知组件的问题是什么.
====又一段信息====
我在Stack Overflow上发现了这个问题,似乎解决了类似的问题.我将查询更改为
select id, name, name, byteken, timeflag,
cast (constext as varchar (2048)) as fconstext
from scales
where id = :p1
Run Code Online (Sandbox Code Playgroud)
并将dbMemo的数据字段设置为'fconstext'.将文本添加到dbMemo后,'applyupdates'调用现在失败,并显示以下消息
column unknown 'fconstext'
Run Code Online (Sandbox Code Playgroud)
尽管存在使用该名称创建的持久字段.
我不知道这是否有助于或简单地混淆水.
====更多信息,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多个表)并从原始数据库复制数据.由于这个数据库服务于客户的旗舰产品,我有点担心这样做....
无法找到记录。未指定密钥。
\n\n设置从比例中选择 id、名称、byteken、timeflag,其中 id = :p1
\n\n到
\n\n从 id = 245 的比例中选择 id、name、byteken、timeflag
\n\n设计时现有的 id。
\n\n强制转换\ncast(上下文为 varchar (2048)).....\n如果更改列的定义,则对该列类型的现有 CAST 可能会变得无效
\n\n算术异常、数字溢出或字符串截断
\n\n字符串截断\n当连接的字符串不适合基础 CHAR 或 VARCHAR 数据类型大小时,就会发生这种情况。如果结果进入表列,则可能是有效错误。或者也许您确实需要增加列大小。存储过程或触发器变量中存储的中间值也类似。
字符音译失败\n当数据库中的数据以一种字符集存储,但音译为所需字符集失败时,就会发生这种情况。字符集音译发生在多个点。有一个自动的:\n从数据库检索的每条数据(通过 SELECT 或其他方式)都会从数据库表列的字符集音译为连接字符集。如果字符集差异太大,则会有两种转换:首先从列字符集到 Unicode,然后从 Unicode 到连接字符集。\n此外,您可以通过将列强制转换为另一个字符集来手动请求音译,例如:\nCAST(column_name AS varchar(100) 字符集 WIN1251)。\n音译可能失败的原因是某些字符集中不存在某些字符。例如,WIN1252 不包含任何西里尔字符,因此如果您使用连接字符集 WIN1252 并尝试从包含西里尔字符的列中进行 SELECT,则可能会收到此类错误。\n在现代,最好使用 Unicode 或 UTF8在您的应用程序中和 UTF8 连接字符。并确保您至少使用Firebird 2.0,具有 UTF8 支持。
使用 DotNetFirebird 时参数顺序错误\n使用 DotNetFirebird 时将参数添加到 FbCommand 的顺序可能会导致 -303 异常,并提示“算术异常、数字溢出或字符串截断”。参数的顺序必须符合存储过程中参数的顺序 - 否则将引发异常。示例(.NET、C#、DotNetFirebird(使用 FirebirdSql.Data.FirebirdClient;))
\n\nFbCommand CMD = new FbCommand("TBLTEXT_ADDTEXT", cnn);\nCMD.Parameters.Add("TEXT1", FbDbType.VarChar, 600).Value = strText1;\nCMD.Parameters.Add("TEXT2", FbDbType.VarChar, 600).Value = strText2;\nCMD.CommandType = CommandType.StoredProcedure;\nCMD.ExecuteNonQuery();\n如果过程“TBLTEXT_ADDTEXT”中参数的顺序与您\xc2\xb4添加参数的顺序不同FbCommand-Object,您\xc2\xb4将收到-303错误。
4.
\n\n\n\n\n纽曼说不是,但是一旦出现错误消息,它就会一直出现,就好像数据库记得有一个错误一样。
\n
没有人记得;数据库损坏!!!
\n\n只要您无法更改数据库字符集并且总是尝试在损坏的表中删除和添加字段,就很难解决问题。1. 对于每个新测试,都必须创建一个新数据库(提示:创建一个数据库并将其复制 x 次)。2. 字段设置为纯文本,而不是原始字段中存储的西里尔字符;你看不到它们,但它们就在那里。3.设置varchar(8191)和数据库PAGE_SIZE为8192。UTF8的实际最大VARCHAR长度为8191
\n\n创建数据库语句:
\n\nCREATE DATABASE localhost:mybase\n USER SYSDBA\n PASSWORD masterkey\n PAGE_SIZE 8192\n DEFAULT CHARACTER SET UTF8;\n SET NAMES ISO8859_1;\n\nCREATE TABLE scales (\n ID ..., \n byteken VARCHAR(8191) COLLATE DE_DE,\n ....\nRun Code Online (Sandbox Code Playgroud)\n\n校对
\n\n没有默认排序规则。因此,您应该为用于排序 (ORDER BY) 或比较 (UPPER) 的每个字段定义一个排序规则:
\n\n您还可以使用 ORDER BY 子句指定排序规则:
\n\nORDER BY LASTNAME COLLATE FR_CA, FIRSTNAME COLLATE FR_CA\nRun Code Online (Sandbox Code Playgroud)\n\n或使用 WHERE 子句:
\n\nWHERE LASTNAME COLLATE FR_CA = :lastnametosearch\nRun Code Online (Sandbox Code Playgroud)\n\n统一码
\n\n火鸟2.0。以上。现在有了新的 UTF8 字符集,可以正确处理 UTF-8 格式的 Unicode 字符串。Unicode 排序规则算法已实现,因此现在您可以使用 UPPER() 和新的 LOWER() 函数,而无需指定排序规则。
\n