我正在将Delphi 5 / BDE应用程序转换为Delphi XE7 / FireDAC。我的一个表单有一个TFDTable
组件,指向在其create语句中包含group by
子句的Oracle视图。
这曾经在BDE应用程序中正常工作,但是使用FireDAC我收到了这个错误。
ORA-01446:无法从DISTINCT中选择ROWID或对其进行采样, GROUP BY等
我理解我从Oracle获得的错误,但我没有选择ROWID
,FireDAC就是! TFDTable
中是否有可以设置的属性,以防止它将ROWID
添加到查询中?如果没有,我该如何使用这个观点?
答案 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