如何在 Oracle 物化视图中记录导致错误的数据?

发布于 2024-12-04 04:32:24 字数 353 浏览 3 评论 0原文

我们创建了一些物化视图,这些视图在实际应用程序数据的副本上运行良好。该应用程序不会监管自己的数据。从那时起,一些用户在数据输入时可能要么粗心,要么有创意。 Mview 现在窒息而死。错误消息表明我们正在从一个或多个函数返回多行。

我们一直在尝试使用异常——在 DBMS_Output 中针对第一行 object_id 取得了一些成功,导致(其中一个)函数失败。最好能够完成 MView 的运行,并记录导致每个函数出现问题的 object_ids。我们尚未成功将异常数据插入表中。

平台是Oracle 10g2。我一直试图将 DML 错误登录塞进我的脑子里。我知道这应该适用于批量数据,并且我假设创建物化视图符合条件。这对 MView 有用吗?这是最好的方法吗?

We created some materialized views that ran fine against a copy of actual app data. The app does not police its own data. Since then, some of the users may have been either careless or creative in their data entry. Mview now chokes and dies. Error messages indicate we are getting multiple rows returned from one or more functions.

We have been trying to use EXCEPTIONS -- with some success at DBMS_Output for the first row object_id that causes (one of) the functions to fail. It would be better be able to complete a run for the MView, and log the object_ids that cause problems from each function. We haven't succeeded in inserting the exception data into a table.

Platform is Oracle 10g2. I've been trying to cram DML Error Logging into my head. I understand that this should work for BULK data, and I am assuming that creating a materialized view would qualify. WOULD this work for MViews? Is this the best way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枕梦 2024-12-11 04:32:24

如果您只是尝试刷新物化视图,我不知道如何使用 DML 错误日志记录来捕获所有问题行。另一方面,您可以创建一个表,并在填充该表时使用 DML 错误日志记录来捕获刷新物化视图时遇到的所有错误。

您可以手动填充此表,然后创建一个物化在此预建表上查看。这可能会产生问题,具体取决于具体化视图的使用方式以及启用的查询重写类型,因为您构建的表将丢失基础表中的一些数据(写入错误日志的行)。

创建表和错误日志

SQL> create table t (
  2    col1 number,
  3    col2 number
  4  );

Table created.

Elapsed: 00:00:00.00

SQL> ed
Wrote file afiedt.buf

  1  begin
  2    dbms_errlog.create_error_log( 'T', 'T_ERR' );
  3* end;
SQL> /

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
SQL> create function f1
  2    return varchar2
  3  is
  4  begin
  5    return 'A';
  6  end;
  7  /

Function created.

尝试插入 10 行。 3 将失败,因为 LEVEL 将是 3 的倍数,并且函数返回的字符串无法转换为数字

Elapsed: 00:00:00.01
SQL> insert into t( col1, col2 )
  2    select level,
  3           (case when mod(level,3) = 0
  4                 then to_number( f1 )
  5                 else mod(level,3)
  6             end)
  7      from dual
  8   connect by level <= 10
  9       log errors into t_err
 10           reject limit unlimited;

7 rows created.

Elapsed: 00:00:00.01

SQL> ed
Wrote file afiedt.buf

  1  select ora_err_mesg$, col1, col2
  2*   from t_err
SQL> /

ORA_ERR_MESG$                  COL1       COL2
------------------------------ ---------- ----------
ORA-01722: invalid number      3          0
ORA-01722: invalid number      6          0
ORA-01722: invalid number      9          0

Elapsed: 00:00:00.00

现在,使用此预建表来创建物化视图

SQL> ed
Wrote file afiedt.buf

  1  create materialized view t
  2      on prebuilt table
  3  as
  4  select 1 col1, 1 col2
  5*   from dual
SQL> /

Materialized view created.

Elapsed: 00:00:00.11

If you're just trying to refresh the materialized view, I don't know of a way to use DML error logging to capture all the problem rows. On the other hand, you could create a table and use DML error logging when you populate the table to capture all the errors that you would encounter refreshing the materialized view.

Potentially, you could populate this table manually and then create a materialized view on this prebuilt table. That may create problems depending on exactly how the materialized view is being used and what sorts of query rewrite is enabled since the table you built will be missing some of the data from the underlying table (the rows written to the error log).

Create the table and the error log

SQL> create table t (
  2    col1 number,
  3    col2 number
  4  );

Table created.

Elapsed: 00:00:00.00

SQL> ed
Wrote file afiedt.buf

  1  begin
  2    dbms_errlog.create_error_log( 'T', 'T_ERR' );
  3* end;
SQL> /

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
SQL> create function f1
  2    return varchar2
  3  is
  4  begin
  5    return 'A';
  6  end;
  7  /

Function created.

Try to insert 10 rows. 3 will fail because the LEVEL will be a multiple of 3 and the string returned by the function can't be converted into a number

Elapsed: 00:00:00.01
SQL> insert into t( col1, col2 )
  2    select level,
  3           (case when mod(level,3) = 0
  4                 then to_number( f1 )
  5                 else mod(level,3)
  6             end)
  7      from dual
  8   connect by level <= 10
  9       log errors into t_err
 10           reject limit unlimited;

7 rows created.

Elapsed: 00:00:00.01

SQL> ed
Wrote file afiedt.buf

  1  select ora_err_mesg$, col1, col2
  2*   from t_err
SQL> /

ORA_ERR_MESG$                  COL1       COL2
------------------------------ ---------- ----------
ORA-01722: invalid number      3          0
ORA-01722: invalid number      6          0
ORA-01722: invalid number      9          0

Elapsed: 00:00:00.00

Now, use this prebuilt table to create the materialized view

SQL> ed
Wrote file afiedt.buf

  1  create materialized view t
  2      on prebuilt table
  3  as
  4  select 1 col1, 1 col2
  5*   from dual
SQL> /

Materialized view created.

Elapsed: 00:00:00.11
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文