When working large amount of data, you must consider exceptions. Suppose that a bulk operation that takes 100.000 of records and inserts it to a table. There may have some exceptions during insertion such as foreign key or not null constraints. If you did not consider exceptions, you can lose your time and do more work. One other assumption that can be, you can get an error on the last record. So all of your correct data can get waste.
Oracle solves this problems with some techniques. One of them is save bulk_exceptions in forall statement. Other is dbms_errlog package. I have described dbms_errlog package one of my older posts. (For performance analysis click here)
Demonstration below simple shows the cases above:
Connected to Oracle Database 10g Express Edition Release 10.2.0.1.0
Connected as SYS
SQL>
SQL> drop table t;
Table dropped
Create a table and add some constraints.
SQL> create table t(i number not null);
Table created
SQL> alter table t add constraint ck_i check( i < 2 );
Table altered
Make insertion with normal way. You will get an exception and all work will be rolled back.
SQL> DECLARE
2 TYPE t_t IS TABLE OF NUMBER;
3 n_t t_t;
4 BEGIN
5 SELECT decode(rownum, 2, NULL, rownum) BULK COLLECT
6 INTO n_t
7 FROM user_tables
8 WHERE rownum < 4;
9 FORALL i IN n_t.FIRST .. n_t.LAST
10 INSERT INTO t VALUES( n_t (i) );
11 END;
12 /
DECLARE
TYPE t_t IS TABLE OF NUMBER;
n_t t_t;
BEGIN
SELECT decode(rownum, 2, NULL, rownum) BULK COLLECT
INTO n_t
FROM user_tables
WHERE rownum < 4;
FORALL i IN n_t.FIRST .. n_t.LAST
INSERT INTO t VALUES( n_t (i) );
END;
ORA-01400: cannot insert NULL into ("SYS"."T"."I")
ORA-06512: at line 9
SQL> SELECT * FROM t;
I
----------
SQL> rollback;
Rollback complete
First technique is handling in forall statement. You will get correct records in table.
SQL> DECLARE
2 TYPE t_t IS TABLE OF NUMBER;
3 n_t t_t;
4 BEGIN
5 SELECT decode(rownum, 2, NULL, rownum) BULK COLLECT
6 INTO n_t
7 FROM user_tables
8 WHERE rownum < 4;
9 FORALL i IN n_t.FIRST .. n_t.LAST SAVE EXCEPTIONS
10 INSERT INTO t VALUES( n_t (i) );
11
12 EXCEPTION
13 WHEN OTHERS THEN
14 dbms_output.put_line( sqlerrm );
15 FOR i IN 1 .. SQL%BULK_EXCEPTIONS.COUNT LOOP
16 dbms_output.put_line(SQL%BULK_EXCEPTIONS(i)
17 .ERROR_INDEX || ' : ' ||
18 SQLERRM(-1 * SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
19 END LOOP;
20
21 END;
22 /
ORA-24381: error(s) in array DML
2 : ORA-01400: cannot insert NULL into ()
3 : ORA-02290: check constraint (.) violated
PL/SQL procedure successfully completed
SQL> SELECT * FROM t;
I
----------
1
SQL> rollback;
Rollback complete
Second method is using supplied package dbms_errlog.
SQL> drop table err$_t;
Table dropped
SQL> BEGIN
2 dbms_errlog.create_error_log('t');
3 END;
4 /
PL/SQL procedure successfully completed
SQL> DECLARE
2 TYPE t_t IS TABLE OF NUMBER;
3 n_t t_t;
4 BEGIN
5 SELECT decode(rownum, 2, NULL, rownum) BULK COLLECT
6 INTO n_t
7 FROM user_tables
8 WHERE rownum < 4;
9 FORALL i IN n_t.FIRST .. n_t.LAST
10 INSERT INTO t VALUES( n_t (i) ) log errors reject LIMIT unlimited;
11
12 END;
13 /
PL/SQL procedure successfully completed
SQL> SELECT * FROM t;
I
----------
1
Errors are logged.
SQL> SELECT t.ora_err_number$ errno, t.ora_err_mesg$ errmess FROM err$_t t;
ERRNO ERRMESS
---------- --------------------------------------------------------------------------------
1400 ORA-01400: cannot insert NULL into ("SYS"."T"."I")
2290 ORA-02290: check constraint (SYS.CK_I) violated
Showing posts with label DBMS_ERRORLOG. Show all posts
Showing posts with label DBMS_ERRORLOG. Show all posts
02 December 2006
11 September 2006
Using DBMS_ERRORLOG Package
Oracle 10G ile birlikte gelen yeni paketlerden biridir DBMS_ERRORLOG. Bu sayede yoğun işlemlerininizi, işlemleriniz kesilmeden yapabilirsiniz. Oluşan hataların ayrı bir yere aktarılması ile daha sonra oluşan hataları gözlemleyip, gerekli aksiyonları alabilirsiniz.
Aşağıda yaptığım örnekte 100000 kayıtlık bir insert işleminde olabilecek hatalardan dolayı bu paketin kullanılmasının avantajı belirtilmiştir.
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as HR
SQL>
SQL> drop table error_log_test;
Table dropped
Executed in 0,016 seconds
Tablo Oluşturulur. İçine kayıt eklenir.
SQL> create table error_log_test( i number );
Table created
Executed in 0 seconds
SQL> DECLARE
2 i NUMBER := 0;
3 BEGIN
4 FOR i IN 1 .. 100000 LOOP
5 INSERT INTO error_log_test VALUES (i);
6 IF MOD(i, 1000) = 0 THEN
7 COMMIT;
8 END IF;
9 END LOOP;
10
11 END;
12 /
PL/SQL procedure successfully completed
Executed in 4,031 seconds
SQL> SELECT COUNT(*) FROM error_log_test;
COUNT(*)
----------
100000
Executed in 0,016 seconds
Kayıtların ekleneceği demo tablo oluşturulur.
SQL> drop table error_log_test_demo;
Table dropped
Executed in 0,219 seconds
SQL> drop table err$_error_log_test_demo;
drop table err$_error_log_test_demo
ORA-00942: table or view does not exist
SQL> create table error_log_test_demo( x number );
Table created
Executed in 0,016 seconds
Kısıtlar eklenir. Bu sayede hata oluşmasını sağlıyoruz.
SQL> alter table error_log_test_demo add constraint more_than_99990 check( x < 99990 );
Table altered
Executed in 0,015 seconds
SQL> alter table error_log_test_demo add constraint less_than_10 check( x > 10 );
Table altered
Executed in 0 seconds
dbms_errlog.create_error_log prosedürü ile hata esnasında gidilecek tablo oluşturulur.
SQL> BEGIN
2 dbms_errlog.create_error_log('error_log_test_demo');
3 END;
4 /
PL/SQL procedure successfully completed
Executed in 0,016 seconds
SQL> describe err$_error_log_test_demo;
Name Type Nullable Default Comments
--------------- -------------- -------- ------- --------
ORA_ERR_NUMBER$ NUMBER Y
ORA_ERR_MESG$ VARCHAR2(2000) Y
ORA_ERR_ROWID$ UROWID(4000) Y
ORA_ERR_OPTYP$ VARCHAR2(2) Y
ORA_ERR_TAG$ VARCHAR2(2000) Y
X VARCHAR2(4000) Y
dbms_errlog kullanılmadan ekleme işlemi yapılmaya çalışılır.
SQL> insert into error_log_test_demo select * from error_log_test;
insert into error_log_test_demo select * from error_log_test
ORA-02290: check constraint (HR.LESS_THAN_10) violated
dbms_errlog ile ekleme işlemi yapılır. Hatalı kayıtlar err$_error_log_test_demo tablosuna aktarılır.
SQL> INSERT INTO error_log_test_demo
2 SELECT * FROM error_log_test log errors reject LIMIT unlimited;
99979 rows inserted
Executed in 5,953 seconds
SQL> SELECT COUNT(*) FROM error_log_test_demo;
COUNT(*)
----------
99979
Executed in 0,016 seconds
Eklenemeyen kayıtlar ve neden eklenemdikleri buradan görülebilir.
SQL> select ed.ora_err_mesg$, ed.x from err$_error_log_test_demo ed ;
ORA_ERR_MESG$ X
------------------------------------------------------ ----
ORA-02290: check constraint (HR.LESS_THAN_10) violated 1
ORA-02290: check constraint (HR.LESS_THAN_10) violated 2
ORA-02290: check constraint (HR.LESS_THAN_10) violated 3
ORA-02290: check constraint (HR.LESS_THAN_10) violated 4
ORA-02290: check constraint (HR.LESS_THAN_10) violated 5
ORA-02290: check constraint (HR.LESS_THAN_10) violated 6
ORA-02290: check constraint (HR.LESS_THAN_10) violated 7
ORA-02290: check constraint (HR.LESS_THAN_10) violated 8
ORA-02290: check constraint (HR.LESS_THAN_10) violated 9
ORA-02290: check constraint (HR.LESS_THAN_10) violated 10
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99990
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99991
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99992
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99993
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99994
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99995
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99996
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99997
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99998
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99999
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 100000
21 rows selected
Executed in 0,047 seconds
SQL>
Aşağıda yaptığım örnekte 100000 kayıtlık bir insert işleminde olabilecek hatalardan dolayı bu paketin kullanılmasının avantajı belirtilmiştir.
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as HR
SQL>
SQL> drop table error_log_test;
Table dropped
Executed in 0,016 seconds
Tablo Oluşturulur. İçine kayıt eklenir.
SQL> create table error_log_test( i number );
Table created
Executed in 0 seconds
SQL> DECLARE
2 i NUMBER := 0;
3 BEGIN
4 FOR i IN 1 .. 100000 LOOP
5 INSERT INTO error_log_test VALUES (i);
6 IF MOD(i, 1000) = 0 THEN
7 COMMIT;
8 END IF;
9 END LOOP;
10
11 END;
12 /
PL/SQL procedure successfully completed
Executed in 4,031 seconds
SQL> SELECT COUNT(*) FROM error_log_test;
COUNT(*)
----------
100000
Executed in 0,016 seconds
Kayıtların ekleneceği demo tablo oluşturulur.
SQL> drop table error_log_test_demo;
Table dropped
Executed in 0,219 seconds
SQL> drop table err$_error_log_test_demo;
drop table err$_error_log_test_demo
ORA-00942: table or view does not exist
SQL> create table error_log_test_demo( x number );
Table created
Executed in 0,016 seconds
Kısıtlar eklenir. Bu sayede hata oluşmasını sağlıyoruz.
SQL> alter table error_log_test_demo add constraint more_than_99990 check( x < 99990 );
Table altered
Executed in 0,015 seconds
SQL> alter table error_log_test_demo add constraint less_than_10 check( x > 10 );
Table altered
Executed in 0 seconds
dbms_errlog.create_error_log prosedürü ile hata esnasında gidilecek tablo oluşturulur.
SQL> BEGIN
2 dbms_errlog.create_error_log('error_log_test_demo');
3 END;
4 /
PL/SQL procedure successfully completed
Executed in 0,016 seconds
SQL> describe err$_error_log_test_demo;
Name Type Nullable Default Comments
--------------- -------------- -------- ------- --------
ORA_ERR_NUMBER$ NUMBER Y
ORA_ERR_MESG$ VARCHAR2(2000) Y
ORA_ERR_ROWID$ UROWID(4000) Y
ORA_ERR_OPTYP$ VARCHAR2(2) Y
ORA_ERR_TAG$ VARCHAR2(2000) Y
X VARCHAR2(4000) Y
dbms_errlog kullanılmadan ekleme işlemi yapılmaya çalışılır.
SQL> insert into error_log_test_demo select * from error_log_test;
insert into error_log_test_demo select * from error_log_test
ORA-02290: check constraint (HR.LESS_THAN_10) violated
dbms_errlog ile ekleme işlemi yapılır. Hatalı kayıtlar err$_error_log_test_demo tablosuna aktarılır.
SQL> INSERT INTO error_log_test_demo
2 SELECT * FROM error_log_test log errors reject LIMIT unlimited;
99979 rows inserted
Executed in 5,953 seconds
SQL> SELECT COUNT(*) FROM error_log_test_demo;
COUNT(*)
----------
99979
Executed in 0,016 seconds
Eklenemeyen kayıtlar ve neden eklenemdikleri buradan görülebilir.
SQL> select ed.ora_err_mesg$, ed.x from err$_error_log_test_demo ed ;
ORA_ERR_MESG$ X
------------------------------------------------------ ----
ORA-02290: check constraint (HR.LESS_THAN_10) violated 1
ORA-02290: check constraint (HR.LESS_THAN_10) violated 2
ORA-02290: check constraint (HR.LESS_THAN_10) violated 3
ORA-02290: check constraint (HR.LESS_THAN_10) violated 4
ORA-02290: check constraint (HR.LESS_THAN_10) violated 5
ORA-02290: check constraint (HR.LESS_THAN_10) violated 6
ORA-02290: check constraint (HR.LESS_THAN_10) violated 7
ORA-02290: check constraint (HR.LESS_THAN_10) violated 8
ORA-02290: check constraint (HR.LESS_THAN_10) violated 9
ORA-02290: check constraint (HR.LESS_THAN_10) violated 10
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99990
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99991
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99992
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99993
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99994
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99995
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99996
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99997
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99998
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 99999
ORA-02290: check constraint (HR.MORE_THAN_99990) violated 100000
21 rows selected
Executed in 0,047 seconds
SQL>
Subscribe to:
Posts (Atom)