Delphi XE7 TFDTable查看RowID错误

时间:2015-06-13 12:18:25

标签: oracle delphi delphi-xe7 firedac

我正在将Delphi 5 / BDE应用程序转换为Delphi XE7 / FireDAC。我的一个表单有一个TFDTable组件,指向在其create语句中包含group by子句的Oracle视图。

这曾经在BDE应用程序中正常工作,但是使用FireDAC我收到了这个错误。

  

ORA-01446:无法从DISTINCT中选择ROWID或对其进行采样,   GROUP BY等

我理解我从Oracle获得的错误,但我没有选择ROWID,FireDAC就是! TFDTable中是否有可以设置的属性,以防止它将ROWID添加到查询中?如果没有,我该如何使用这个观点?

2 个答案:

答案 0 :(得分:2)

FireDAC提取ROWID,因为它尝试识别结果集中的元组以获取可能的更新。为了停止,只需启用ReadOnly选项,这将正确地使分组视图结果集成为只读(正确的是,如果它们在结果集中被分组以进行更新,则不能仅识别特定元组)。

如果您想知道此问题的根源,则在 TFDPhysCommandGenerator.GenerateSelectTable 方法中生成SQL命令。根据{{​​3}}属性设置(对于Oracle DBMS为ReadOnly),在选择列表中附加了通用唯一元组标识符。

答案 1 :(得分:0)

fiMeta中加入FetchOptions.Items

  

TFDQuery,TFDTable,TFDMemTable和TFDCommand自动检索   主要的唯一标识列(mkPrimaryKeyFields)   (第一个)SELECT ... FROM ...语句中的表,当fiMeta时   包含在FetchOptions.Items中的。注意:

     

mkPrimaryKeyFields查询可能很耗时;       当FireDAC无法正确确定它们时,应用程序可能需要显式指定唯一标识列。

     

要明确指定列,请从FetchOptions.Items中排除fiMeta,   并使用以下选项之一:

     

将UpdateOptions.KeyFields设置为';'分隔的列名列表;       将pfInKey包含到相应的TField.ProviderFlags属性中。

     

当应用程序创建持久字段时,最初   TField.ProviderFlags将正确设置。之后,自动   数据库结构或查询时,不会发生字段设置   改变。您应该手动更新ProviderFlags以调整列   名单。此外,如果主键由多个字段组成,那么所有字段   它们必须包含在持久字段中。行标识列

     

或者,可以在行中包含行标识列   选择列表。当FireDAC找到这样的列时,它将无法检索   mkPrimaryKeyFields元数据,它将使用此列。支持   DBMS如下:

     

DBMS行标识列

     

Firebird DB_KEY

     

Informix ROWID

     

Interbase DB_KEY / RDB $ DB_KEY

     

Oracle ROWID

     

PostgreSQL OID。必须使用OID创建表。

     

SQLite ROWID

来源:http://docwiki.embarcadero.com/RADStudio/XE8/en/Unique_Identifying_Fields_%28FireDAC%29