Skip to Main Content
  • Questions
  • SEQUENCE parameter in creating external table

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Gunjeet.

Asked: December 21, 2004 - 4:57 pm UTC

Last updated: December 22, 2004 - 1:59 pm UTC

Version: 9.2.0.6

Viewed 1000+ times

You Asked


Hi Tom,

Could you please give me an example of using SEQUENCE(1,1) parameter in the create table definition of an external table ?

It seems that it is supported (Oracle9i Database Utilities, Chapter 11
section "Rejected Rows") talks about it but I haven't been able to use it.

I need this in the definition of the external table as I finally create a table using ctas from external table and the final table needs to have a unique sequence number for each record. I use CTAS with PARALLEL option and I'm hitting a bug where if I use the sequence.nextval in the embedded select, it gives me ORA-03113: end-of-file on communication channel error.

I had found a bug # "Bug 3321767 Dump possible (in xtyqbcb) from CTAS with a SEQUENCE" which is marked fixed in 9.2.0.6 but it still does not work with PARALLEL clause (I have reproduced it against a table with 9 million records with 9.2.0.6). Because I'm hitting this bug, I want to assign this unique id to the records in the external table definition so that I do not have to use a sequence in my ctas parallel statement. I can't share the test case as my current data is confidential (I can share the sql script and modify the data if you are interested ...).

Please note that I have already tried ctas without the parallel clause but with a parallel hint for the embedded select and the performance is 3 times "slower" than if I were to use a parallel clause with ctas
(I had tested this by removing the sequence from the embedded select).

Here's my test case for external table (using SEQUENCE) :
Please note that the data file has values for only l_name,p_name,n_name,c1,y1,x2 and y2 (not for d_id).

create table test_ext
( l_name varchar2(100),
p_name varchar2(100),
n_name varchar2(100),
x1 number,
y1 number,
x2 number,
y2 number ,
d_id number
)
ORGANIZATION EXTERNAL
( type oracle_loader
default directory data_dir
access parameters
( records delimited by newline
LOGFILE log_file_dir:'rect_log.txt'
BADFILE log_file_dir:'rect_bad.txt'
fields terminated by ',' missing field values are null
(l_name,
p_name,
n_name,
x1,
y1,
x2,
y2,
d_id SEQUENCE(1,1))
)
location ('test_ext.data')
)PARALLEL 4
REJECT LIMIT UNLIMITED;

Table gets created.

select count(*) from test_ext
*
ERROR at line 1:
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-00554: error encountered while parsing access parameters
KUP-01005: syntax error: found "identifier": expecting one of: "comma, char,
date, defaultif, decimal, double, float, integer, (, nullif, oracle_date,
oracle_number, position, raw, recnum, ), unsigned, varrawc, varchar, varraw,
varcharc, zoned"
KUP-01008: the bad identifier was: SEQUENCE
KUP-01007: at line 12 column 11
ORA-06512: at "SYS.ORACLE_LOADER", line 14
ORA-06512: at line 1

Another realted question is :

If my external table definition has "parallel 8" and I do a ctas with parallel 8 clause against it, I still see only 1 select
if I run your showsql.sql script even though I see 16 processes IN USE in select * from v$px_process;

Not sure if the select against the external table is parallelized.
Same is the case with insert append select with a parallel 8 hint. Only 1 select against process (P000) is shown by showsql.sql.

My data file for external table has 43.5 million records and the file is on a solaris 9 machine.

Thanks,

Gunjeet


and Tom said...

whenever I'm stumped trying to figure out how to convert a sqlldr control file'ism to an external table, I use

sqlldr / test.ctl external_table=generate_only

and see what it says.... Here, it says "use a sequence object". consider:

LOAD DATA
INFILE *
APPEND

INTO TABLE EMP
FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"'
(empno, ename, job, mgr,
hiredate DATE(20) "DD-Month-YYYY",
sal, comm,
deptno CHAR TERMINATED BY ':',
projno,
loadseq SEQUENCE(MAX,1) )


that results in:


sequences created to simulate SEQ in control file:
------------------------------------------------------------------------
CREATE SEQUENCE SYS_SQLLDR_X_SEQ_000 MINVALUE 0 START WITH 0 INCREMENT BY 1


CREATE TABLE statement for external table:
------------------------------------------------------------------------
CREATE TABLE "SYS_SQLLDR_X_EXT_EMP"
(
EMPNO NUMBER(4),
...
PROJNO NUMBER
)
ORGANIZATION external
(
TYPE oracle_loader
DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE CHARACTERSET WE8ISO8859P1
BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'test.bad'
LOGFILE 'test.log_xt'
READSIZE 1048576
SKIP 30
FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' LDRTRIM
REJECT ROWS WITH ALL NULL FIELDS
(
EMPNO CHAR(255)
TERMINATED BY "," OPTIONALLY ENCLOSED BY '"',
....
PROJNO CHAR(255)
TERMINATED BY "," OPTIONALLY ENCLOSED BY '"'
)
)
location
(
'test.ctl'
)
)REJECT LIMIT UNLIMITED


INSERT statements used to load internal tables:
------------------------------------------------------------------------
INSERT /*+ append */ INTO EMP
(
EMPNO,
...
LOADSEQ
)
SELECT EMPNO, ENAME, JOB, MGR, HIREDATE,
SAL, COMM, DEPTNO, PROJNO,
SYS_SQLLDR_X_SEQ_000.nextval
FROM "SYS_SQLLDR_X_EXT_EMP"


so, use an Oracle sequence to do this.


if you see 16 processes in use, then you are going parallel.


the select against the external tables are parallelized. do a select count(*) and see what you see.

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

can sequence parameter be used in create external table ?

Gunjeet Singh, December 21, 2004 - 7:16 pm UTC


Hi Tom,

Thanks for your response.

I think I didn't explain my question well. I wanted to find out a way to use SEQUENCE parameter in the external table create statement. Is it possible ?

Your solution is to use sequence.nextval in the select statement of insert append. I'm not using insert/select.
If I were to use insert/select, I wouldn't have asked this question as I could use a sequence object.

I want to use create table as select. Like I had pointed out ctas with parallel clause with a sequence.nextval in select is generating ORA-03113: end-of-file on communication channel error.

Therefore to avoid having a sequence.nextval in the select of ctas, I was wondering if that column could be added to the external table definition itself.

So, just to be clear - is it true that SEQUENCE parameter
(and not the sequence object) does not apply to external tables ? I was probably misled by it's mention in Oracle manuals as mentioned below in my original post ...

Thanks,

Gunjeet

Tom Kyte
December 21, 2004 - 7:31 pm UTC

I thought I answered that?

external tables <> control files

they are close, but they are not the same. you use a SEQUENCE (create sequence) in external tables.


You MUST be using insert/select -- or you won't be worrying about how to create an external table!!!!!! think about it, the only way to process an ET-- select, the only way to get the ET from outside the database to the inside? INSERT/create table as select.


If you are getting a 3113 -- please contact support, really.

sequence & external table

Gunjeet Singh, December 22, 2004 - 1:47 pm UTC


Hi Tom,

Thanks for the clarification.

BTW, the reason I had asked this question in the first place was because of the following text :

------------------------------------------------------------
Oracle 9i Database Utilities
Chapter 11 : External Tables Concepts
Rejected Rows

With SQL*Loader, if the SEQUENCE parameter is used and there are rejected rows, the rejected row still updates the sequence number value. With external tables, if the SEQUENCE parameter is used, rejected rows do not update the sequence number value. For example, suppose you load 5 rows with sequence numbers beginning with 1 and incrementing by 1. In SQL*Loader, if rows 2 and 4 are rejected, the successfully loaded rows are assigned the sequence numbers 1, 3, and 5. In an external table load, the successfully loaded rows are assigned the sequence numbers 1, 2, and 3.

------------------------------------------------------------

Thanks,

Gunjeet

Tom Kyte
December 22, 2004 - 1:59 pm UTC

that is because sequence.nextval never gets invoked.

External table definition cannot use the SEQUENCE parameter

Ed Eaglehouse, November 07, 2006 - 12:34 pm UTC

I ran into the same problem. The documentation implies you can use the SEQUENCE _parameter_, but in fact the database (at least 9i) does not allow it. I searched for many hours on the Web, through Oracle documentation, and by experimenting with different keywords.

The documentation lies. You can use it in a SQLLDR definition, but not in an external table definition.

The simplest answer would have been: "No, you cannot use the SEQUENCE parameter in an external table; create a SEQUENCE object instead."

Reset the sequence object before you execute your SELECT.

More to Explore

Hints

Need more information on hints? Check out the complete hint descriptions