Home » SQL & PL/SQL » SQL & PL/SQL » Nested Table issue. (Oracle 10g Release 2.)
Nested Table issue. [message #547821] |
Sat, 17 March 2012 01:29  |
Manoj.Gupta.91
Messages: 239 Registered: March 2008 Location: Delhi
|
Senior Member |
|
|
Hi All,
I've to do a update activity for data correction. There are about 1 crore records involved in this. I want to keep a log of the activity at least Sales No. so that I can validate my data correction. Main cursor is involved for this. The problem is if I insert each record for sales number in the loop then process will take about double time. So i decided to create a nested table and insert after each session finishes.
I'm talking about session here is. The table I'm updation is partition table. So I can have many sessions and each session updating different table partition. This way there is no lock, better performance. Server has 35 processors so I can at least have 25 sessiions.
I could have used varray for this. But I want to learn nested table also. Problem here is not to take different way to complete this activity but to learn why I'm facing this issue.
Please help.
CREATE OR REPLACE TYPE OBJ_TXN_LOG AS OBJECT
(
SALES_NO VARCHAR2(24)
,sALES_SEQ NUMBER(4)
) ;
CREATE OR REPLACE TYPE TYP_TBL_TXN_LOG
AS TABLE OF OBJ_TXN_LOG ;
CREATE TABLE SLS_UPDT_LOG
(
TXN_LOG TYP_TBL_TXN_LOG
)
NESTED TABLE TXN_LOG STORE AS NESTED_TAB
TABLESPACE PCARDUSR_DAT_MT01 ;
DECLARE
CURSOR CUR_TMP
IS
SELECT
AA
,BB
,CC
,DD
FROM TABLE1 ;
TBL_TXN_LOG TYP_TBL_TXN_LOG := TYP_TBL_TXN_LOG () ;
LV_SQL_QRY VARCHAR2(4000) ;
I NUMBER := 0 ;
BEGIN
FOR REC_TMP IN CUR_TMP LOOP
I = I + 1 ;
LV_SQL_QRY := ' UPDATE TABLE2 N PARTITION( TABLE2_01 ) '
|| ' SET N.X = ' || CHR(39) || REC_TMP.AA || CHR(39)
|| ' WHERE N.P = ' || CHR(39) || REC_TMP.BB || CHR(39)
|| ' WHERE N.T = ' || CHR(39) || REC_TMP.CC || CHR(39)
|| ' RETURNING N.SALES_NO, N.SALES_SEQ INTO :1, :2 ' ;
EXECUTE IMMEDIATE( LV_SQL_QRY )
RETURNING INTO TBL_TXN_LOG(I).SALES_NO, TBL_TXN_LOG(I).SALES_SEQ ;
END LOOP ;
INSERT INTO SLS_UPDT_LOG VALUES( TBL_TXN_LOG ) ;
COMMIT WORK ;
END ;
Thanks & Regards
Manoj
|
|
|
|
Re: Nested Table issue. [message #547827 is a reply to message #547823] |
Sat, 17 March 2012 01:51   |
Manoj.Gupta.91
Messages: 239 Registered: March 2008 Location: Delhi
|
Senior Member |
|
|
Dear Michel,
This is a dummy script. I cannot post original script here due to some legal constraints. I might have made some mistake while converting my script to dummy.
I've explained my idea here. As per your reply this is a bad idea. OK please help me to do it correctly. What is the correct approach to do this. Also help me to know about issue in my script for nested table.
Thnaks & Regards
Manoj
|
|
|
|
Re: Nested Table issue. [message #547835 is a reply to message #547829] |
Sat, 17 March 2012 02:37   |
Manoj.Gupta.91
Messages: 239 Registered: March 2008 Location: Delhi
|
Senior Member |
|
|
Hi Michel,
Below is complete script including some sample records.
This is just an example code data and structure. Original is different.
CREATE OR REPLACE TYPE OBJ_TXN_LOG AS OBJECT
(
SALES_NO VARCHAR2(24)
,SALES_SEQ NUMBER(4)
) ;
CREATE OR REPLACE TYPE TYP_TBL_TXN_LOG
AS TABLE OF OBJ_TXN_LOG ;
CREATE TABLE SLS_UPDT_LOG
(
TXN_LOG TYP_TBL_TXN_LOG
)
NESTED TABLE TXN_LOG STORE AS NESTED_TAB
TABLESPACE PCARDUSR_DAT_MT01 ;
CREATE TABLE SALES_DETAIL ( SALES_NO VARCHAR2(24), SALES_SEQ NUMBER(4), CLOSING_DATE DATE )
TABLESPACE PCARDUSR_DAT_MT01 ;
CREATE TABLE SALES_DETAIL_RPT ( SALES_NO VARCHAR2(24), SALES_SEQ NUMBER(4), CLOSING_DATE DATE )
TABLESPACE PCARDUSR_DAT_MT01;
INSERT INTO SALES_DETAIL( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01234', 1, TRUNC(SYSDATE-20) ) ;
INSERT INTO SALES_DETAIL( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01235', 1, TRUNC(SYSDATE-20) ) ;
INSERT INTO SALES_DETAIL( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01236', 1, TRUNC(SYSDATE-20) ) ;
INSERT INTO SALES_DETAIL_RPT( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01234', 1, NULL ) ;
INSERT INTO SALES_DETAIL_RPT( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01235', 1, NULL ) ;
INSERT INTO SALES_DETAIL_RPT( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01236', 1, NULL ) ;
COMMIT ;
create or replace
procedure procedure1 as
CURSOR CUR_TMP
IS
SELECT
SALES_NO
,SALES_SEQ
,CLOSING_DATE
FROM SALES_DETAIL ;
TBL_TXN_LOG TYP_TBL_TXN_LOG := TYP_TBL_TXN_LOG () ;
LV_SQL_QRY VARCHAR2(4000) ;
I NUMBER := 0 ;
BEGIN
FOR REC_TMP IN CUR_TMP LOOP
I := I + 1 ;
TBL_TXN_LOG.EXTEND(1) ;
LV_SQL_QRY := ' UPDATE SALES_DETAIL_RPT T2 SET T2.CLOSING_DATE = ' || CHR(39) ||
REC_TMP.CLOSING_DATE || CHR(39)
|| ' WHERE T2.SALES_NO = ' || CHR(39) ||
REC_TMP.SALES_NO || CHR(39)
|| ' AND T2.SALES_SEQ = ' || CHR(39) || REC_TMP.SALES_SEQ || CHR(39)
|| ' RETURNING T2.SALES_NO , T2.SALES_SEQ INTO :1, :2 ' ;
EXECUTE IMMEDIATE( LV_SQL_QRY )
RETURNING INTO TBL_TXN_LOG(1).SALES_NO, TBL_TXN_LOG(1).SALES_SEQ ;
END LOOP ;
INSERT INTO SLS_UPDT_LOG VALUES( TBL_TXN_LOG ) ;
COMMIT WORK ;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK WORK ;
DBMS_OUTPUT.PUT_LINE( DBMS_UTILITY.FORMAT_ERROR_BACKTRACE ) ;
END ;
Thanks & Regards
Manoj
[Updated on: Mon, 19 March 2012 01:54] by Moderator Report message to a moderator
|
|
|
|
Re: Nested Table issue. [message #547838 is a reply to message #547837] |
Sat, 17 March 2012 03:04   |
Manoj.Gupta.91
Messages: 239 Registered: March 2008 Location: Delhi
|
Senior Member |
|
|
Hi,
I don't want to use trigger. I could have don't the same thing in a simple insert statement in the script. But the problem is this will add a big overhead to overall process and it will take about double time to finish.
I can manage a simple nested table in PL/SQL and then at last insert it in table. Insert will happen only once so overhead will be very less.
Corore is 1,00,00,000
Thanks & Regards
Manoj
|
|
|
Re: Nested Table issue. [message #547839 is a reply to message #547838] |
Sat, 17 March 2012 03:10   |
John Watson
Messages: 8979 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Quote: But the problem is this will add a big overhead to overall process and it will take about double time to finish.
I am surprised that your tests found this to be the case. I would have expected that your technique of generating and executing 10000000 dynamic SQL statements would be much slower. Perhaps I've misunderstood what your code is doing.
|
|
|
Re: Nested Table issue. [message #547841 is a reply to message #547839] |
Sat, 17 March 2012 03:18   |
Manoj.Gupta.91
Messages: 239 Registered: March 2008 Location: Delhi
|
Senior Member |
|
|
Dear John,
This is not the actual code but just a dummy code and exmple. Both the tables are partitioned. So I want to execute this updated for partition wise on different sessions. For example I've 10 partitions so I'll have 10 sessions each updating different partition.
I'll pass partition name as parameter in the procedure. This is because I've 35 processors in oracle clustered server. In this way it will be much faster. Since we cannot have big window to complete such activities so it has to be completed in shortest time.
Please suggest.
LV_SQL_QRY := ' UPDATE SALES_DETAIL_RPT PARTITION( SALES_DTL_1201 ) T2 '
|| ' SET T2.CLOSING_DATE = ' || CHR(39) || REC_TMP.CLOSING_DATE || CHR(39)
|| ' WHERE T2.SALES_NO = ' || CHR(39) || REC_TMP.SALES_NO || CHR(39)
|| ' AND T2.SALES_SEQ = ' || CHR(39) || REC_TMP.SALES_SEQ || CHR(39)
|| ' RETURNING T2.SALES_NO , T2.SALES_SEQ INTO :1, :2 ' ;
|
|
|
Re: Nested Table issue. [message #547862 is a reply to message #547841] |
Sat, 17 March 2012 09:55   |
 |
Barbara Boehmer
Messages: 9106 Registered: November 2002 Location: California, USA
|
Senior Member |
|
|
The following corrects your syntax so that it runs, disregarding the method chosen. I commented out the tablespace clauses so that it would run on my sytem.
The method that I used to debug it, which you should learn to use, begins with temporarily commenting out the exception section, so that you get the line number that the error occurs on. This tells you that you were missing some initialization, which is solved by adding the line:
TBL_TXN_LOG(I) := OBJ_TXN_LOG (NULL, NULL);
You can also temporarily comment out the execution of the dynamic SQL and use dbms_output to display it instead. You can copy and paste, replacing variables and run the update statement form SQL to find any problems.
I noticed that you were using (1) in the returning clause, resulting in always affecting the first record, so I fixed that by using (I) so that it updates the next one.
SCOTT@orcl_11gR2> CREATE OR REPLACE TYPE OBJ_TXN_LOG AS OBJECT
2 (
3 SALES_NO VARCHAR2(24)
4 ,SALES_SEQ NUMBER(4)
5 ) ;
6 /
Type created.
SCOTT@orcl_11gR2> CREATE OR REPLACE TYPE TYP_TBL_TXN_LOG
2 AS TABLE OF OBJ_TXN_LOG ;
3 /
Type created.
SCOTT@orcl_11gR2> CREATE TABLE SLS_UPDT_LOG
2 (
3 TXN_LOG TYP_TBL_TXN_LOG
4 )
5 NESTED TABLE TXN_LOG STORE AS NESTED_TAB
6 --TABLESPACE PCARDUSR_DAT_MT01
7 ;
Table created.
SCOTT@orcl_11gR2> CREATE TABLE SALES_DETAIL
2 ( SALES_NO VARCHAR2(24), SALES_SEQ NUMBER(4), CLOSING_DATE DATE )
3 --TABLESPACE PCARDUSR_DAT_MT01
4 ;
Table created.
SCOTT@orcl_11gR2> CREATE TABLE SALES_DETAIL_RPT
2 ( SALES_NO VARCHAR2(24), SALES_SEQ NUMBER(4), CLOSING_DATE DATE )
3 --TABLESPACE PCARDUSR_DAT_MT01
4 ;
Table created.
SCOTT@orcl_11gR2> BEGIN
2 INSERT INTO SALES_DETAIL( SALES_NO, SALES_SEQ , CLOSING_DATE )
3 VALUES( '01234', 1, TRUNC(SYSDATE-20) ) ;
4 INSERT INTO SALES_DETAIL( SALES_NO, SALES_SEQ , CLOSING_DATE )
5 VALUES( '01235', 1, TRUNC(SYSDATE-20) ) ;
6 INSERT INTO SALES_DETAIL( SALES_NO, SALES_SEQ , CLOSING_DATE )
7 VALUES( '01236', 1, TRUNC(SYSDATE-20) ) ;
8 INSERT INTO SALES_DETAIL_RPT( SALES_NO, SALES_SEQ , CLOSING_DATE )
9 VALUES( '01234', 1, NULL ) ;
10 INSERT INTO SALES_DETAIL_RPT( SALES_NO, SALES_SEQ , CLOSING_DATE )
11 VALUES( '01235', 1, NULL ) ;
12 INSERT INTO SALES_DETAIL_RPT( SALES_NO, SALES_SEQ , CLOSING_DATE )
13 VALUES( '01236', 1, NULL ) ;
14 COMMIT ;
15 END;
16 /
PL/SQL procedure successfully completed.
SCOTT@orcl_11gR2> create or replace procedure procedure1
2 as
3 CURSOR CUR_TMP IS
4 SELECT SALES_NO
5 , SALES_SEQ
6 , CLOSING_DATE
7 FROM SALES_DETAIL ;
8 TBL_TXN_LOG TYP_TBL_TXN_LOG := TYP_TBL_TXN_LOG () ;
9 LV_SQL_QRY VARCHAR2(4000) ;
10 I NUMBER := 0 ;
11 BEGIN
12 FOR REC_TMP IN CUR_TMP LOOP
13 I := I + 1 ;
14 TBL_TXN_LOG.EXTEND(1) ;
15 TBL_TXN_LOG(I) := OBJ_TXN_LOG (NULL, NULL);
16 LV_SQL_QRY :=
17 ' UPDATE SALES_DETAIL_RPT T2
18 SET T2.CLOSING_DATE = ' || CHR(39) || REC_TMP.CLOSING_DATE || CHR(39) ||
19 ' WHERE T2.SALES_NO = ' || CHR(39) || REC_TMP.SALES_NO || CHR(39) ||
20 ' AND T2.SALES_SEQ = ' || CHR(39) || REC_TMP.SALES_SEQ || CHR(39) ||
21 ' RETURNING T2.SALES_NO, T2.SALES_SEQ INTO :1, :2 ' ;
22 EXECUTE IMMEDIATE( LV_SQL_QRY )
23 RETURNING INTO TBL_TXN_LOG(I).SALES_NO, TBL_TXN_LOG(I).SALES_SEQ ;
24 END LOOP ;
25 INSERT INTO SLS_UPDT_LOG VALUES( TBL_TXN_LOG ) ;
26 COMMIT WORK ;
27 EXCEPTION
28 WHEN OTHERS THEN
29 ROLLBACK WORK ;
30 DBMS_OUTPUT.PUT_LINE( DBMS_UTILITY.FORMAT_ERROR_BACKTRACE ) ;
31 END ;
32 /
Procedure created.
SCOTT@orcl_11gR2> SHOW ERRORS
No errors.
SCOTT@orcl_11gR2> EXEC procedure1
PL/SQL procedure successfully completed.
SCOTT@orcl_11gR2> SELECT * FROM sales_detail_rpt
2 /
SALES_NO SALES_SEQ CLOSING_D
------------------------ ---------- ---------
01234 1 26-FEB-12
01235 1 26-FEB-12
01236 1 26-FEB-12
3 rows selected.
SCOTT@orcl_11gR2> SELECT * FROM sls_updt_log
2 /
TXN_LOG(SALES_NO, SALES_SEQ)
--------------------------------------------------------------------------------
TYP_TBL_TXN_LOG(OBJ_TXN_LOG('01234', 1), OBJ_TXN_LOG('01235', 1), OBJ_TXN_LOG('0
1236', 1))
1 row selected.
SCOTT@orcl_11gR2>
[Updated on: Sat, 17 March 2012 09:56] Report message to a moderator
|
|
|
|
Re: Nested Table issue. [message #547905 is a reply to message #547864] |
Sun, 18 March 2012 20:09   |
Manoj.Gupta.91
Messages: 239 Registered: March 2008 Location: Delhi
|
Senior Member |
|
|
Hi,
Thanks "Barbara Boehmer" I got where I was doing a mistake. I was referring to constructure wrongly.
Thanks "Michel Cadot". Exception handling part not the actual part. This is a dummy code. Yes, this is a bad way for "WHEN OTHERS"
But I don't understand your concern about COMMIT. Are you talking about "COMMIT WORK"? Please help me to know what is wrong with this. I'll not repeat this mistake in future.
I'm facing one error even after hard coding things.
TBL_TXN_LOG(I).SALES_NO := '12345' ;
TBL_TXN_LOG(I).SALES_SEQ := 2 ;
ORA-22805: cannot insert NULL object into object tables or nested tables
Thanks & Regards
Manoj
|
|
|
|
Re: Nested Table issue. [message #547907 is a reply to message #547906] |
Sun, 18 March 2012 20:24   |
Manoj.Gupta.91
Messages: 239 Registered: March 2008 Location: Delhi
|
Senior Member |
|
|
Hi,
CREATE OR REPLACE TYPE OBJ_TXN_LOG AS OBJECT
(
SALES_NO VARCHAR2(24)
,SALES_SEQ NUMBER(4)
) ;
CREATE OR REPLACE TYPE TYP_TBL_TXN_LOG
AS TABLE OF OBJ_TXN_LOG ;
CREATE TABLE SLS_UPDT_LOG
(
TXN_LOG TYP_TBL_TXN_LOG
)
NESTED TABLE TXN_LOG STORE AS NESTED_TAB
TABLESPACE PCARDUSR_DAT_MT01 ;
CREATE TABLE SALES_DETAIL ( SALES_NO VARCHAR2(24), SALES_SEQ NUMBER(4), CLOSING_DATE DATE )
TABLESPACE PCARDUSR_DAT_MT01 ;
CREATE TABLE SALES_DETAIL_RPT ( SALES_NO VARCHAR2(24), SALES_SEQ NUMBER(4), CLOSING_DATE DATE )
TABLESPACE PCARDUSR_DAT_MT01;
INSERT INTO SALES_DETAIL( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '4567', 1, TRUNC(SYSDATE-20) ) ;
INSERT INTO SALES_DETAIL( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01235', 1, TRUNC(SYSDATE-20) ) ;
INSERT INTO SALES_DETAIL( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01236', 1, TRUNC(SYSDATE-20) ) ;
INSERT INTO SALES_DETAIL_RPT( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01234', 1, NULL ) ;
INSERT INTO SALES_DETAIL_RPT( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01235', 1, NULL ) ;
INSERT INTO SALES_DETAIL_RPT( SALES_NO, SALES_SEQ , CLOSING_DATE )
VALUES( '01236', 1, NULL ) ;
COMMIT ;
create or replace
procedure procedure1 as
CURSOR CUR_TMP
IS
SELECT
SALES_NO
,SALES_SEQ
,CLOSING_DATE
FROM SALES_DETAIL ;
TBL_TXN_LOG TYP_TBL_TXN_LOG := TYP_TBL_TXN_LOG( NULL, NULL ) ;
LV_SQL_QRY VARCHAR2(4000) ;
I NUMBER := 0 ;
BEGIN
FOR REC_TMP IN CUR_TMP LOOP
I := I + 1 ;
TBL_TXN_LOG.EXTEND( 1 ) ;
TBL_TXN_LOG(I) := OBJ_TXN_LOG( NULL, NULL ) ;
LV_SQL_QRY := ' UPDATE SALES_DETAIL_RPT T2 SET T2.CLOSING_DATE = ' || CHR(39) ||
REC_TMP.CLOSING_DATE || CHR(39)
|| ' WHERE T2.SALES_NO = ' || CHR(39) || REC_TMP.SALES_NO || CHR(39)
|| ' AND T2.SALES_SEQ = ' || CHR(39) || REC_TMP.SALES_SEQ || CHR(39)
|| ' RETURNING T2.SALES_NO, T2.SALES_SEQ INTO :1, :2 ' ;
EXECUTE IMMEDIATE( LV_SQL_QRY )
RETURNING INTO TBL_TXN_LOG(I).SALES_NO, TBL_TXN_LOG(I).SALES_SEQ ;
TBL_TXN_LOG(I).SALES_NO := '1234' ;
TBL_TXN_LOG(I).SALES_SEQ := 1 ;
END LOOP ;
INSERT INTO SLS_UPDT_LOG VALUES( TBL_TXN_LOG ) ;
COMMIT WORK ;
END ;
BEGIN
PROCEDURE1 ;
END ;
ORA-22805: cannot insert NULL object into object tables or nested tables
ORA-06512: at "STAGING.PROCEDURE1", line 34
ORA-06512: at line 2
22805. 00000 - "cannot insert NULL object into object tables or nested tables"
*Cause: An attempt was made to insert a NULL object into an object table
or a Nested Table.
*Action: Ensure that a non-NULL object is inserted into the table or
insert an object with attributes whose values are NULL.
Regards
Manoj
[Updated on: Mon, 19 March 2012 01:53] by Moderator Report message to a moderator
|
|
|
|
|
Re: Nested Table issue. [message #547923 is a reply to message #547920] |
Mon, 19 March 2012 00:51   |
Manoj.Gupta.91
Messages: 239 Registered: March 2008 Location: Delhi
|
Senior Member |
|
|
Hi Michel,
What I understand is a procedure should not be committed but a complete transaction should be committed. There can be so many procedures in a transaction.
right?
Thanks & Regards
Manoj
|
|
|
Re: Nested Table issue. [message #547928 is a reply to message #547923] |
Mon, 19 March 2012 01:46   |
 |
Michel Cadot
Messages: 68765 Registered: March 2007 Location: Saint-Maur, France, https...
|
Senior Member Account Moderator |
|
|
ONLY the caller knows if the transaction should be commited or not, NOT the procedure.
What do you say if some else says "I did some work, I commit it" and commit yours
at the same time without you know it?
What if now, in the end, you want to rollback what you did?
Regards
Michel
[Updated on: Mon, 19 March 2012 01:55] Report message to a moderator
|
|
|
Re: Nested Table issue. [message #547938 is a reply to message #547928] |
Mon, 19 March 2012 02:43  |
Manoj.Gupta.91
Messages: 239 Registered: March 2008 Location: Delhi
|
Senior Member |
|
|
Hi Michel,
Understood.
This was a procedure for one time activity and it will never be used after that. So I'm putting commit.
I understood that this is a wrong practice and should not be used. I'll add it to my basics.
Thanks & Regards
Manoj
|
|
|
Goto Forum:
Current Time: Sun Aug 03 17:34:27 CDT 2025
|