首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Oracle SQL*Plus中执行函数时的不一致行为?

在Oracle SQL*Plus中执行函数时的不一致行为?
EN

Stack Overflow用户
提问于 2012-02-05 12:45:40
回答 2查看 1K关注 0票数 2

我是Oracle和SQL的新手,正在尝试从SQL*Plus中执行一个简单的测试函数。我的函数名为tf (代表测试函数),它在名为tf.sql的文件中定义如下;

代码语言:javascript
运行
复制
create or replace
function
tf
(
 arg1 in varchar2
)
return number

as

return_value number;

begin

return_value := 0;
dbms_output.put_line('Argument 1 = ' || arg1);
return return_value;

end;
/

我可以使用以下命令成功地将此函数加载到Oracle中;

代码语言:javascript
运行
复制
SQL> start ./tf.sql

作为执行此命令的结果,SQL*Plus简单地声明;

代码语言:javascript
运行
复制
Function created.

当我从SQL*Plus命令提示符执行以下命令时(在我调用set serveroutput on之后);

代码语言:javascript
运行
复制
SQL> exec dbms_output.put_line(SYSTEM.TF('Hello'));

我得到了以下输出;

代码语言:javascript
运行
复制
Argument = Hello
0

PL/SQL procedure successfully completed.

现在,如果我尝试直接从SQL*Plus命令提示符执行我的函数,使用以下命令;

代码语言:javascript
运行
复制
SQL> exec SYSTEM.TF('Hello');

然后,我从SQL*Plus得到以下错误消息;

代码语言:javascript
运行
复制
BEGIN SYSTEM.TF('Hello'); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00221: 'TF' is not a procedure or is undefined
ORA-06550: ;ine 1, column 7
PL/SQL: Statement ignored

有没有人能给我解释一下?我不明白为什么我的函数在第一种情况下似乎执行成功,但在第二种情况下却不能。

如果我从SQL*Plus命令提示符执行以下命令;

代码语言:javascript
运行
复制
SQL> select * from user_objects where object_name = 'TF';

然后我会得到以下返回的结果;

代码语言:javascript
运行
复制
OBJECT_NAME
-----------
TF
SUBOBJECT_NAME
--------------
OBJECT_ID
---------
74475
DATA_OBJECT_ID
--------------
OBJECT_TYPE
-----------
FUNCTION
CREATED
-------
05-FEB-12
LAST_DDL_
---------
05-FEB-12
TIMESTAMP
---------
2012-02-05:02:11:15
STATUS
------
VALID
T
-
N
G
-
N
S
-
N
EDITION_NAME
------------
1

在这方面的任何帮助都将非常感谢。

提前谢谢。

克雷格

EN

回答 2

Stack Overflow用户

发布于 2012-02-05 13:02:30

exec不能处理函数,因为它不知道如何处理返回值。这类似于常规的PL/SQL语句;如果调用函数,则必须将返回值赋给某个对象。

如果要使用SQL*Plus中的函数,则应改用SQL:

代码语言:javascript
运行
复制
select tf('asdf') from dual;

此外,您永远不应该在系统中创建对象。这可能会导致一些非常奇怪的问题。

票数 6
EN

Stack Overflow用户

发布于 2012-02-05 17:54:06

在@jonearles answer和@MS Stp的评论中,从SQL*Plus的角度强调了函数和过程之间的区别,运行它的一种方法是:

代码语言:javascript
运行
复制
variable rc number;
exec :rc := tf('Hello');

Argument = Hello

PL/SQL procedure successfully completed.

要查看返回代码,您可以执行以下操作:

代码语言:javascript
运行
复制
print rc
0

正如您从收到的错误消息中看到的那样,exec实际上只是匿名PL/SQL块的缩写。variable允许您在SQL级别声明绑定变量,而不是在块中声明。您还可以将参数声明为绑定变量,并使用单独的exec调用对其进行设置:

代码语言:javascript
运行
复制
variable rc number;
variable arg varchar2(5);
exec :arg := 'Hello';
exec :rc := tf(:arg);

我经常使用这种结构来测试现有的过程调用,例如从Pro*C代码复制的东西,而不必将调用中的变量替换为固定值。它可以使使用不同参数重复调用变得更容易,并且您可以在多次调用中重用变量-因此您可以稍后将:rc传递给另一个函数。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9146981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档