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

Posted

技术标签:

【中文标题】PL/SQL 函数中的 XmlRoot、XmlElement、InsertChildXml 给出 PLS-00201 必须声明标识符【英文标题】:XmlRoot, XmlElement, InsertChildXml in PL/SQL function gives PLS-00201 identifier must be declared 【发布时间】:2014-08-06 10:08:45 【问题描述】:

注意:请不要将此标记为类似问题的重复。我之所以问这个只是因为其他问题没有解决完全相同的情况,而且他们的答案也没有提供有效的解决方案。

如果我在如下的 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】:

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

显然它不起作用的原因是因为我试图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

【讨论】:

以上是关于PL/SQL 函数中的 XmlRoot、XmlElement、InsertChildXml 给出 PLS-00201 必须声明标识符的主要内容,如果未能解决你的问题,请参考以下文章

vsize 函数不能与 PL/SQL 中的修剪函数一起使用

如何通过 PL/SQL 中的 VARRAY 函数中的变量传递字符串值

如何在 pl/sql 函数中的变量中存储多行?

过程中的 Pl/Sql Oracle 函数

pl/sql 中的 Next_Day 函数

具有布尔返回值的 pl/sql 函数的 OracleType?