PL / SQL函数中的XmlRoot,XmlElement,InsertChildXml必须声明PLS-00201标识符

时间:2014-08-06 10:08:46

标签: sql xml oracle plsql

  

注意:请不要将此标记为类似问题的副本。我只是问这个,因为其他问题没有解决完全相同的问题,他们的答案也没有提供可行的解决方案。

如果我在如下所示的select语句中使用像INSERTCHILDXML这样的XML相关函数,那么它可以正常工作:

SELECT INSERTCHILDXML( ... ) FROM DUAL;

但是如果我尝试在PL / SQL中使用它,如下所示,它会给出错误PLS-00201: identifier 'INSERTCHILDXML' must be declared

CREATE FUNCTION ...
    RETURN XMLType
AS
BEGIN
    RETURN INSERTCHILDXML( ... );
EXCEPTION
    ...
END;

遇到此问题的功能:XMLROOTXMLELEMENTINSERTCHILDXML

在网上搜索有关错误时,有很多结果。其中许多人告诉我有问题的标识符CREATE PUBLIC SYNONYMGRANT EXECUTE但它不起作用。

可以为同一名称创建公共同义词,但授予执行(在任何模式上)失败,并显示:

ORA-01775: looping chain of synonyms

如果我尝试使用不同的同义词名称,在尝试授予执行权时,我会得到:

ORA-00980: synonym translation is no longer valid

如何在新的PL / SQL函数中解决问题并成功使用列出的函数

1 个答案:

答案 0 :(得分:2)

  

在短暂休息(并查看更多类似问题)后,我达成了顿悟。

显然它不起作用的原因是因为我试图RETURN函数输出:

RETURN INSERTCHILDXML( ... );

我应该做的是将输出推送到变量中,然后返回变量:

CREATE FUNCTION ...
    RETURN XMLType
AS
    temp XMLType;
BEGIN
    SELECT INSERTCHILDXML( ... ) INTO temp FROM DUAL;
    RETURN temp;
EXCEPTION
    ...
END;

注意:无需创建同义词或授予执行权限。如果你已经执行过任何操作,可以将其撤消。

其他调查结果:

您无法将功能输出分配给变量。必须使用SELECT INTO推送它。但是,您可以使用XMLType类型及其方法。

temp := XMLType( ... ) -- works fine
temp := XMLELEMENT ( ... ) -- does not work

条件中的用法是片状的。 CASE WHEN容忍它,而IF则不容忍。

CASE WHEN EXISTSNODE( ... ) = 1 THEN -- works fine

IF EXISTSNODE( ... ) = 1 THEN -- does not work

您可以使用变量来解决IF的问题:

SELECT EXISTSNODE( ... ) INTO exists_node FROM DUAL;
IF exist_node = 1 THEN -- works