【问题标题】:DataSnap and the autoinc fieldDataSnap 和 autoinc 字段
【发布时间】:2014-10-04 21:21:26
【问题描述】:

我希望我的表具有 autoinc 字段,但使用 ClientDataSet 对其进行插入会导致“字段必须具有值”错误。似乎 Datasnap 服务器不知道它应该自己生成一个并期望一个值。 对于演示,我创建了一个只有 2 个字段的简单表:ID (autoinc) 和 DATE (varchar)。 数据库是 SQLite。

procedure TForm3.Button1Click(Sender: TObject);
begin
ClientDataSet1.Insert;
ClientDataSet1.FieldByName('DATE').Value:= DateUtils.DateOf(PlannerCalendar1.Date);
ClientDataSet1.Post;
ClientDataSet1.ApplyUpdates(0);
if ClientDataSet1.ApplyUpdates(0) = 0 then
ClientDataSet1.Refresh;

为了处理 autoinc 问题,我使用了 Bobs 博士的建议:

procedure TForm3.ClientDataSet1NewRecord(DataSet: TDataSet);
const {$J+}
ID: Integer = -1;
begin
DataSet.FieldByName('ID').AsInteger := ID;
DEC(ID) ;
end;

虽然 autoinc 计数正在倒退,但我可以忍受。但 ... 记录会添加到网格中,但不会添加到数据库中!?

那么有人可以告诉我如何处理这个 autoinc 噩梦吗?看到了一些关于使用数据集的 onreconcile 事件的建议,但手动纠正错误不适合我。我尝试为 ID 字段插入一个零值,希望 datasnap 服务器能够纠正错误,但它所做的只是让我弹出协调对话框,以便我可以纠正问题。救命!

结束;

【问题讨论】:

  • 我发现从服务器检索要生成的 ID 以便在帖子中提供最简单的方法。例如 see 代表火鸟。
  • 原来的article,我相信你有这个想法。如果我没记错的话,我也想不出来。还有see.
  • 有趣的是,如果我删除 autoinc 字段,一切都会正常运行。当我尝试删除一个值时出现问题。我可以在网格中删除,但不能在数据库中删除。

标签: delphi datasnap delphi-xe6


【解决方案1】:

您没有说您使用哪种数据集将 DataSetProvider 连接到 Sqlite 数据库。我想这不是 FireDac 数据集,因为它们正确处理 Sqlite 表中的 autoinc 列。

所以假设你使用的是其他类型,我想你可能忽略了

Errata 部分的重要性

http://edn.embarcadero.com/article/20847

在 cmets 中提到的文章,其中说:

“对于不将其自动增量字段映射到 TAutoIncField 的 DBMS,您需要删除源数据集上的 TField.ProviderFlags.pfInUpdate 标志,以允许 DataSnap 将记录解析回数据库。您真的在做通过这样做,DataSnap 会自动为 TAutoIncFields 做同样的事情。"

这适用于 Sqlite。除此之外,如果您的源数据集字段不是持久字段,您需要在运行时检查源数据集的列类型(我的意思是,为您的 DataSetProvider 提供的列类型)。

对于 Sqlite,源数据集字段类型应该是 ftLargeInt,而不是 ftAutoInc,因为 Sqlite 数据库中的 autoinc 列大小是 64 位,而不是 32 位(这是 ftAutoinc 假设的)。避免此问题的最简单方法是在源数据集上创建持久 TField,并确保在访问 Sqlite 数据库的 DBX 表和 ClientDataSet 中,ID 列一是 ftLargeInt 类型。

顺便说一句#2,您不需要 Button1Click 中的 2 个 ApplyUpdates,但除此之外,您的代码看起来还不错。

【讨论】:

  • 告诉你发生了什么......按照建议做了一切......但是,当我从 -1 到 -5 序列中删除一条记录(例如'-3')时,一切都崩溃了松散......计数变得疯狂......新记录插入了相同的自动编号......因此应用更新开始失败......总而言之 - 没用。
  • 两件事:首先,我更新了我的答案以删除 ID 列可能是 DBX 和 CDS 数据集中不同数据类型的建议。我不确定我从哪里得到这个想法,因为如果 CDS 的 ID 列类型与 DBX 数据集不匹配,CDS 就会引发异常。其次,我想我可能知道为什么您在删除记录时会发现“一切都乱了套”。如果您从 Sqlite 数据库中的表完全为空并添加 3 行开始,可能它们的 ID 在您的 GUI 中显示为 -1、-2 和 -3。但是它们在 db 中的 ID 值是多少?
  • 好吧,这么想。我想我知道如何解决它,但坦率地说,我认为你最好发布一个新的 q,因为它与这个 q 不在同一点上,这基本上是如何将自动记录的记录保存到数据库中,并且需要比此处的评论更长的答案。可能类似于“我正在关注 EMB 文章,使用 DBX 和 ftLargeInt ID 字段,因为这是 Sqlite 所需要的,但是我的记录仍然使用它们的临时负 ID 号保存到数据库中,如果我尝试删除其中一个新记录的序列,我得到了混乱”
猜你喜欢
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多