【问题标题】:How to retrieve information from a field that has the property Required set as false?如何从属性Required设置为false的字段中检索信息?
【发布时间】:2012-01-27 18:46:41
【问题描述】:

我的软件中有以下 DBX 结构:

TSQLDataSet -> TDataSetProvider -> TClientDataSet

我的 TClientDataSet 中的一个字段将Required 属性设置为 false,因为该字段会根据数据库 (Firebird) 上的触发器和生成器自动递增。

但是,在配置了不需要此字段的 TSQLDataSet 和 TClientDataSet 之后,当我尝试从 TClientDataSet 中读取此字段时,我得到了非常奇怪的结果。我怀疑我可能需要做一些额外的事情来强制我的 TClientDataSet 在这种情况下获取该字段的值。

我在这里错过了什么?

提前致谢。

编辑

Required 属性的帮助文件对此有所说明,但我不太明白它要我做什么。

说明

指定字段的非空值是否为 必需的。

使用必填项来确定一个字段是否需要一个值或者该字段是否需要一个值 可以为空。

如果使用字段编辑器创建字段,则设置此属性 基于基础表。将Required设置为true的应用程序 对于必须具有值的字段(例如,密码或部分 编号),但基础表不需要 字段,必须编写一个 OnValidate 事件处理程序来强制执行该属性。

当Required属性反映底层证券的属性时 数据库表,尝试发布应用空值会导致异常 待提高。将 Required 属性设置为 true 的应用程序 基础表不需要该字段,应该提出一个 OnValidate 事件中的空值出现 EDatabaseError 异常 处理程序以达到相同的结果。

编辑 2

忘了说:在 TDataSetProvider 和 TClientDataSet 之间,有一个 DataSnap 层(TClientDataSet 连接是通过 DataSnap 驱动建立的)。

编辑 3

我用这个 DataSnap 设置创建了一个小测试用例,它运行良好。该项目是遗留的,混乱的,我想要么我在某个地方配置了一个模糊的选项,这让我很痛苦,要么我偶然发现了一个 DataSnap 错误。

【问题讨论】:

  • 您是如何尝试从 ClientDataSet 中读取该字段的?从字段读取时,是否需要字段应该没有区别;它仅影响在插入或编辑操作中将数据写入表/数据集的时间。
  • cds.FieldByName('FIELD').AsString; // 问题只发生在Required:=false 字段上。
  • 什么是奇怪的结果?你有一个递增的字符串字段?
  • 你还是不清楚。正如马库斯所说,奇怪的结果是什么? Reading 字段与Required 属性无关,您引用的文档部分完全是关于写入数据的(最后一段明确表示“尝试发布”,并且前面的段落提到当底层数据库不需要时,有一个OnValidate 事件来在 ClientDataSet 上强制执行所需的属性,这又与 writing 到字段有关)。
  • @KenWhite 假设我的表有两个字段:INDEX(整数)和 NAME(varchar)。如果我当前的活动记录指向具有 (3, John) 作为其值的行,则尝试使用之前引用的过程读取它会给我 (1953366016, John)。但它适用于第一条记录(如果是 (1, Mary),我会得到 (1, Mary))。

标签: delphi firebird datasnap tclientdataset


【解决方案1】:

好乐,TClientDataset.RefreshRecord插入后有没有试过?甚至 TClientDataset.Refresh? 有了生成器,你甚至可以在select gen_id(generator,1) from RDB$Database 之类的查询中提前(在调用ApplyUpdates 之前)获取生成器(它来自内存,这里没有Firebird 来测试)并提前填写PK 字段。

编辑:似乎这是一个 heisenbug。我会尝试删除组件并重新配置它们从头开始(这意味着:删除后,保存并关闭 Delphi)。

或者更好的是,创建一个仅包含所需查询配置的空项目,并尝试在 TDBGrid 中查看该数据。如果这个问题仍然存在,可能是你的 FB 安装有一些组件损坏(甚至是 Delphi 安装)

【讨论】:

  • 嗯,现在不涉及插入。我有一些数据已经在数据库中,我无法使用我的 TClientDataSet 正确读取此字段。
  • TClientDataset.Refresh 没有解决它。由于我的应用程序是线程化的,因此获取这样的生成器值是危险的。
  • 嗯。 IBExpert 甚至 ISQL 上的简单 SELECT 显示正确的数据?
  • 您是否更改了 TClientDataset 和 TSQLDataset 上的 TField.Required?
  • 我的机器上没有 Firebird,只有笔记本电脑上。我会尝试重现这一点。如果您允许我们了解相关表格的相关结构,将会有所帮助。
【解决方案2】:

似乎问题是一个过时的字段被读取为 INTEGER,它是数据库中的一个 SMALLINT。

这个问题很难调试,而且这个问题具有误导性。感谢所有帮助我调试此问题的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多