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?
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
精彩评论