的dbExpress /指定关键(dbExpress/No key specified)

2019-06-23 14:07发布

我工作的一个数据库程序,使用dbExpress组件(德尔福7)。 >的TDataSetProvider - - >的TClientdataSet - >的TDataSource - > TDBEdit将TSQLDataSet:将数据从所述数据库通过以下组分检索。 到现在为止,窗体上有工作正常。 在将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”和“大小”正确的值。

====甚至更多的信息====

我重写使用非数据感知组件的形式。 一个查询从数据库中检索数据(使用完全一样,我使用的将TSQLDataSet相同的查询字符串); 然后将数据传送到控制。 用户按下的形式上的OK按钮后,将数据通过另一个查询执行的更新或插入传递回数据库。 作为这一工作正常,我没有看到的问题是与数据感知组件是什么。

====信息的另一个片段====

我发现这个问题上堆栈溢出,这似乎解决类似的问题。 我改变了查询是

select id, name, name, byteken, timeflag, 
cast (constext as varchar (2048)) as fconstext
from scales
where id = :p1

并设置数据库备注的数据字段是“fconstext”。 添加文本到数据库备注后,“的ApplyUpdates”呼叫现在失败,出现以下消息

column unknown 'fconstext'

尽管没有与该名称创建一个持久字段。

我不知道这是否有助于或干脆muddies水。

====更多信息,4月23日====

我从数据库表中删除字段,然后加了回去。 作为编写程序工作正常,只要被输入到问题的数据字段中的字符串小于约260个字符。 我加了十个字符一次了几次都没有问题,直到字符串的长度是256。然后,我增加了一些更多的字符(不计),试图挽救 - 并得到了错误。 从这个角度上,试图以添加一个或多个字符会导致该错误消息(来自于“的ApplyUpdates” ClientDataSet的方法)。

原来,该领域包含832个字符,所以没有一个硬性限制,我可以成功地存储的字符数。 但是,一旦出现错误信息,它总是出现,就像该数据库还记得,有一个错误。

====更多信息,4月24日====

再一次,我从数据库中删除字段加入回来; 字符集是WIN1251,是在不很清楚,我现在(我不需要西里尔字母)的原因。 我可以进入使用数据感知控件的最大字符数似乎是约280,不管如何领域本身的定义。

因为我已经搬到了在出现此问题的真正的程序中使用非数据感知控件 ,我可以向你保证,这个限制不存在那里。 因此我相当肯定,问题是不是由于字符大小不匹配,因为已建议。 不要忘了,我是用Delphi 7,不具有Unicode字符串。 我认为有在组件的一个错误,但我使用的是旧版本,我想,这个问题已经解决了,但不是在我使用的版本。

====希望最终编辑25/04/12 ====

继蚊子的建议下,我创建了一个新的数据库,其默认字符集是WIN1252(UTF-8没有出现一个选择,反正我的计划是不是Unicode)。 在此洁净数据库中,我定义的一个表,其中“constext”字符串的字符集也被定义为WIN1252。 我跑的问题形式的数据感知版本,并能没有问题(目前超过1700个字符)输入文字。

这似乎,因此,这个问题是由具有对数据库和一个用于现场定义的一个字符集创建。 我不知道该怎么回想起来有什么设置数据库的默认字符被定义为检查,所以我无法证实这一点。

我现在有定义一个新的数据库的小问题(有50+表),并从原始数据库复制数据。 由于该数据库服务于客户的主打产品,我有些警惕这样的....

Answer 1:

无法找到记录。 无键指定。

设置选择ID,姓名,byteken,timeflag鳞片其中id =:P1

选择ID,名称,byteken,鳞片timeflag其中id = 245

在设计一个现有ID。


到蒙上投(constext为varchar(2048))......如果列的定义被改变,现有的强制转换成该列的类型可能会变得无效

算术异常,数值溢出或字符串截断

  1. 字符串截断它发生在连接字符串不符合基本CHAR或VARCHAR数据类型的大小。 如果结果进入一个表列,也许这是一个有效的错误。 或者,也许你真的需要增加列的大小。 类似云存储在存储过程或触发器中介变量的值

  2. 汉字音译失败发生这种情况时,你有存储在一个字符集数据库中的数据,但音译所需的字符集失败。 在有些情况下字符集音译发生的不同点。 有一个自动的一个:你从数据库中检索每一块数据(通过选择或以其他方式)从字符集数据库的列音译,以连接字符集 。 如果字符集是太不一样了,会有两种译法:首先从列字符集为Unicode,然后从Unicode到连接字符集。 CAST(列为varchar(100)字符集WIN1251):此外,还可以通过柱浇铸到另一个字符集,例如手动请求音译。 该音译会失败的原因是,只是一些字符不特定的字符集存在。 例如,WIN1252不包含任何西里尔文字符,所以如果你使用连接字符集WIN1252,并尝试从西里尔字符列以选择,你可能会得到这样的错误。 在近代,最好是使用Unicode或UTF8在您的应用程序和UTF8连接字符。 并确保您使用至少火鸟2.0,具有支持UTF8。

  3. 参数错误的顺序使用DotNetFirebird其参数是用DotNetFirebird可能导致-303异常,并暗示“算术异常,数值溢出或字符串截断”当添加到FbCommand订单 。 参数的顺序必须适应在存储过程中则params的顺序 - 否则将引发异常。 实施例(.NET,C#,DotNetFirebird(使用FirebirdSql.Data.FirebirdClient;))

    FbCommand CMD =新FbCommand( “TBLTEXT_ADDTEXT”,CNN); CMD.Parameters.Add( “TEXT1”,FbDbType.VarChar,600)。价值= strText1; CMD.Parameters.Add( “TEXT2”,FbDbType.VarChar,600)。价值= strText2; CMD.CommandType = CommandType.StoredProcedure; CMD.ExecuteNonQuery(); 如果过程“TBLTEXT_ADDTEXT”内的参数的顺序从顺序不同,其中加入you're参数到FbCommand-对象,you'll收到-303错误。

4。

No'am纽曼说,但一旦出现错误信息,它总是出现,就像该数据库还记得,有一个错误。

不记得; 数据库损坏!


只要你无法改变你的数据库的字符集,并始终以删除和添加字段到一个被破坏的表进行试验,这是很难解决的问题。 1.对于每一个新的考验,必须有一个新的数据库中创建(提示:创建一个,并将它们复制X次)。 2.字段中设置与纯文本不与存储在原本字段西里尔字符 ; 你不能看到他们,但他们的存在。 3.集VARCHAR(8191)和数据库PAGE_SIZE到8192,实际的最大长度VARCHAR与UTF8是8191

CREATE DATABASE语句:

CREATE DATABASE localhost:mybase
  USER SYSDBA
  PASSWORD masterkey
  PAGE_SIZE 8192
  DEFAULT CHARACTER SET UTF8;
  SET NAMES ISO8859_1;

CREATE TABLE scales (
  ID ...,      
  byteken VARCHAR(8191) COLLATE DE_DE,
  ....

排序规则

没有默认排序规则。 所以,你应该定义每个字段是用于排序(ORDER BY)或比较(上部)排序规则:

您也可以指定与ORDER BY子句中的排序规则:

ORDER BY LASTNAME COLLATE FR_CA, FIRSTNAME COLLATE FR_CA

或与WHERE子句:

WHERE LASTNAME COLLATE FR_CA = :lastnametosearch

统一

火鸟2.0。 以上。 现在有一个能够正确处理Unicode字符串UTF8格式的新UTF8字符集。 Unicode归类算法已经被实现,现在你可以使用UPPER()和新的较低()函数,而无需指定归类。



Answer 2:

检查UpdateMode提供者的财产。 如果它被设置为upWhereChangedupWhereKeyOnly你需要在数据库表中的关键字才能正常工作。



文章来源: dbExpress/No key specified