Oracle 如何从pl/sql匿名块调用pl/sql匿名块

Oracle 如何从pl/sql匿名块调用pl/sql匿名块,oracle,plsql,Oracle,Plsql,我有下面的PL/SQL块,它工作正常。我想从另一个PL/SQL块调用这个函数(TimeToFrame) 我不能在DB中存储的过程或包中声明此函数。换句话说,在pl/sql都是匿名块的情况下,如何从另一个pl/sql调用pl/sql 如果我把这个函数放在一个单独的.sql文件中呢。我不能从我的匿名块调用该.sql文件,并将一些参数传递给它,然后让fct返回参数吗 Declare nTime Number; FUNCTION TimeToFrame(pTime IN Varchar2) retur

我有下面的PL/SQL块,它工作正常。我想从另一个PL/SQL块调用这个函数(TimeToFrame)

我不能在DB中存储的过程或包中声明此函数。换句话说,在pl/sql都是匿名块的情况下,如何从另一个pl/sql调用pl/sql

如果我把这个函数放在一个单独的.sql文件中呢。我不能从我的匿名块调用该.sql文件,并将一些参数传递给它,然后让fct返回参数吗

Declare
nTime Number;

FUNCTION TimeToFrame(pTime IN Varchar2)
return NUMBER IS
nTime NUMBER;
BEGIN
select (SUBSTR(pTime, 1, 2) * 108000)+(SUBSTR(pTime, 4, 2) * 1800)+(SUBSTR(pTime, 7, 2)     * 30)+SUBSTR(pTime, 10, 2)
 into nTime
 from dual;
 return nTime;
END TimeToFrame;

Begin
nTime:=TimeToFrame('47:59:59:29');
DBMS_OUTPUT.PUT_LINE(nTime);
End;

关键是如果您有一个PL/SQL匿名块,您就无法识别和调用它,因为它是匿名的。您必须编译此存储过程,然后从两个PL/SQL块调用它。关键是,如果您有一个PL/SQL匿名块,您无法识别和调用它,因为它是匿名的。您必须编译这个存储过程,然后从PL/SQL块调用它。不幸的是,没有办法实现这一点。匿名块中声明的嵌套子程序在处理匿名块后甚至不会持久化,因此即使忽略范围限制,在处理另一个匿名块时它也不存在


如果因为邪恶的DBA不允许而无法将其作为存储函数,则必须复制粘贴该函数。

不幸的是,无法实现这一点。匿名块中声明的嵌套子程序在处理匿名块后甚至不会持久化,因此即使忽略范围限制,在处理另一个匿名块时它也不存在


如果因为邪恶的DBA不允许而无法将其设置为存储函数,则必须复制粘贴该函数。

根据您的评论和问题编辑,如果匿名块以SQL*Plus脚本运行,则可以按照您的建议执行,并将该函数保存在其自己的文件中。如果您创建了一个名为TimeToFrame.sql的文件,并使用以下函数:

FUNCTION TimeToFrame(pTime IN Varchar2)
return NUMBER IS
  nTime NUMBER;
BEGIN
  select (SUBSTR(pTime, 1, 2) * 108000)+(SUBSTR(pTime, 4, 2) * 1800)
    +(SUBSTR(pTime, 7, 2)     * 30)+SUBSTR(pTime, 10, 2)
  into nTime
  from dual;
  return nTime;
END TimeToFrame;
然后,通过SQL*Plus或其他脚本,您可以执行以下操作:

Declare
  nTime Number;
  @TimeToFrame
Begin
  nTime:=TimeToFrame('47:59:59:29');
  DBMS_OUTPUT.PUT_LINE(nTime);
End;
/

5183999
PL/SQL procedure successfully completed.
当然,包含函数的文件必须位于SQL*Plus可以看到它的地方。还要注意的是,文件的内容在包含外部文件时被合并到匿名块中,因此如果您执行
列表
,那么您将看到整个内容,而不是对
@
的原始引用。正如AmmoQ所说,匿名块在数据库中执行;这是关于在将块发送到要执行的数据库之前在客户机中创建块


当然,最好还是将函数创建为存储的子程序或包。

根据您的评论和问题编辑,如果匿名块以SQL*Plus脚本运行,那么您可以按照建议执行,并将函数保存在自己的文件中。如果您创建了一个名为TimeToFrame.sql的文件,并使用以下函数:

FUNCTION TimeToFrame(pTime IN Varchar2)
return NUMBER IS
  nTime NUMBER;
BEGIN
  select (SUBSTR(pTime, 1, 2) * 108000)+(SUBSTR(pTime, 4, 2) * 1800)
    +(SUBSTR(pTime, 7, 2)     * 30)+SUBSTR(pTime, 10, 2)
  into nTime
  from dual;
  return nTime;
END TimeToFrame;
然后,通过SQL*Plus或其他脚本,您可以执行以下操作:

Declare
  nTime Number;
  @TimeToFrame
Begin
  nTime:=TimeToFrame('47:59:59:29');
  DBMS_OUTPUT.PUT_LINE(nTime);
End;
/

5183999
PL/SQL procedure successfully completed.
当然,包含函数的文件必须位于SQL*Plus可以看到它的地方。还要注意的是,文件的内容在包含外部文件时被合并到匿名块中,因此如果您执行
列表
,那么您将看到整个内容,而不是对
@
的原始引用。正如AmmoQ所说,匿名块在数据库中执行;这是关于在将块发送到要执行的数据库之前在客户机中创建块


当然,将函数创建为存储的子程序或包会更好。

如果我将该函数放在单独的.sql文件中。我不能从我的匿名块调用该.sql文件,并将其传入一些参数,然后让fct返回参数吗?否。匿名块在数据库中执行,很可能无法访问该文件(即使有,也没有加载和执行该文件的简单方法)。如果我将该函数放在单独的.sql文件中。我不能从匿名块调用该.sql文件,并将其传入一些参数,然后让fct返回参数吗?否。匿名块在数据库中执行,很可能无法访问该文件(即使有,也没有简单的加载和执行方法)。:可重用性。不允许子程序(命名块)似乎是一个奇怪的限制:可重用性。不允许使用子程序(命名块)似乎是一个奇怪的限制。