Oracle: Inserting into table error - either duplicate column name or invalid datatype
-
06-03-2021 - |
Question
I'm trying to insert data from an external table.
INSERT /*+ ignore_row_on_dupkey_index ( consruct ( construct_id ) ) */
INTO construct
(construct_id,
n_term ,
enz_name,
c_term,
cpp,
mutations,
mw_kda)
SELECT *
FROM EXTERNAL ((
construct_id NUMBER(10),
n_term VARCHAR2 (50),
enz_name VARCHAR2 (50),
c_term VARCHAR2 (50),
cpp VARCHAR2 (50),
mutations VARCHAR2 (50),
mw_kda NUMBER (7,3))
TYPE ORACLE_LOADER
DEFAULT DIRECTORY data_to_input
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
SKIP 1
BADFILE bad_files:'badflie_insert_into_construct_from_construct.bad'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
MISSING FIELD VALUES ARE NULL
)
LOCATION ('CONSTRUCT.CSV')
REJECT LIMIT UNLIMITED) ext
WHERE NOT EXISTS (
SELECT * FROM construct c
WHERE c.n_term = ext.n_term
AND c.enz_name = ext.enz_name
AND c.c_term = ext.c_term
AND c.cpp = ext.cpp
AND c.mutations = ext.mutations
);
But now i get this error:
Error at Command Line : 171 Column : 7
Error report -
SQL Error: ORA-00957: duplicate column name
00957. 00000 - "duplicate column name"
Line 171 is the last line of this part
INSERT /*+ ignore_row_on_dupkey_index ( consruct ( construct_id ) ) */
INTO construct
(construct_id,
n_term ,
enz_name,
c_term,
cpp,
mutations,
mw_kda)
Which is clearly not a duplicate column.
If I do:
INSERT /*+ ignore_row_on_dupkey_index ( consruct ( construct_id ) ) */
INTO construct
(construct_id,
n_term,
enz_name,
c_term,
cpp,
mutations,
mw_kda)
SELECT *
FROM EXTERNAL ((
ext.construct_id NUMBER (10),
ext.n_term VARCHAR2 (50),
ext.enz_name VARCHAR2 (50),
ext.c_term VARCHAR2 (50),
ext.cpp VARCHAR2 (50),
ext.mutations VARCHAR2 (50),
ext.mw_kda NUMBER (7,3))
TYPE ORACLE_LOADER
DEFAULT DIRECTORY data_to_input
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
SKIP 1
BADFILE bad_files:'badflie_insert_into_construct_from_construct.bad'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
MISSING FIELD VALUES ARE NULL
)
LOCATION ('CONSTRUCT.CSV')
REJECT LIMIT UNLIMITED) ext
WHERE NOT EXISTS (
SELECT * FROM construct c
WHERE c.n_term = ext.n_term
AND c.enz_name = ext.enz_name
AND c.c_term = ext.c_term
AND c.cpp = ext.cpp
AND c.mutations = ext.mutations
);
I get
Error at Command Line : 174 Column : 10
Error report -
SQL Error: ORA-00902: invalid datatype
00902. 00000 - "invalid datatype"
Line 171 is ext.construct_id NUMBER (10),
Solution
External table name is construct_ext
CREATE TABLE construct_ext
( construct_id NUMBER (10),
n_term VARCHAR2 (50),
enz_name VARCHAR2 (50),
c_term VARCHAR2 (50),
cpp VARCHAR2 (50),
mutations VARCHAR2 (50),
mw_kda NUMBER (7,3)
)
ORGANIZATION EXTERNAL
(
TYPE ORACLE_LOADER
DEFAULT DIRECTORY data_to_input
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE CHARACTERSET US7ASCII
TERRITORY AMERICA
SKIP 1
BADFILE bad_files:'badflie_insert_into_construct_from_construct.bad'
LOGFILE bad_files:'logflie_insert_into_construct_from_construct.log'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
MISSING FIELD VALUES ARE NULL
)
LOCATION ('CONSTRUCT.CSV')
) REJECT LIMIT UNLIMITED;
INSERT /*+ ignore_row_on_dupkey_index ( consruct ( construct_id ) ) */
INTO construct
(construct_id,
n_term,
enz_name,
c_term,
cpp,
mutations,
mw_kda)
SELECT
construct_id,
n_term ,
enz_name,
c_term ,
cpp ,
mutations ,
mw_kda
FROM
construct_ext ext
WHERE NOT EXISTS (
SELECT * FROM construct c
WHERE c.n_term = ext.n_term
AND c.enz_name = ext.enz_name
AND c.c_term = ext.c_term
AND c.cpp = ext.cpp
AND c.mutations = ext.mutations
);
Edit:-After creating external table verify if you're able to query the table
Edit:- As per @a_horse_with_no_name you can access external table without creating using inline external table for Database version 18c and above
The problem arises when you try to insert target table without creating external table(hope someone can shed light on this) work around is to create staging table then insert into target table
CREATE TABLE construct_stg
AS
-- select part works without creating external table
SELECT *
FROM EXTERNAL (
(
construct_id NUMBER(10),
n_term VARCHAR2 (50),
enz_name VARCHAR2 (50),
c_term VARCHAR2 (50),
cpp VARCHAR2 (50),
mutations VARCHAR2 (50),
mw_kda NUMBER (7,3)
)
TYPE ORACLE_LOADER
DEFAULT DIRECTORY data_to_import
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE CHARACTERSET US7ASCII
TERRITORY AMERICA
SKIP 1
BADFILE bad_files:'badflie_insert_into_construct_from_construct.bad'
--LOGFILE bad_files:'logflie_insert_into_construct_from_construct.log'--create different directory for log file or skip this line
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
MISSING FIELD VALUES ARE NULL
(
construct_id,
n_term ,
enz_name,
c_term ,
cpp ,
mutations ,
mw_kda
)
)
LOCATION ('CONSTRUCT.CSV')
REJECT LIMIT UNLIMITED)ext_tab;
CREATE INDEX idx_construct_id ON construct_stg(construct_id);
ALTER TABLE construct_stg ADD CONSTRAINT pk_construct_id_stg PRIMARY KEY (construct_id) USING INDEX; -- to enforce unique or skip this
INSERT /*+ ignore_row_on_dupkey_index ( consruct,idx_construct_id) */
INTO construct
(construct_id,
n_term,
enz_name,
c_term,
cpp,
mutations,
mw_kda)
SELECT
construct_id,
n_term ,
enz_name,
c_term ,
cpp ,
mutations ,
mw_kda
FROM
construct_stg ext
WHERE NOT EXISTS (
SELECT * FROM construct c
WHERE c.n_term = ext.n_term
AND c.enz_name = ext.enz_name
AND c.c_term = ext.c_term
AND c.cpp = ext.cpp
AND c.mutations = ext.mutations
);
Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange