在Oracle中跨数据库链接调用返回用户定义类型数组的存储函数

4
通常,我这样调用我的函数:
SELECT * 
FROM TABLE(
  package_name.function(parameters)
)

我正在尝试通过数据库链接调用此函数。我的直觉告诉我以下是正确的语法,但我还没有使其工作:

SELECT * 
FROM TABLE(
  package_name.function@DBLINK(parameters)
)

> ORA-00904: "PACKAGE_NAME"."FUNCTION": invalid identifier

我已经尝试了多次移动数据库链接,但没有效果。我尝试将其放在参数列表后面、最后一个括号后面、包名后面...我还尝试了所有上述排列方式,包括在包名之前加模式名称。我已经没有更多的想法了。
这是 Oracle 10g。我怀疑问题可能是在调用它的模式中未定义函数的返回类型,但如果是这种情况,我感觉应该会得到不同的错误。
谢谢你的帮助!
1个回答

4

据我所知,你尝试的语法是正确的,但无论如何它都不会起作用,因为返回类型是用户定义的,正如你所怀疑的那样。

这里有一个使用内置管道函数的示例。当然,在本地调用它是可以工作的:

SELECT * FROM TABLE(dbms_xplan.display_cursor('a',1,'ALL'));

返回:

SQL_ID: a, child number: 1 cannot be found 

通过数据库链接进行调用:

SELECT * FROM TABLE(dbms_xplan.display_cursor@core('a',1,'ALL'));

出现以下错误:

ORA-30626: function/procedure parameters of remote object types are not supported

可能出现ORA-904的原因是链接到一个特定模式,该模式没有访问该包的权限。但无论如何,即使您在本地模式中定义了具有相同名称的相同类型,这也不起作用,因为从Oracle的角度来看它们仍然不是相同的类型。
当然,您可以远程查询视图,因此如果存在明确定义的可能参数集,则可以为每个参数组合创建一个视图,然后查询该视图,例如:
CREATE VIEW display_cursor_a_1_all AS
  SELECT * FROM TABLE(dbms_xplan.display_cursor('a',1,'ALL'))
  ;

如果可能的参数值范围太大,您可以创建一个过程,根据任何一组参数动态创建所需的视图。然后,每次执行查询时,您需要进行两步操作:
EXECUTE  package.create_view@remote(parameters)

SELECT * FROM created_view@remote;

接下来,您需要考虑是否会有多个会话并行调用此函数,如果是,则需要防止它们相互干扰。


好的,我确认在第二个模式中创建UDT也没有帮助(相同的错误)。你有任何建议的解决方法吗? - David Marx
我目前最好的想法是使用视图来包装远程数据库中的函数。请参见编辑后的答案。 - Dave Costa
也许更好的想法是在远程创建一个单一的全局临时表,调用一个远程函数将请求的行加载到该表中,然后查询它。 - Dave Costa
我想到的最好的解决方法就是你上面提到的评论,但是重新构建视图对我来说比截断和重新填充表格更有吸引力。无论如何,我会接受你提出的解决方案。谢谢! - David Marx
没问题。只是提醒一下,全局临时表不需要被截断 - 它会自动为每个使用它的事务(或会话,取决于如何创建)保留一个单独的行集。 - Dave Costa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接