我最近从代码中得到了一个非常奇怪的例外:
XXX.WrappedSqlException: ORA-00604: error occurred at recursive SQL level 1
ORA-00942: table or view does not exist
while executing create table ST_UTEST2_DATE (value varchar(100) not null unique,replacement varchar(100) not null)
at XXX
Caused by: java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-00942: table or view does not exist
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1037)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3685)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1088)
... 8 more
该表确实不存在(在此次发布之前和之后)。当我想执行“create table”时通常就是这种情况。我不知道在创建表格时如何才能获得“表或视图不存在”。
此异常只被抛出一次。具有完全相同的环境(db状态)的相同代码执行很多次。有多个线程执行此代码(检查此表是否存在,如果它不存在,则创建它),每个线程都有自己的连接。但是检查和创建发生的片段是同步的 - 表的执行当然不会同时从多个线程发生,并且检查和创建是原子的。
任何可能产生这种异常的想法(包括疯狂的猜测)都是受欢迎的。
数据库是Oracle 10g。
答案 0 :(得分:2)
如果数据字典已损坏,则这种情况很常见。再阅读here(不完全在创建表上,但这可能是同一个问题。尝试在那里提供的解决方案)。您可能必须执行catqueue.sql脚本。在数据字典上运行任何脚本之前,您应该备份数据库。请参阅相同的讨论here
答案 1 :(得分:0)
我的猜测是模式级别的触发器,它试图执行某种审计操作并失败。
一种可能的情况:
用于复制此语句的SQL语句(假设用户test1已存在且具有DBA权限):
-- create the log table
CREATE TABLE ddl_log as
SELECT ora_sysevent,
ora_dict_obj_owner,
ora_dict_obj_name,
USER as ddl_user,
SYSDATE as ddl_date
FROM DUAL
WHERE 1=0;
-- create the logging package
CREATE OR REPLACE PACKAGE pck_log_ddl AUTHID CURRENT_USER is
PROCEDURE log_ddl;
END pck_log_ddl;
/
create or replace package body pck_log_ddl is
procedure log_ddl is
begin
INSERT INTO ddl_log
SELECT ora_sysevent,
ora_dict_obj_owner,
ora_dict_obj_name,
USER,
SYSDATE
FROM DUAL;
end;
end pck_log_ddl;
-- create the second user
create user test2 identified by test2;
grant connect, resource, create table, create trigger to test2;
grant execute on pck_log_ddl to test2;
connect test2@mydb
-- create the schema-level trigger
CREATE OR REPLACE TRIGGER bcs_trigger
BEFORE CREATE
ON SCHEMA
BEGIN
test1.pkg_log_ddl.log_ddl;
END bcs_trigger;
-- try creating a table => ORA-00604 / ORA-00942
create table ST_UTEST2_DATE (
value varchar(100) not null unique,
replacement varchar(100) not null
);