我在SYS下有一个存储过程,它使用EXECUTE IMMEDIATE
命令来执行alter object compile
。但我收到以下错误。
CREATE OR REPLACE PROCEDURE comp_inv
is
CURSOR empCursor IS
SELECT object_type,
owner,object_name
from dba_objects
where status = 'INVALID'
and object_type in ('PACKAGE','FUNCTION','PROCEDURE');
BEGIN
FOR i_rec IN empCursor LOOP
execute immediate 'alter ' ||i_rec.object_type|| ' ' ||
i_rec.owner || '.' || i_rec.object_name || ' compile';
END LOOP;
END;
/
SQL> exec comp_inv; ERROR: ORA-24344: success with compilation error ORA-06512: at "SYS.COMP_INV", line 8 ORA-06512: at line 1 Warning: PL/SQL compilation errors. SQL> show errors procedure comp_inv; No errors.
答案 0 :(得分:3)
您可以使用标准Oracle包DBMS_UTILITY
及其过程COMPILE_SCHEMA()
,它为您提供了重新编译无效对象的标准方法。值得使用它有很多原因,特别是它允许你保持编译设置。
答案 1 :(得分:3)
在您的情况下,错误只是意味着某些架构对象由于某种原因无法重新编译 - 过程成功执行,但您尝试重新编译的某些对象无法重新编译。例如:
create table t1(col1 number);
create or replace procedure p2(p_in in number) is
l_res number;
begin
select count(1)
into l_res
from t1;
end;
确定那里是否存在“无效”:
column object_type format a10;
column object_name format a10;
column status fromat a10;
select object_type
, object_name
, status
from dba_objects
where status = 'INVALID'
and object_type in ('PACKAGE','FUNCTION','PROCEDURE');
no rows selected
无效P2
程序:
alter table t1 add (col2 number);
column object_type format a10;
column object_name format a10;
column status fromat a10;
select object_type
, object_name
, status
from dba_objects
where status = 'INVALID'
and object_type in ('PACKAGE','FUNCTION','PROCEDURE');
OBJECT_TYP OBJECT_NAM STATUS
---------- ---------- -------
PROCEDURE P2 INVALID
重新编译:
exec comp_inv
anonymous block completed
重新编译成功:
column object_type format a10;
column object_name format a10;
column status fromat a10;
select object_type
, object_name
, status
from dba_objects
where status = 'INVALID'
and object_type in ('PACKAGE','FUNCTION','PROCEDURE');
no rows selected
使我们的P2
程序无效,因此无法编译:
create or replace procedure p2(p_in in number) is
l_res number;
begin
invalid_operator;
end;
/
PROCEDURE P2 compiled
Errors: check compiler log
检查无效对象:
column object_type format a10;
column object_name format a10;
column status fromat a10;
select object_type
, object_name
, status
from dba_objects
where status = 'INVALID'
and object_type in ('PACKAGE','FUNCTION','PROCEDURE');
OBJECT_TYP OBJECT_NAM STATUS
---------- ---------- -------
PROCEDURE P2 INVALID
尝试重新编译该过程:
exec comp_inv
ORA-24344: success with compilation error
ORA-06512: at "SYS.COMP_INV", line 11
ORA-06512: at line 1
24344. 00000 - "success with compilation error"
正如@OracleUser已经说过的那样,检查一个*_errors
数据字典视图,看看其中是否有内容。它将为您提供消除威胁所需的信息。
column owner format a10;
column name format a10;
column type format a10;
column text format a60;
select owner
, name
, type
, text
from dba_errors
OWNER NAME TYPE TEXT
------ ---------- ------------------------------------------------------------
NK P2 PROCEDURE PLS-00201: identifier
'INVALID_OPERATOR' must be declared
NK P2 PROCEDURE PL/SQL: Statement ignored
其次,正如@Frank Schmitt在他对你的问题的评论中所指出的那样,永远不会在SYS
模式中创建任何类型的用户对象。如果您需要在某处存储某些管理存储过程或其他对象,请为其授予不同的用户权限,并为其授予适当的权限和角色,或者作为最后的手段使用SYSTEM
(也不建议使用)架构。
答案 2 :(得分:2)
CREATE OR REPLACE PROCEDURE comp_inv
is
CURSOR empCursor IS
SELECT object_type,
owner,object_name
from dba_objects
where status = 'INVALID'
and object_type in ('PACKAGE','FUNCTION','PROCEDURE');
BEGIN
FOR i_rec IN empCursor LOOP
BEGIN
execute immediate 'alter ' ||i_rec.object_type|| ' ' ||
i_rec.owner || '.' || i_rec.object_name || ' compile';
EXCEPTION
WHEN OTHERS THEN
FOR I IN (select * from DBA_ERRORS where NAME = i_rec.object_name and owner = i_rec.owner AND type = i_rec.object_type)
LOOP
DBMS_OUPT.PUT_LINE(I.line || ' ' || I.text);
END LOOP;
END;
END LOOP;
END;
/
答案 3 :(得分:0)
这可能就是你所需要的。
exec dbms_utility.compile_schema('SCOTT');
当然你需要适当的权利才能执行