Showing posts with label External Table. Show all posts
Showing posts with label External Table. Show all posts

Wednesday, July 21, 2010

ORA-29913, ORA-29400, KUP-00554 while querying external table

Problem Description
While querying an external table it fails with error ORA-29913, ORA-29400, KUP-00554, KUP-01005 like below.
SQL> create directory ext_dir as 'c:\';

Directory created.

SQL> create table external_table(
2 col1 varchar2(1),
3 col2 varchar2(20),
4 col3 varchar2(10)
5 )
6 organization external
7 (type oracle_loader
8 default directory ext_dir
9 access parameters
10 (
11 records delimited by newline
12 fields
13 missing field value are null
14 (col1 position(1,1),
15 col2 position(2,20),
16 col3 position(21,30)
17 )
18 )
19 location ('c:\temp\TEST.TXT')
20 )
21 ;

Table created.

SQL> select * from external_table;
select * from external_table
*
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: "values"
KUP-01008: the bad identifier was: value
KUP-01007: at line 3 column 15

Cause of the Problem
While creating external table the access parameters are not parsed. The access parameters are parsed when the external table is queried. The above errors are returned due to syntax error in the external table access parameters.

Solution of the Problem
The solution is correct the syntax in the external table creation access parameters. Let's try to solve syntax error one by one.

- Drop the table as in the database two tables as same name under one schema can't exist.

SQL> drop table external_table;

Table dropped.
- Write the previous external table creation script.
SQL> create table external_table(
2 col1 varchar2(1),
3 col2 varchar2(20),
4 col3 varchar2(10)
5 )
6 organization external
7 (type oracle_loader
8 default directory ext_dir
9 access parameters
10 (
11 records delimited by newline
12 fields
13 missing field value are null
14 (col1 position(1,1),
15 col2 position(2,20),
16 col3 position(21,30)
17 )
18 )
19 location ('c:\temp\TEST.TXT')
20 )
21
- At line 13 the keyword will be values.
SQL> 13
13* missing field value are null
SQL> c/value/values
13* missing field values are null
- At line 14, 15 and 16 position value comma (,) will be replaced by colon (:).
SQL> 14
14* (col1 position(1,1),
SQL> c/1,1/1:1
14* (col1 position(1:1),
SQL> 15
15* col2 position(2,20),
SQL> c/2,20/2:20
15* col2 position(2:20),
SQL> 16
16* col3 position(21,30)
SQL> c/21,30/21:30
16* col3 position(21:30)
SQL> /

Table created.
- Now selecting the table avoid any syntax type errors but it lead to another error related to path. In the external table we can't specify absolute path in this way. So in the following example we are correcting that.
SQL> select * from external_table;
select * from external_table
*
ERROR at line 1:
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-04076: file name cannot contain a path specification: c:\temp\TEST.TXT

SQL> drop table external_table;

Table dropped.
- Creating external table after correcting path.

SQL> create table external_table(
2 col1 varchar2(1),
3 col2 varchar2(20),
4 col3 varchar2(10)
5 )
6 organization external
7 (type oracle_loader
8 default directory ext_dir
9 access parameters
10 (
11 records delimited by newline
12 fields
13 missing field values are null
14 (col1 position(1:1),
15 col2 position(2:20),
16 col3 position(21:30)
17 )
18 )
19 location ('test.txt')
20 );

Table created.

SQL> select * from external_table;

C COL2 COL3
- -------------------- ----------
1 222222222222222222 2 11111111
1 222255555555555222 2 11111333

Friday, August 15, 2008

How to load data using external table into oracle database

Using SQL*Loader we can load data from flat data file to oracle database which is described in How to load data using sql*loader into oracle database. The external tables feature is a complement to existing SQL*Loader functionality.

In the following section, I will show with an example of how you can load data using external table.

1)Prepare your data file.
This file is where my input data is which will be loaded to database table. Here my datafile data.dat.txt is as follows,
045 Faruk
012 Arju
022 Momin

2)Create the database directory where data file resides.
This data file is not oracle data file rather it is the file where data resides. This oracle database directory is just a operating system path synonym. This directory is the logical path of physical datafile path. As my data file is in the directory c:\oracle\data\ so I create the directory as

SQL> create directory exter_dir as 'E:\oracle\work';

Directory created.

Note that user must have grant create any directory privilege. If other user create the directory then current user must have read access to the directory.
SQL> GRANT READ ON DIRECTORY exter_dir TO Arju;
Here current user is Arju. So execute above statement with a user that have privilege.

3)Prepare the original Table: You should ignore this step if your desired table already exist in your database. If not exist then create a new one. I created as,

SQL> create table std_name (id varchar2(10), name varchar2(20));
Table created.

4)Create the external table: I created the external table as,
SQL> create table external_tab(id char(4),
name char(10))
organization external
(default directory exter_dir
ACCESS parameters
(records delimited by newline
fields (id char(4), name char(10)
)
)
location ('data.dat.txt')
);


Table created.

Here "organizational external" indicates this one is external table.
"default directory" indicates the name of the directory where data file resides.
"location" indicates the name of the data file.

In this phase data from the data file is loaded into the external table. You can check whether it is successfully load or not by issuing,
SQL> select * from external_tab;
ID NAME
---- ----------
045 Faruk
012 Arju
022 Momin

5) Load the data from the external table to database table:
Load data from external_tab into the table std_name by,

SQL> insert into std_name select * from external_tab;
3 rows created.

SQL> commit;
Commit complete
.

6)Test the data.
SQL> select * from std_name;

ID NAME
---------- --------------------
045 Faruk
012 Arju
022 Momin