如何在线重命名内部表(将表test_table重命名为test_table_new)到包内部表(pkg_test)时不解包(pkg_test)。 除此之外,还有一个Web服务会不断查询该程序包,并在使用时将其阻止。
解决方案之一是使用命令“ alter package pkg_test compile”,但问题是Web服务已经采用了该软件包(pkg_test),并且不允许执行该操作。
答案 0 :(得分:0)
嗯,我能想到的正确方法是:不要那样做。如果重命名了程序包使用的表,则该程序包将无效,并且必须先解决错误,然后才能使用它。
为什么要重命名表?它有什么好处?
如果可能,将使用TEST_TABLE的代码移动到动态SQL中。这样做,程序包不会失效,但是您仍将无法使用引用重命名表的代码。这是一个示例:
创建示例表和包(没什么花样):
SQL> create table test (datum date);
Table created.
SQL> insert into test values (sysdate);
1 row created.
SQL> create or replace package pkg_test as
2 function f_right_now return date;
3 function f_max_datum return date;
4 end;
5 /
Package created.
SQL> create or replace package body pkg_test as
2 function f_right_now return date is
3 begin
4 return sysdate;
5 end;
6
7 function f_max_datum return date is
8 retval date;
9 begin
10 select max(datum)
11 into retval
12 from test;
13 return retval;
14 end;
15 end;
16 /
Package body created.
SQL>
让我们看看它是否有效:
SQL> select pkg_test.f_right_now, pkg_test.f_max_datum from dual;
F_RIGHT_NO F_MAX_DATU
---------- ----------
2018-10-01 2018-10-01
SQL> select object_type, status from user_objects where object_name = 'PKG_TEST';
OBJECT_TYPE STATUS
------------------- -------
PACKAGE VALID
PACKAGE BODY VALID
到目前为止,太好了。现在,重命名表并再次检查包状态:
SQL> rename test to test_new;
Table renamed.
SQL> select object_type, status from user_objects where object_name = 'PKG_TEST';
OBJECT_TYPE STATUS
------------------- -------
PACKAGE VALID
PACKAGE BODY INVALID
SQL> select pkg_test.f_right_now, pkg_test.f_max_datum from dual;
select pkg_test.f_right_now, pkg_test.f_max_datum from dual
*
ERROR at line 1:
ORA-04063: package body "SCOTT.PKG_TEST" has errors
SQL>
按预期-程序包主体现在无效,您不能使用它。因此,让我们切换到动态SQL:
SQL> create or replace package body pkg_test as
2 function f_right_now return date is
3 begin
4 return sysdate;
5 end;
6
7 function f_max_datum return date is
8 retval date;
9 begin
10 execute immediate 'select max(datum) from test' into retval;
11 return retval;
12 end;
13 end;
14 /
Package body created.
SQL>
看到了吗?尽管表TEST不再存在,Oracle也不抱怨。包裹状态为有效:
SQL> select object_type, status from user_objects where object_name = 'PKG_TEST';
OBJECT_TYPE STATUS
------------------- -------
PACKAGE VALID
PACKAGE BODY VALID
但是您不能使用“无效”功能(而“正确”功能仍然有效):
SQL> select pkg_test.f_right_now, pkg_test.f_max_datum from dual;
select pkg_test.f_right_now, pkg_test.f_max_datum from dual
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at "SCOTT.PKG_TEST", line 10
SQL> select pkg_test.f_right_now from dual;
F_RIGHT_NO
----------
2018-10-01
SQL>
SQL> select pkg_test.f_right_now, pkg_test.f_max_datum from dual;
select pkg_test.f_right_now, pkg_test.f_max_datum from dual
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at "SCOTT.PKG_TEST", line 10
SQL>
再重命名?当然可以,为什么不呢?
SQL> rename test_new to test_littlefoot;
Table renamed.
SQL> select object_type, status from user_objects where object_name = 'PKG_TEST';
OBJECT_TYPE STATUS
------------------- -------
PACKAGE VALID
PACKAGE BODY VALID
SQL> select pkg_test.f_right_now from dual;
F_RIGHT_NO
----------
2018-10-01
SQL> select pkg_test.f_max_datum from dual;
select pkg_test.f_max_datum from dual
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at "SCOTT.PKG_TEST", line 10
因此,请参见动态SQL为您工作。我认为(再次)-不要“仅因为”重命名表,您应该有充分的理由这样做。
答案 1 :(得分:0)
感谢您的帮助
由于使用重命名的速度快,因此Web服务可以在线查询该表,所以我要做的是首先加载一个临时表(dws.temp),然后将该临时表重命名为原始表。 Web服务使用的表(dws .finally)。
另一种方法是直接加载到原始表(dws.finally),但是根据情况,这可能会延迟,并且要求表(dws.finally)的更新以秒为单位。重新命名后,我在一秒钟内更新了表
注意:Web服务通过包消耗了原始表(dws.finally),因此当我重命名(dws.temp到dws.finally)时,它将被反编译并且Web服务显示错误。
也可以尝试使用动态SQL,但是开发成本更高