(PLSQL) Oracle 正在运行已执行过程的旧版本

问题描述 投票:0回答:1

我在使用 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;
  • 终止所有正在运行的 Oracle 进程(我是通过任务管理器完成的)并重新启动系统
  • 虽然我正在使用 SQL Plus,但我还在 sqldeveloper 上测试了相同的脚本。我还手动更改并重新编译了左侧菜单上正确的包主体选项内的过程(在 sqldeveloper 内)。
  • 尝试断开并重新连接模式并重新启动应用程序,甚至多次(SQL Plus 和 sqldeveloper)

解决方案

我不小心通过开始以不同的方式调用程序来解决了这个问题,我删除了“@@”并这样做了:

BEGIN
    package_example.example1;
END;
/
BEGIN
    package_example.example2;
END;
/

现在问题不再出现了。

问题

你们有人知道为什么会发生这种情况吗? 有没有办法在保持“@@”执行程序的方式的同时解决问题?

谢谢你。

oracle plsql oracle-sqldeveloper sqlplus plsql-package
1个回答
0
投票

代码:

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;
/

开始引发异常,但使用包标识符的其他代码仍然有效。

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.