Oracle External Table - No Rows Selected - oracle

I've created an external table using the following definition
CREATE TABLE EXT_TABLE (CID NUMBER, CNAME VARCHAR2(20), FEES NUMBER)
ORGANIZATION EXTERNAL
(
TYPE ORACLE_LOADER
DEFAULT DIRECTORY TEST_DIR
ACCESS PARAMETERS
(RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY ','
(
CID INTEGER,
CNAME CHAR(20),
FEES INTEGER
)
)
LOCATION ('DATA.TXT'))
REJECT LIMIT UNLIMITED;
table has been created. But, when i try to select data from table, I don't find any records
SQL> select * from ext_table;
no rows selected
I've made sure directory and table have sufficient privileges for the user.
The data in text file;
1,JAVA,300
2,LINUX,400
3,ORACLE,400
4,EXCEL,500

RECORD is not the keyword you should use here.
it must be RECORDS.
Use this:
RECORDS DELIMITED BY NEWLINE
Cheers!!

Related

Capture Oracle Errors in a Manually Created Table

Hi I want to capture all the Oracle Errors for my DML operations in the manually created table with columns as ErrorID and Error_Descr.
How to get ORA_ERR_NUMBER$ and ORA_ERR_MESG$ values in the above columns?
This table contains user defined errors as well so I do not want to limit it to the Oracle Errors.
Is there any way of capturing Oracle as well as User Defined Errors in the User Defined Tables?
Thanks in Advance!
As per documentation Link,
Oracle allows you to use a manually created table for LOGGING only if you have included these mandatory columns.
ORA_ERR_NUMBER$
ORA_ERR_MESG$
ORA_ERR_ROWID$
ORA_ERR_OPTYP$
ORA_ERR_TAG$
If you want other columns to capture the information in those two columns, you could make them as virtual columns.
CREATE TABLE my_log_table (
ORA_ERR_NUMBER$ NUMBER
,ORA_ERR_MESG$ VARCHAR2(2000)
,ORA_ERR_ROWID$ ROWID
,ORA_ERR_OPTYP$ VARCHAR2(2)
,ORA_ERR_TAG$ VARCHAR2(2000)
,ErrorID NUMBER AS (COALESCE(ORA_ERR_NUMBER$, ORA_ERR_NUMBER$))
,Error_Descr VARCHAR2(2000) AS (COALESCE(ORA_ERR_MESG$, ORA_ERR_MESG$))
);
using COALESCE is a hack because Oracle doesn't allow you to have one column default to another directly.
Now, you could run your error logging dml normally mentioning the logging table name.
INSERT INTO t_emp
SELECT employee_id * 10000
,first_name
,last_name
,hire_date
,salary
,department_id
FROM hr.employees
WHERE salary > 10000 LOG ERRORS
INTO my_log_table('ERR_SAL_LOAD') REJECT LIMIT 25
0 row(s) inserted.
select ORA_ERR_TAG$,ErrorID,Error_Descr FROM my_log_table ;
ORA_ERR_TAG$ ERRORID ERROR_DESCR
ERR_SAL_LOAD 1438 ORA-01438: value larger than specified precision allowed for this column
ERR_SAL_LOAD 1438 ORA-01438: value larger than specified precision allowed for this column

Oracle:inner join between file and table

I'm new to oracle and plsql, so just bear with me.
I have a file TYPES.txt,
id,name,values
1,aaa,32
2,bbb,23
3,cvv,12
4,fff,54
I also have a table in my db, PARTS.ATTRIBUTES
id,name,props,crops
1,aaa,100,zzzz
2,bbb,200,yyyy
3,cvv,300,xxxx
4,fff,400,wwww
5,sasa,343,gfgg
6,uyuy,897,hhdf
I'd like to do an INNER JOIN on the file TYPES and ATTRIBUTES based on the column name. Now, i have done this by initially loading file TYPES into a temp table and then doing INNER JOIN between the temp table and ATTRIBUTES table.
But i'd like to know whether it is possible to do INNER JOIN between TYPES file and ATTRIBUTES table without making use of a temp table.
I understand that i can load the file using and get respective rows using following script:
declare
file utl_file.file_type;
line varchar2(500);
begin
file :=utl_file.fopen('USER_DIR','TYPES.txt','r');
loop
utl_file.get_line(file ,line);
dbms_output.put_line(line);
end loop;
exception
when others then
utl_file.fclose(file);
end;
Could someone be kind enough to explain to me how i can do the join between file contents and the db table?
P.S. The file TYPES.txt is dynamically generated and can have different number of columns at different times.
One cleaner approach is to use an EXTERNAL TABLE.
Use a create statement like this to create TYPES_external table.
CREATE TABLE TYPES_external (
id NUMBER(5),
name VARCHAR2(50),
Values VARCHAR2(50)
)
ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY USER_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY ','
MISSING FIELD VALUES ARE NULL
(
id NUMBER(5),
name VARCHAR2(50),
Values VARCHAR2(50)
)
)
LOCATION ('TYPES.txt','TYPES.txt')
)
PARALLEL 5
REJECT LIMIT UNLIMITED;
Once created , you can use this external table(TYPES_external) just as you
use any database table for select operation.

Oracle SQL Loader - How to do field count check and reject records?

Oracle Table Structure.
create table EmployeeTemp
(
Name VARCHAR2(80) NOT NULL,
Age NUMBER(3),
Gender VARCHAR2(10)
);
SQL Loader Control File
LOAD DATA
REPLACE
INTO TABLE EmployeeTemp
FIELDS TERMINATED BY "|" OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS
(
Name CHAR(80),
Age INTEGER EXTERNAL,
Gender CHAR(10)
)
Data File:
John Williams|23|Male
Caser|78|
Brit
Sam|34||extrafield
How to reject a record which has has more fields or fewer fields in data file compared to the number of fields in Database table?
In the data file example:
Record 'Sam' need to be rejected as it has 4th field (Extra field ).
Record 'Brit' need to be rejected as it has not passed null or empty value for Gender field. ( Having fewer field information)
'John Williams' & 'Caser' record has either data or null/empty values for all 3 fields is provided. So they should not be rejected.
Please suggest how to achieve my requirement and what changes needed in the Oracle SQL loader Control file (As I don't have option to change table structure to make Age and Gender field as not null)?

Loading data in external table SQLLoader

I want to crate external table based on datafile, but I got error. I use whitespace to delimit my record but this doesn't work . Yes I created directory and gave read and write permissions than I created my external table . However when I selected it I got an error:
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
My external table is :
create table nflteams_ext (
ACR varchar2(4),
NAME varchar2(20))
organization external
(
type oracle_loader
default directory ext_tab_data
access parameters (
records delimited by newline CHARACTERSET US7ASCII
fields terminated by whitespace
missing field values are null
(ACR varchar2(4),
NAME varchar2(20))
)
LOCATION ('NFL_Teams.dat')
)
REJECT LIMIT UNLIMITED NOPARALLEL;
data file:
NO New Orleans Saints
PIT Pittsburgh Steelers
IND Indianapolis Colts
The problem is solved . I used char instead of varchar2 in the lower section of my external tablecreation also I delimeted by '/n'.
CREATE TABLE nflteams_ext
(acr VARCHAR2( 4),
name VARCHAR2(20))
ORGANIZATION EXTERNAL
(TYPE ORACLE_LOADER
DEFAULT DIRECTORY ext_tab_data
ACCESS PARAMETERS
(RECORDS DELIMITED BY NEWLINE CHARACTERSET US7ASCII
FIELDS TERMINATED BY WHITESPACE
MISSING FIELD VALUES ARE NULL
(acr CHAR( 4),
name CHAR(20) TERMINATED BY '/n'))
LOCATION ('NFL_Teams.dat'))
REJECT LIMIT UNLIMITED
NOPARALLEL
/
SELECT * FROM nflteams_ext
2 /
ACR NAME
NO New Orleans Saints
PIT Pittsburgh Steelers
IND Indianapolis Colts
3 rows selected.

Oracle external tables

I'm struggling with an Oracle external table, although I researched the Oracle forums. Still, no success.
Let's suppose I have a simple table
DESCRIBE PRODUCTS
Name Null Type
------------------------------ -------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID NOT NULL NUMBER
NAME VARCHAR2(30)
VALUE NUMBER(5,2)
DEP VARCHAR2(30)
COUNT NUMBER(3)
Then, I created an oracle folder:
CREATE OR REPLACE DIRECTORY ext_prod_dir AS 'c:\';
I save the content of that table in a .lst file
spool c:\products.lst
select p.id || ';' || p.name || ';' || p.value || ';' || p.dep || ';' || p.count FROM products p;
spool off;
P.ID||';'||P.NAME||';'||P.VALUE||';'||P.DEP||';'||P.COUNT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1;Settlers of Catan;29,95;Toys;3
2;DVD Player;82,97;Electronics;2
3;Red Shirt;12,49;Clothes;3
4;Black Leather Couch;399,99;Furniture;5
5;Oak Cofee Table;223,99;Furniture;5
6;Technodrome;27,99;Toys;4
7;Oh Cereal;3,95;Foods;1
8;Game Console;299,95;Toys;2
9;Video Game;29,95;Toys;3
10;Lawn Chair;34,99;Furniture;11
11;Dog Toy Bone;34,99;Toys;9
12;Heated Blanket;27,95;Toys;8
13;Flux Capacitor;27,95;Toys;7
14;Chocolate Pie;3,14;Foods;7
Then I tried to create the external table:
CREATE TABLE products_ext
(ID NUMBER,
NAME VARCHAR2(30),
VALUE NUMBER(5,2),
DEP VARCHAR2(30),
COUNT NUMBER(3))
ORGANIZATION EXTERNAL
(TYPE oracle_loader DEFAULT DIRECTORY ext_prod_dir
ACCESS PARAMETERS
(RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY ';'
MISSING FIELD VALUES ARE NULL
BADFILE ext_prod_dir:'products.bad_xt'
LOGFILE ext_prod_dir:'products.log_xt'
(ID CHAR(6),
NAME CHAR(30),
VALUE CHAR(8),
DEP CHAR(30),
COUNT CHAR(3)))
location ('products.lst')
) REJECT LIMIT UNLIMITED
So far so good. Then when I select data from the external table, I got:
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-00554: error encontered while parsing access parameters
KUP-01005: syntax error: found "badfile": expecting one of: "column (,reject"
KUP-01007: at line 4 column 7
I tried a huge amount of things, but I got variations on this error. Best thing I accomplished was that I got rid of error, but the table was empty. I would be very much indebted If someone with more experience can point me in the right direction.
BADFILE and LOGFILE are not part of the FIELDS clause. So, move them above the FIELDS TERMINATED.
CREATE TABLE products_ext
(ID NUMBER,
NAME VARCHAR2(30),
VALUE NUMBER(5,2),
DEP VARCHAR2(30),
COUNT NUMBER(3))
ORGANIZATION EXTERNAL
(TYPE oracle_loader DEFAULT DIRECTORY ext_prod_dir
ACCESS PARAMETERS
(RECORDS DELIMITED BY NEWLINE
BADFILE ext_prod_dir:'products.bad_xt'
LOGFILE ext_prod_dir:'products.log_xt'
FIELDS TERMINATED BY ';'
MISSING FIELD VALUES ARE NULL
(ID CHAR(6),
NAME CHAR(30),
VALUE CHAR(8),
DEP CHAR(30),
COUNT CHAR(3)))
LOCATION ('products.lst')
) REJECT LIMIT UNLIMITED
Also, you said when you got rid of the error, the table was empty. Did you check the logfile? If the error is with the VALUE column, then check NLS_NUMERIC_CHARACTERS parameter
in view v$nls_parameters.
select * from v$nls_parameters;
Check if the decimal marker is indeed a comma. If not either update this parameter or change it in the data file.

Resources