我有以下PL / SQL块,它工作正常。 我想从另一个PL / SQL块中调用此函数(TimeToFrame)。
我无法在数据库中存储的过程或程序包中声明此函数。 换句话说,如何在另一个pl / sql都是匿名块的另一个pl / sql中调用pl / sql?
如果我将该功能放在单独的.sql文件中怎么办。 我不能从我的匿名块中调用该.sql文件并将其传递给某些IN参数,并使该fct返回OUT参数吗?
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;
使用子程序的原因:可重用性。 不允许子程序(命名块)似乎是一个奇怪的限制。
不幸的是,没有办法实现这一目标。处理匿名块后,在匿名块中声明的嵌套子程序甚至都不会保留,因此即使我们忽略范围限制,在处理另一个匿名块时也不存在。
如果由于邪恶的DBA不允许将其存储为函数,则必须复制粘贴该函数。
如果我将该功能放在单独的.sql文件中。 不能我从我的匿名块中调用该.sql文件,并将其传递给一些IN参数,并使该fct返回OUT参数吗?
否。匿名块是在数据库中执行的,很可能无法访问文件(即使有访问权限,也没有简单的方法来加载和执行文件)。
在注释和问题编辑之后,如果您的匿名块以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可以看到的位置。另请注意,由于包含了外部文件,因此文件的内容已合并到匿名块中,因此,如果执行list,则将看到整个内容-而不是对@的原始引用。正如AmmoQ所说,匿名块是在数据库中执行的。这是关于在将其发送到数据库执行之前在客户端中创建该块。
当然,将功能创建为存储的子程序或在程序包中仍然要好得多。
关键是,如果您有PL / SQL匿名块,则无法识别和调用它,因为它是匿名的。您必须先编译此存储过程,然后从两个PL / SQL块中调用它