问题:
Oracle Package 在修改后没有生效......现象:
创建测试包create or replace package PACK_TEST is
       v_global   varchar2(1000):='nnnnnnn';
       
       procedure get_values (v_values out varchar2);
       procedure set_values (v_values11 in varchar2);
       procedure set_values (v_values11 in number);end PACK_TEST;
/create or replace package body PACK_TEST is
  procedure get_values (
    v_values out varchar2
    )
    as
    
    begin
      v_values:=v_global;
    
    end;
  
  procedure set_values (
    v_values11 in varchar2
    )
    as
    
    begin
      v_global:=v_values11;
    exception
      when others then
        dbms_output.put_line(sqlcode||':'||sqlerrm);
    end;
    
    procedure set_values (
    v_values11 in number
    )
    as
    
    begin
      v_global:=v_values11;
    exception
      when others then
        dbms_output.put_line(sqlcode||':'||sqlerrm);
    end;
end PACK_TEST;
/创建测试调用过程:CREATE OR REPLACE PROCEDURE "PROC_ICE" (
       v_A  IN VARCHAR2,
       v_B  IN NUMBER,
       v_E  IN date,
       v_C  OUT NUMBER,
       v_D  OUT VARCHAR2
)
AS
BEGIN
       v_c:=0;
       pack_test.set_values('kkkkkkkk');
       pack_test.get_values(v_d);
       
exception
when others then
null;
END;
/在PL/SQL Developer中调用PROC_ICE会打印出v_C=0; v_D=kkkkkkkk; 但修改包后,任意修改,
比如修改 v_global   varchar2(1000):='uuuuu';
在PLSQL中(不要重新连接,使用前面已经连接上的SESSION),再次调用PROC_ICE会打印出v_C=0; v_D=; v_D是没有值的,说明过程调用包没有生效,重新连接后是正常的.在应用中用VC做ODBC连接也是同样的问题, 连接后调用是正常的,但修改包后出现的问题同PL/SQL Developer; 
先前以为是ODBC的问题, 所以改用OCI驱动连接, 结果是一样的问题.但在用SQLPLUS测试的时候是没有问题的,修改包后是立即生效, 打印正常.个人检查:
包是在第一次调用时将整个包放入内存,我也检查过SHARED_POOL,查看过v$db_object_cache; 使用过dbms_shared_pool包将包重新放入内存,但在PL/SQL Developer和VC中的结果是相同的,问题没有解决.请教高手这个问题是什么原因??

解决方案 »

  1.   

    这个应该是缓冲池中的缓冲机制有问题。
    理论上,重新编译package后,package的时间戳会被改变。
    已经编译到内存缓冲区中的数据的时间戳由于小于新编译的包的时间戳,内存中的package会失效。
    再次调用的时候会重新到磁盘上读取package的内容。看楼主的意思是vc和plsql的执行,没有重新编译包,这会不会是这两个工具的设置有问题。
      

  2.   

    sorry,
    刚明白楼主是怎么编译的--你疑似只对package进行了编译是吧。
    select * from dba_objects dp
    where dp.object_name = 'PACK_TEST'
    执行你所谓的修改后,使用上面的脚本检查一下,你会发现你的package body是invalid的要同时编译package和package body,你的设置自然会生效。
      

  3.   

    --对在sqlplus是马上的刷新的,我觉得还是刷新机制的问题
    SQL> create or replace package PACK_TEST is
      2    v_global varchar2(1000):='nnnnnnn';
      3      
      4    procedure get_values (v_values out varchar2);
      5    procedure set_values (v_values11 in varchar2);
      6    procedure set_values (v_values11 in number);
      7  
      8  end PACK_TEST;
      9  /程序包已创建。SQL> create or replace package body PACK_TEST is
      2    procedure get_values (
      3    v_values out varchar2
      4    )
      5    as
      6      
      7    begin
      8    v_values:=v_global;
      9      
     10    end;
     11     
     12    procedure set_values (
     13    v_values11 in varchar2
     14    )
     15    as
     16      
     17    begin
     18    v_global:=v_values11;
     19    exception
     20    when others then
     21    dbms_output.put_line(sqlcode||':'||sqlerrm);
     22    end;
     23      
     24    procedure set_values (
     25    v_values11 in number
     26    )
     27    as
     28      
     29    begin
     30    v_global:=v_values11;
     31    exception
     32    when others then
     33    dbms_output.put_line(sqlcode||':'||sqlerrm);
     34    end;
     35  end PACK_TEST;
     36  /程序包体已创建。
    SQL> declare
      2  v_c varchar2(100);
      3  v_d varchar2(100);
      4  begin
      5  v_c:='wkc';
      6  pack_test.set_values(v_c);
      7  pack_test.get_values(v_d);
      8  dbms_output.put_line(v_d);
      9  end;
     10  /PL/SQL 过程已成功完成。SQL> set serveroutput on
    SQL> /
    wkcSQL> ed
    已写入 file afiedt.buf  1  create or replace package PACK_TEST is
      2    v_global varchar2(1000):='uuuu';
      3    procedure get_values (v_values out varchar2);
      4    procedure set_values (v_values11 in varchar2);
      5    procedure set_values (v_values11 in number);
      6* end PACK_TEST;
      7  /程序包已创建。SQL> 
    SQL> declare
      2  v_c varchar2(100);
      3  v_d varchar2(100);
      4  begin
      5  pack_test.get_values(v_d);
      6  dbms_output.put_line(v_d);
      7  end;
      8  /
    uuuuPL/SQL 过程已成功完成。
      

  4.   

    2楼的朋友,你的视图我是看过的,也试过重新编译,但是问题相同,必须对SESSION重新连接后才可以生效;
    有没有方法可以让SESSION不重新连接也可以生效;单独的过程和函数都是可以的,但是包不行;
    请回复的朋友测试好方案后再回复.