我在使用 Oracle 时遇到了问题。我已经解决了这个问题(我将展示如何解决),但我将不胜感激任何有关故障原因的解释。
背景
我已经声明了要按以下方式执行的程序包。
声明过程的脚本(package_example_spec.sql):
CREATE OR REPLACE PACKAGE package_example AS
PROCEDURE example1;
PROCEDURE example2;
END package_example;
/
执行程序的脚本(package_example_body.sql):
CREATE OR REPLACE PACKAGE BODY package_example IS
PROCEDURE example1 AS
...
END example1;
PROCEDURE example2 AS
...
END example2;
END package_example;
/
执行程序的脚本:
@@package_example_spec.sql
@@package_example_body.sql
BEGIN
example1;
END;
/
BEGIN
example2;
END;
/
问题
一开始一切都很顺利。
然后,大约一天后,我开始注意到有时 Oracle 没有运行过程实现的新编辑,但不知何故,即使旧版本的过程不再存在,它仍在运行旧版本(我注意到它感谢 DBMS_OUTPUT.PUT_LINE 语句)。 换句话说,我正在对脚本进行更改并重新编译,但 Oracle 没有看到我编译的新更改,它看到的是这些过程的旧编译。 尽管如此,Oracle 仍会从这个问题中“自动”恢复,我只需要等待,有时我只是通过断开连接并重新连接到模式来解决它。
但是,几天后,这个问题变得令人恼火:我无能为力,就是让 Oracle 执行我的程序的当前版本,而最后一次(在我解决它之前)“滞后”持续了几个小时。
无效尝试
我所做的相关事情是:
alter system flush shared_pool;
解决方案
我不小心通过开始以不同的方式调用程序来解决了这个问题,我删除了“@@”并这样做了:
BEGIN
package_example.example1;
END;
/
BEGIN
package_example.example2;
END;
/
现在问题不再出现了。
问题
你们有人知道为什么会发生这种情况吗? 有没有办法在保持“@@”执行程序的方式的同时解决问题?
谢谢你。
代码:
BEGIN
example1;
END;
/
BEGIN
example2;
END;
/
不是从包中调用过程;它正在调用与包中的过程同名的独立过程。
如果您想从过程中调用包,那么您需要事先用包名称限定过程名称,以便您DO想要使用:
BEGIN
package_example.example1;
package_example.example2;
END;
/
例如,如果您有代码:
CREATE PROCEDURE example1 IS
BEGIN
DBMS_OUTPUT.PUT_LINE('A');
END;
/
CREATE PACKAGE package_example IS
PROCEDURE example1;
END;
/
CREATE PACKAGE BODY package_example IS
PROCEDURE example1 IS
BEGIN
DBMS_OUTPUT.PUT_LINE('B');
END;
END;
/
然后就可以查询数据字典了:
SELECT object_name, object_type
FROM USER_OBJECTS
WHERE OBJECT_NAME IN ('EXAMPLE1', 'PACKAGE_EXAMPLE');
并看到架构中有 3 个对象:
OBJECT_NAME | 对象类型 |
---|---|
示例1 | 程序 |
包_示例 | 包装 |
包_示例 | 封装体 |
一个独立的过程、包和包体。
使用时:
BEGIN
DBMS_OUTPUT.ENABLE();
example1;
END;
/
那么输出是:
A
这对应于独立程序。
如果您使用:
BEGIN
DBMS_OUTPUT.ENABLE();
package_example.example1;
END;
/
那么输出是:
B
对应打包流程。
如果您不应该有独立的过程(即,如果您最初创建它是为了在包中实现该过程之前测试该过程),那么您可以删除该过程:
DROP PROCEDURE example1;
你应该发现:
BEGIN
DBMS_OUTPUT.ENABLE();
example1;
END;
/
开始引发异常,但使用包标识符的其他代码仍然有效。