我们正在将代码库从带有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
星号(*(应该可以解决问题,如果是这种情况,请告诉我们。