FireDAC 插入 ORACLE 表时"table or view does not exist" 德尔福贝林 10.1 upd 2



我们正在将代码库从带有FireDAC 8.0.5的Delphi XE3迁移到带有FireDAC 15.0.1的Delphi Berlin 10.1 Upd 2(内部版本86746(。使用MS Sql Server一切都很顺利,但是使用ORACLE已经是另一段历史了。

在整个应用程序源代码中,我们使用大量带有 SQL 指令的 TAdQuery,例如

AdQuery1.Sql.Text := 'SELECT FIELD1, FIELD2 FROM TABLE1';

为了插入记录,我们使用追加或插入方法,如下所示

AdQuery1.Insert;AdQuery1.Append;

在调用其 Post 方法后,组件在内部创建一个 INSERT sql 语句,如下所示

INSERT INTO TABLE1 (FIELD1, FIELD2) VALUES(:FIELD1, :FIELD2)

因此,记录已成功插入。

现在,使用柏林德尔福的TFdQuery,该组件在内部创建一个INSERT sql语句,如下所示

INSERT INTO USERNAME.TABLE1 (FIELD1, FIELD2) VALUES(:FIELD1, :FIELD2)

失败与 [FireDAC][物理][Ora] ORA-00942:表或视图不存在

发生这种情况是因为在我们的 Oracle 数据库中,TABLE1 是在名为 MAIN_SCHEMA 的架构中创建的,我们使用公共同义词访问它。

为了找到解决方法,我们比较了FireDAC源代码,发现

在Delphi XE3中,单元uADDAptManager.pas在其函数TADDAptTableAdapter.GetUpdateRowCommand上调用oConn.CreateCommandGenerator(oCmdGen, nil);

在DelphiBerlin,UnitFireDAC.DApt.pas在其函数TFDDAptTableAdapter.GetUpdateRowCommand上调用oConn.CreateCommandGenerator(oCmdGen, GetSelectCommand);

只要第二个参数(称为 ACommand: IFDPhysCommand(不为nil,就会返回连接用户名的表名(在名为TFDPhysCommandGenerator.GetFrom的函数中(。

如果我们将'MetaCurSchema=MAIN_SCHEMA'添加到 TFdConnection 参数中,它适用于不使用池连接的应用程序,但是我们有几个进程使用具有相同参数的池连接,甚至是 MetaCurSchema 参数,但它不起作用

我们能做什么?

感谢您的帮助

我的理解是,您最好使连接避免使用任何模式名称,而不是指定它。另外,请记住,您已经使用了公共同义词。

因此,根据文档:

完整对象名称

FireDAC 支持完整的对象名称,其中包括目录和/或架构名称。

当将短对象名称指定为 StorageProcName、TableName 等时,它们将使用当前目录和/或架构名称扩展为完整的对象名称。要覆盖或避免使用当前目录和/或模式名称,请使用MetaCurCatalog 和 MetaCurSchema连接定义参数。例如:

[Oracle_Demo]
DriverID=Ora  
...
MetaCurCatalog=*
MetaCurSchema=*

~ 来源: 对象名称 (FireDAC( - docWiki

MetaCurSchema

指定应用程序的当前架构。如果未指定,则将从 DBMS 接收其值。当应用程序请求元数据且未指定架构名称时,FireDAC 将隐式使用当前架构。
如果MetaCurSchema是 '*',那么模式名称将从元数据参数中省略。

~ 来源: Common Connection Parameters (FireDAC( - docWiki

星号(*(应该可以解决问题,如果是这种情况,请告诉我们。

最新更新