pl/sql 必须声明 PLS-00201 标识符
Posted
技术标签:
【中文标题】pl/sql 必须声明 PLS-00201 标识符【英文标题】:pl/sql PLS-00201 identifier must be declared 【发布时间】:2014-02-13 18:16:47 【问题描述】:PL/SQL 新手。我有几个问题,下面是我正在尝试做的一个示例。
CREATE OR REPLACE PROCEDURE "my_procedure" (
"my_inparam1" IN VARCHAR2,
"my_inparam2" IN VARCHAR2,
"my_output" OUT SYS_REFCURSOR)
AS
sql_text VARCHAR2 (10000);
BEGIN
sql_text :=
'select something
from my_table
where 1 = 1';
IF '&my_inparam1' <> 'foo'
THEN
sql_text := sql_text || ' and something = 0';
END IF;
IF '&my_inparam1' = 'foo' and '&my_inparam2' = 'bar'
THEN
sql_text := sql_text || ' and somethingelse = 1';
ELSIF '&my_inparam1' = 'foo' AND '&my_inparam2' = 'baz'
THEN
sql_text := sql_text || ' and somethingelse = 0';
END IF;
OPEN my_output FOR sql_text; --ERROR PLS-00201 Identifier 'MY_OUTPUT' must be declared
END;
所以很明显我正在尝试返回一个查询结果,可以选择通过我传入的任何参数进行过滤。我不知道为什么有问题的行返回错误 - 在早期的迭代中,我能够返回结果,但现在,神秘地,它停止了工作。
1) 有没有更好的方法来解决这个问题?
2) 我是否必须使用 '&my_inparam' 语法来引用输入参数?
3) 如果我确实通过先创建 sql 文本然后打开 ref 游标来解决此问题,是否有连接字符串的快捷方式,例如
sql_text &= ' and another_condition = 1'
?
【问题讨论】:
FWIW - 双引号围绕变量名(或 Oracle 中的任何内容)使该名称为“CaSe SenSiTivE”,Oracle 中的默认大写为 UPPER_CASE,但如果您不使用双引号您可以将其输入为大写字母、大写字母、uPpEr_CaSe 或任何您喜欢的形式,数据库系统会为您将其转换为大写字母。 IMO 遵循的一个很好的规则是:永远,永远,永远不要在 Oracle 中对任何标识符进行双引号。 :-) 分享和享受。 【参考方案1】:以相反的顺序...不,没有像&=
这样的串联简写。您可以改用concat()
函数,但||
方法更常见,也更方便,特别是如果您将两个以上的东西粘在一起 - 嵌套的concat()
调用并不容易遵循。我会坚持你正在做的事情。
其次,不,您将 SQL*Plus 替换变量与 PL/SQL 变量混淆了。您对'&my_inparam1'
的引用应该是my_inparam1
等;没有和号,也没有引号。
除非出于某种原因,您决定让自己过得不愉快并使用区分大小写的过程和变量名称,因此您必须引用"my_inparam1"
,用双引号括起来,无处不在。
这就是您收到消息PLS-00201 Identifier 'MY_OUTPUT' must be declared
的原因。您没有引用my_output
,因此默认情况下它正在寻找一个不存在的名为MY_OUTPUT
的不区分大小写的变量。如果你这样做,它会起作用:
OPEN "my_output" FOR sql_text;
除非你有一个非常好的理由,否则真的不要那样做。
CREATE OR REPLACE PROCEDURE my_procedure (
my_inparam1 IN VARCHAR2,
my_inparam2 IN VARCHAR2,
my_output OUT SYS_REFCURSOR)
AS
sql_text VARCHAR2 (10000);
BEGIN
sql_text :=
'select something
from my_table
where 1 = 1';
IF my_inparam1 <> 'foo'
THEN
sql_text := sql_text || ' and something = 0';
END IF;
...
OPEN my_output FOR sql_text;
END;
更多信息,请参考naming rules:
每个数据库对象都有一个名称。在 SQL 语句中,您表示 带有带引号的标识符或不带引号的对象的名称 标识符。
带引号的标识符以双引号 (") 开头和结尾。 如果您使用带引号的标识符命名架构对象,那么您必须 引用该对象时使用双引号。
不带引号的标识符不被任何标点符号包围。
更重要的是:
注意: Oracle 不建议对数据库对象名称使用带引号的标识符。这些引用的标识符被 SQL*Plus,但在使用其他管理工具时可能无效 数据库对象。
您引用的过程名称属于此类;引用的变量名也是如此。它们都是标识符,适用相同的建议。
【讨论】:
谢谢亚历克斯,是的,我通过实验发现a)输出参数上的双引号修复了我的错误,b)我不需要在输入参数上使用双引号任何一个。我剩下的问题都是简单的语法错误。以上是关于pl/sql 必须声明 PLS-00201 标识符的主要内容,如果未能解决你的问题,请参考以下文章
在 PL/SQL 中出现错误“PLS-00201:必须声明标识符‘JSON_VALUE’”
PL/SQL 函数中的 XmlRoot、XmlElement、InsertChildXml 给出 PLS-00201 必须声明标识符
ORA-06550:第 1 行,第 7 列:PLS-00201:必须声明标识符“PAYMENT_UPDATE” ORA-06550:第 1 行,第 7 列:PL/SQL:语句被忽略