ear*_*efl 2 oracle plsql stored-procedures syntax-error
新手到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;
Run Code Online (Sandbox Code Playgroud)
所以很明显我正在尝试返回一个查询结果,可选地通过我传入的任何参数进行过滤.我对于为什么违规行返回错误感到茫然 - 在之前的迭代中,我能够返回结果,但是现在,神秘地,它停止了工作.
1)有更好的方法来解决这个问题吗?
2)我是否必须使用'&my_inparam'语法引用输入参数?
3)如果我通过首先创建sql文本然后打开引用光标来接近这个,是否有用于连接字符串的快捷方式,如
sql_text &= ' and another_condition = 1'
Run Code Online (Sandbox Code Playgroud)
?
以相反的顺序...不,没有连接的简写&=
.您可以使用该concat()
函数,但该||
方法更常见,更方便,特别是如果您将两个以上的东西放在一起 - 嵌套concat()
调用并不容易理解.我坚持你正在做的事情.
其次,不,您将SQL*Plus替换变量与PL/SQL变量混淆.你的引用'&my_inparam1'
应该是my_inparam1
等等; 没有&符号,也没有引号.
除了一些原因,你已经决定要难为自己和使用情况,sentisive程序和变量名,所以你不得不提到"my_inparam1"
,在双引号,随处可见.
这就是你收到消息的原因PLS-00201 Identifier 'MY_OUTPUT' must be declared
.您没有引用,my_output
所以默认情况下它正在寻找一个MY_OUTPUT
不存在的不区分大小写的变量.如果你这样做,它会工作:
OPEN "my_output" FOR sql_text;
Run Code Online (Sandbox Code Playgroud)
除非你有一个非常好的理由,否则真的不这样做.
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;
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅命名规则:
每个数据库对象都有一个名称.在SQL语句中,您表示具有带引号的标识符或非带引号的标识符的对象的名称.
带引号的标识符以双引号(")开头和结尾.如果使用带引号的标识符命名模式对象,则每次引用该对象时都必须使用双引号.
未加引号的标识符不包含任何标点符号.
更重要的是:
注意:
Oracle建议不要对数据库对象名称使用带引号的标识符.SQL*Plus接受这些带引号的标识符,但在使用管理数据库对象的其他工具时它们可能无效.
您引用的程序名称属于此类别; 所引用的变量名称也是如此.它们都是标识符,并且适用相同的建议.