Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Oracle SQL*Plus中执行函数时行为不一致?_Sql_Oracle_Function_Plsql - Fatal编程技术网

从Oracle SQL*Plus中执行函数时行为不一致?

从Oracle SQL*Plus中执行函数时行为不一致?,sql,oracle,function,plsql,Sql,Oracle,Function,Plsql,我是Oracle和SQL的新手,正在尝试从SQL*Plus中执行一个简单的测试函数。我的函数名为tf(用于测试函数),它在一个名为tf.sql的文件中定义如下 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); retu

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

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中

SQL> start ./tf.sql
SQL> exec SYSTEM.TF('Hello');
作为执行此命令的结果,SQL*Plus仅表示:

Function created.
然后从SQL*Plus命令提示符执行以下命令时(在调用set serveroutput on之后)

我得到以下输出

Argument = Hello
0

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

SQL> start ./tf.sql
SQL> exec SYSTEM.TF('Hello');
然后,我从SQL*Plus获得以下错误消息:

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命令提示符执行以下命令

SQL> select * from user_objects where object_name = 'TF';
然后返回以下结果

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
在此方面的任何帮助都将不胜感激

提前谢谢


Craig

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

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

select tf('asdf') from dual;

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

下面是@jonearles answer,它突出了SQL*Plus中函数和过程的区别,以及@MS Stp的注释,运行它的一种方法是:

variable rc number;
exec :rc := tf('Hello');

Argument = Hello

PL/SQL procedure successfully completed.
要查看返回代码,您可以执行以下操作:

print rc
0
exec
实际上只是一个匿名PL/SQL块的简写,您可以从收到的错误消息中看到这一点<代码>变量允许您在SQL*Plus级别而不是在块中声明绑定变量。您还可以将参数声明为绑定变量,并使用单独的
exec
调用进行设置:

variable rc number;
variable arg varchar2(5);
exec :arg := 'Hello';
exec :rc := tf(:arg);

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

True,或者他也可以在annon PL/SQL块中使用host/bind或local变量来获取返回值+1 Yup,还有另一种方法也可以使用,例如声明rc编号(指定长度或使用%TYPE);arg varchar2(5):=“你好”;开始rc:=tf(arg);DBMS_输出。输出线(rc);结束;或者也可以使用DBMS_OUTPUT.PUT_LINE(tf(arg));在开始标记和结束标记之间。@msstp-我从您先前的评论中认为您的意思是;我认为有必要将其分解成一个单独的答案,因为它本身很有用,而且可以说更通用?