【问题标题】:Can we find which table is causing ORA-00942 table or view does not exist.:我们能否找到导致 ORA-00942 表或视图不存在的表:
【发布时间】:2019-09-21 01:28:38
【问题描述】:

我有一个带有 CTAS 查询的普通 PLSQL 块。

BEGIN
EXECUTE IMMEDIATE'
CREATE TABLE ZZZ_TEMP NOLOGGING PARALLEL AS
SELECT /*+ PARALLEL(a,4) */
        *
    FROM
        HI0XXX001.HI_TABLE_NAME a
    LEFT JOIN
        HR_001_GROUP B
    ON
        a.EMPLOYERGROUP_UD =B.ACC_NUM
    LEFT JOIN
        HR_002_GROUP l
    ON
        a.EMPLOYERGROUP_UD =l.EMPLOYERGROUP_UD
    AND
        a.GRP_CON_UD_COV_CONTRACT_NAME=l.GRP_CON_UD_COV_CONTRACT_NAME
    ';
EXCEPTION WHEN OTHERS THEN Dbms_Output.put_line(SQLERRM);
END;

假设 HR_002_GROUP 表在我运行此块的架构中不存在。有什么方法可以显示 HR_002_GROUP 表不存在的错误消息?

我发布的查询只是一个示例场景。我们在 ETL 结构中工作,我们有一大行查询脚本,将数百万个数据从许多 HI 表中的一个插入到另一个带有前缀 VH 的小表中。我在左连接中有大约 15-30 个表。选择每个左连接以了解哪个表实际导致错误非常耗时。

【问题讨论】:

  • 试试DBMS_UTILITY.FORMAT_ERROR_STACK而不是SQLERRM
  • 这仍然不会告诉你它在抱怨哪个表。
  • 假设您有一个用于创建 SQL 的变量,为什么错误消息不能简单地不显示变量的值?或者您可以使用 raise application error 来引发自定义错误和消息

标签: oracle plsql error-handling dynamic-sql


【解决方案1】:

使用DBMS_SQL代替原生动态SQL,然后使用DBMS_SQL.LAST_ERROR_POSITION()标识语句中出错的部分。

DBMS_SQL 不如原生动态 SQL 方便,但也更强大。有几个需要注意的问题。第一个是DBMS_SQL.PARSE这个过程不仅会解析命令,还会自动运行DDL命令。

下面的代码尝试使用另外两个表创建一个表,其中一个显然不存在。正则表达式用于输出每个字符 从错误的位置到第一个空格。 (此代码基于this answer.

declare
    v_cursor_id integer := dbms_sql.open_cursor ();
    v_sql varchar2(32767) := q'[
        create table zzz_temp as
        select *
        from dual
        join some_schema.fake_table
            on dual.dummy = fake_table.dummy
    ]';
begin
    dbms_sql.parse(v_cursor_id, v_sql, dbms_sql.native);
    dbms_sql.close_cursor(v_cursor_id);
exception
    when others then
        dbms_output.put_line
        (
            sqlerrm||chr(10)||
            'Error occurred here: '||
            regexp_substr
            (
                srcstr   => v_sql,
                pattern  => '\w+',
                position => dbms_sql.last_error_position()
            )
        );
        dbms_sql.close_cursor(v_cursor_id);
end;
/

DBMS_OUTPUT:

ORA-00942: table or view does not exist
Error occurred here: fake_table

其他一些随机代码建议:

  1. 使用PARALLEL(4) 而不是PARALLEL(A, 4)。语句级并行性几乎总是比对象级并行性好。如果您并行运行一个表,您可能希望并行运行整个查询。
  2. 尽量避免WHEN OTHERS。如果可能,请使用更具体的错误处理程序。

【讨论】:

  • 谢谢,这稍微解决了我的问题。但我明白了。非常感谢。
猜你喜欢
  • 2019-01-22
  • 2015-11-09
  • 2011-12-10
  • 1970-01-01
  • 2015-01-30
  • 2016-08-23
  • 2020-10-16
  • 2018-02-05
相关资源
最近更新 更多