调用封装成过程,Oracle PL/SQL
Posted
技术标签:
【中文标题】调用封装成过程,Oracle PL/SQL【英文标题】:Call package into a procedure, Oracle PL/SQL 【发布时间】:2016-03-07 13:18:15 【问题描述】:我正在尝试找出我们应该在 Oracle 的 11g PL/SQL 中解决的这个家庭作业,但是我和我的四个朋友都没有找到解决这个问题的方法,我们希望有人更有才华比我们会给我们一些关于它的指示和/或cmets。
让我们从有问题的作业开始(它分为两部分,这是我们无法弄清楚的最后一部分):
首先,创建一个使用 DBMS_UTILITY.GET_TIME 获取当前时间的过程,然后执行复杂的计算。最后,说明获得结果/得到答案需要多长时间(以秒为单位)。
我们通过创建一个计算素数的 for 循环很好地解决了这个问题(计算从 1 到 5000 的每个素数大约需要 5 秒),但是,最后一部分是这样说的:
现在,创建一个包含此复杂计算的包,然后重新编写您的过程,以便调用该计算的“包方法”。您的程序现在将只测量开始时间,调用包含计算的包,并显示获得结果/到达答案所花费的时间(以秒为单位)。
因此,回顾一下:该过程将测量包进行计算所需的时间。这就是我们陷入困境的地方。网上关于这方面的信息不多,但我的代码如下所示:
SET SERVEROUTPUT ON
CREATE OR REPLACE PROCEDURE time_measure_procedure
AS
time_start NUMBER;
time_end NUMBER;
time_diff NUMBER;
BEGIN
time_start := dbms_utility.get_time;
--This is where I'd presumably call in the
--package into the procedure, whereas the time
--will be measured until the calculation is done.
heavy_calculation_package;
time_end := dbms_utility.get_time;
time_diff := ( time_end - time_start ) / 100;
dbms_output.Put_line('Time it took: ' || time_diff || ' seconds.');
END time_measure_procedure;
/
CREATE OR REPLACE PACKAGE BODY heavy_calculation_package
AS
PROCEDURE time_measure_procedure
IS
x NUMBER;
counter NUMBER;
BEGIN
--This is the prime number calculation, which
--we're supposed to call into the procedure.
FOR n IN 1 .. 5000 LOOP
counter := 0;
x := Floor(n / 2);
FOR i IN 2 .. x LOOP
IF ( MOD(n, i) = 0 ) THEN
counter := 1;
END IF;
END LOOP;
IF ( counter = 0 ) THEN
dbms_output.Put_line(n ||' is a prime number.');
END IF;
END LOOP;
END time_measure_procedure;
END heavy_calculation_package;
/
我收到的错误通常是:
对象 package_heavy_calc 无效 没有规范就无法编译 package_heavy_calc 的主体
有没有人知道为什么这不起作用?任何提示或指针都会很可爱!
【问题讨论】:
除了需要包规范外,您在独立过程中的调用还需要是heavy_calculation_package. time_measure_procedure
。您不直接调用包,而是调用其中的函数或过程,必须在规范中声明。
【参考方案1】:
在调用之前,您需要使包处于有效状态。在这种情况下,您需要先像这样声明包:
CREATE OR REPLACE PACKAGE package_heavy_calc
AS
PROCEDURE heavy_calc;
END PACKAGE_HEAVY_CALC;
你可以有一个没有主体的包,但不能有一个没有包的主体。您可以通过将代码放在包头中来做到这一点。为您的目的声明包和包体,要容易得多。
顺便说一下,命名对于可读性好的代码至关重要。我会把你的包命名为 PKG_MATH 和过程 P_CALC_PRIME_NUMBERS,所以当你调用它时,你就会知道它的作用。然而,命名就像运动队一样,每个人都有自己喜欢的球队,而且风格可能完全不同。
【讨论】:
但是如果body是空的,包怎么计算呢?哦,对命名错误感到抱歉,我已经将它们从瑞典语翻译成英语,所以它可能把我的头搞砸了,哈哈:) @tobulos1 - 你已经有了身体,你只需要规范就可以了。 “you can have a package without a body...”部分是关于how packages work的一般性陈述;这并不是说在这种情况下您不需要身体。 哦,我明白你的意思了!谢谢!【参考方案2】:请添加包装规格,然后尝试。下面是一个sn-p 会帮助你的。
CREATE OR REPLACE PACKAGE package_heavy_calculation
AS
PROCEDURE heavy_calc;
END package_heavy_calculation;
CREATE OR REPLACE PACKAGE BODY package_heavy_calculation
AS
PROCEDURE heavy_calc
IS
x NUMBER;
counter NUMBER;
BEGIN
--This is the prime number calculation, which
--we're supposed to call into the procedure.
FOR n IN 1 .. 5000
LOOP
counter := 0;
x := Floor(n / 2);
FOR i IN 2 .. x
LOOP
IF ( MOD(n, i) = 0 ) THEN
counter := 1;
END IF;
END LOOP;
IF ( counter = 0 ) THEN
dbms_output.Put_line(n ||' is a prime number.');
END IF;
END LOOP;
END heavy_calc;
END package_heavy_calculation;
【讨论】:
嗯,我还是不能让它工作。我得到“未声明的标识符”或其他一些错误。 立即尝试。它在我的工作区中编译并且工作正常。以上是关于调用封装成过程,Oracle PL/SQL的主要内容,如果未能解决你的问题,请参考以下文章
ORACLE PL/SQL:以最大执行时间调用外部 Oracle PL/SQL 过程
使用带有布尔输入参数的 PL/SQL 在 oracle 中调用 java 存储过程
带有输入参数的 Oracle JDBC 调用 PL/SQL 过程记录表