Cannot read external table or read using utl_file.get_line on Windows 10 with Oracle 18c - oracle

I just upgraded to Oracle 18c XE from 11g. I have an external table that worked fine on 11g, but I keep getting the following errors on 18c.
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-11604: no directory object specified for log file
The directory does exist and I have the correct grants.
SELECT *
FROM all_directories
WHERE directory_name = 'MYDIR';
OWNER DIRECTORY_NAME DIRECTORY_PATH ORIGIN_CON_ID
SYS MYDIR C:\Users\sneuf\OneDrive\PLSQL\OracleDirectory 1
I have the required privileges.
SELECT *
FROM all_tab_privs
WHERE table_name = 'MYDIR'
AND grantee = 'C##_SNEUF';
GRANTOR GRANTEE TABLE_SCHEMA TABLE_NAME PRIVILEGE GRANTABLE HIERARCHY COMMON TYPE INHERITED
SYS C##_SNEUF SYS MYDIR EXECUTE YES NO NO DIRECTORY NO
SYS C##_SNEUF SYS MYDIR READ YES NO NO DIRECTORY NO
SYS C##_SNEUF SYS MYDIR WRITE YES NO NO DIRECTORY NO
I'm pretty sure I'm missing a grant somewhere, but I can't figure out what. Can someone please help?
Here is my table:
CREATE TABLE C##_SNEUF.CHECKING_TBL_EXT2
(
DB_KEY NUMBER,
CHECK_NUM VARCHAR2(10),
TRANS_DATE TIMESTAMP (6),
DESCRIPTION VARCHAR2(100),
DEPOSIT_WITHDRAWAL VARCHAR2(1),
AMOUNT VARCHAR2(12),
MEMO VARCHAR2(200)
)
ORGANIZATION EXTERNAL
( TYPE ORACLE_LOADER
DEFAULT DIRECTORY MYDIR
ACCESS PARAMETERS
( RECORDS DELIMITED BY NEWLINE
BADFILE MYDIR: 'checking.bad'
FIELDS TERMINATED BY ","
OPTIONALLY ENCLOSED BY '"'
LDRTRIM
MISSING FIELD VALUES ARE NULL
(
DB_key CHAR,
check_num CHAR(10),
trans_date CHAR(21) DATE_FORMAT DATE MASK 'MM/DD/YYYY HH24:MI:SS',
description CHAR(100),
deposit_withdrawal CHAR(1),
amount CHAR(12),
memo CHAR(200)
)
)
LOCATION
( MYDIR: 'checking.csv'
)
)
REJECT LIMIT UNLIMITED ;
Thanks,
Steve

Logfile isn't specified, so - by default - it resides in the same directory as the data file.
However, as you write to log file, you require write privilege on the MYDIR directory. Info you posted suggests that you have only READ privilege so - grant WRITE as well.

Related

Oracle External Table - No Rows Selected

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!!

SPOOL in Oracle

I have this table and sample data which I want to spool in a file.
I'm not sure what is the right way to do or the syntax. I tried few ways from internet but couldn't get the right answer.
CREATE TABLE RoomType
(
RoomType Varchar2(25),
RoomTypeDesc Varchar2(50)
);
INSERT INTO RoomType VALUES ('STD', 'Standard Room');
INSERT INTO RoomType VALUES ('Business', 'Business Class');
SPOOL path/file/to/save/log.log(or txt)
PROMPT ************************************
PROMPT *** CREATION OF OBJECTS ***
PROMPT ************************************
CREATE TABLE RoomType
(
RoomType Varchar2(25),
RoomTypeDesc Varchar2(50)
);
PROMPT ************************************
PROMPT *** INSERTION ***
PROMPT ************************************
INSERT INTO RoomType VALUES (STD, 'Standard Room');
INSERT INTO RoomType VALUES (Business, 'Business Class');
Save your commands in a file with your favourite editor( like vi ), in your favourite path( let's take /home/oracle/scripts ) as a .sql file :
[oracle#DoonieDB scripts]$ vi RoomTypes.sql
set term[out] off
set feed[back] off
col RoomType format a25
col RoomTypeDesc format a25
spool /home/oracle/scripts/RoomTypes.txt
select * from RoomType;
spool off;
where col setting are used to restrict the length of the columns to keep them in single line.
Connect to your related schema and call your .sql by prefixing with a # sign and get RoomTypes.txt file with formatted info :
[oracle#DoonieDB scripts]$ pwd
/home/oracle/scripts
[oracle#DoonieDB scripts]$ sqlplus hotels/myKey
...
Connected to:
Oracle Database xxx Enterprise Edition Release 1x.x.x.x.x - 64bit Production
SQL> #RoomTypes.sql
SQL> exit
Disconnected from Oracle Database xxx Enterprise Edition Release 1x.x.x.x.x - 64bit Production
[oracle#barbdb12c scripts]$ cat RoomTypes.txt
ROOMTYPE ROOMTYPEDESC
------------------------- -------------------------
STD Standard Room
Business Business Class

How to use expdp dumpfile as external oracle_datapump

I couldn't use dump expdp output file in to external table with access driver.
Is it possible to use expdp output file in to external table?
Is there any special solution for this case or the structure is so different?
script :
CREATE TABLE item_import (
item_id NUMBER
, item_barcode VARCHAR2(20)
, item_type NUMBER
, item_title VARCHAR2(60)
, item_subtitle VARCHAR2(60)
, item_rating VARCHAR2(8)
, item_rating_agency VARCHAR2(4)
, item_release_date DATE
, created_by NUMBER
, creation_date DATE
, last_updated_by NUMBER
, last_update_date DATE)
ORGANIZATION EXTERNAL
( TYPE oracle_datapump
DEFAULT DIRECTORY "download"
LOCATION ('item_export.dmp')
);
ERROR at line 1:
ORA-29913: error IN executing ODCIEXTTABLEOPEN callout
seems that you wrong the table definition.
Try the following:
CREATE TABLE inventories_xt
ORGANIZATION EXTERNAL
(
TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY def_dir1
LOCATION ('inv_xt.dmp')
)
AS SELECT * FROM inventories;
Pls. Review the following:
The ORACLE_DATAPUMP Access Driver

Oracle 10G external table error

I have created the following external table on Oracle 10G.
connect system/password as SYSDBA
create or replace directory ext_tab as 'C:\Suman\External_Tables';
CREATE TABLE emp_ext_3(
empno NUMBER(4), first_name CHAR(20), last_name CHAR(20), dob CHAR(10))
ORGANIZATION EXTERNAL(
TYPE ORACLE_LOADER DEFAULT DIRECTORY ext_tab
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE
NOBADFILE
NOLOGFILE
SKIP 1
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LRTRIM
MISSING FIELD VALUES ARE NULL
REJECT ROWS WITH ALL NULL FIELDS
(empno INTEGER EXTERNAL (4),
first_name CHAR(20),
last_name CHAR(20),
dob CHAR(10) DATE_FORMAT DATE MASK "dd/mm/yyyy")
)
LOCATION ('employee1.dat')
)
PARALLEL
REJECT LIMIT 0;
Now If I try to execute select command, I am getting following error.
SQL> select * from "SYSTEM"."EMP_EXT_3";
select * from "SYSTEM"."EMP_EXT_3"
*
ERROR at line 1:
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-04040: file employee1.dat in EXT_TAB not found
ORA-06512: at "SYS.ORACLE_LOADER", line 19
But I have the file "employee1.dat" in 'C:\Suman\External_Tables'. Can someone please help me on why I am getting this error?
The Oracle server is looking for a file in the following location: 'C:\Suman\External_Tables'. That directory is on the Oracle server machine, not your local Windows client machine.

How to query the permissions on an Oracle directory?

I have a directory in all_directories, but I need to find out what permissions are associated with it, i.e. what has been granted on it?
This should give you the roles, users and permissions granted on a directory:
SELECT *
FROM all_tab_privs
WHERE table_name = 'your_directory'; --> needs to be upper case
And yes, it IS in the all_TAB_privs view ;-) A better name for that view would be something like "ALL_OBJECT_PRIVS", since it also includes PL/SQL objects and their execute permissions as well.
You can see all the privileges for all directories wit the following
SELECT *
from all_tab_privs
where table_name in
(select directory_name
from dba_directories);
The following gives you the sql statements to grant the privileges should you need to backup what you've done or something
select 'Grant '||privilege||' on directory '||table_schema||'.'||table_name||' to '||grantee
from all_tab_privs
where table_name in (select directory_name from dba_directories);
Wasn't sure if you meant which Oracle users can read\write with the directory or the correlation of the permissions between Oracle Directory Object and the underlying Operating System Directory.
As DCookie has covered the Oracle side of the fence, the following is taken from the Oracle documentation found here.
Privileges granted for the directory
are created independently of the
permissions defined for the operating
system directory, and the two may or
may not correspond exactly. For
example, an error occurs if sample
user hr is granted READ privilege on
the directory object but the
corresponding operating system
directory does not have READ
permission defined for Oracle Database
processes.
With Oracle 11g R2 (at least with 11.2.02) there is a view named datapump_dir_objs.
SELECT * FROM datapump_dir_objs;
The view shows the NAME of the directory object, the PATH as well as READ and WRITE permissions for the currently connected user. It does not show any directory objects which the current user has no permission to read from or write to, though.
Expanding on this a bit, this script will allow you to see the privileges for any object type and name that appears in all_tab_privs.
/*
usage: #obj-privs <object-type> <object-name>
object-type can be any type of object; table, directory, index, etc.
case does not matter
object-name can be any legal name - case matters
Wild cards work for both object-type and object-name
#obj-privs dir% MYDIR
#obj-privs table INV%
#obj-privs synonym %
*/
set pagesize 100
set linesize 200 trimspool off
col grantor format a15
col grantee format a30
col table_schema format a30 head 'OWNER'
col table_name format a30 head 'OBJECT_NAME'
col privilege format a15
col v_object_name new_value v_object_name noprint
col v_object_type new_value v_object_type noprint
set feed off term off echo off pause off verify off
select upper('&1') v_object_type from dual;
select '&2' v_object_name from dual;
set feed on term on feed on
select
p.table_name
, p.table_schema
, p.privilege
, p.grantee
, p.grantor
, o.object_type
from all_tab_privs p
join all_objects o on o.owner = p.table_schema
and o.object_name = p.table_name
and p.table_name like '&v_object_name'
and o.object_type like '&v_object_type'
order by p.table_name, p.table_schema, p.grantee
/
Here is an example for directories:
SQL# #obj-privs dir% %
OBJECT_NAME OWNER PRIVILEGE GRANTEE GRANTOR OBJECT_TYPE
------------------------------ ------------------------------ --------------- ------------------------------ --------------- ---------------------------------------------------------------------
DATA_PUMP_DIR SYS WRITE EXP_FULL_DATABASE SYS DIRECTORY
DATA_PUMP_DIR SYS READ EXP_FULL_DATABASE SYS DIRECTORY
DATA_PUMP_DIR SYS WRITE IMP_FULL_DATABASE SYS DIRECTORY
DATA_PUMP_DIR SYS READ IMP_FULL_DATABASE SYS DIRECTORY
ORACLE_OCM_CONFIG_DIR SYS READ ORACLE_OCM SYS DIRECTORY
ORACLE_OCM_CONFIG_DIR SYS WRITE ORACLE_OCM SYS DIRECTORY
ORACLE_OCM_CONFIG_DIR2 SYS WRITE ORACLE_OCM SYS DIRECTORY
ORACLE_OCM_CONFIG_DIR2 SYS READ ORACLE_OCM SYS DIRECTORY
8 rows selected.
Here is another for tables with USER in the name:
SQL# #obj-privs tab% %USER%
OBJECT_NAME OWNER PRIVILEGE GRANTEE GRANTOR OBJECT_TYPE
------------------------------ ------------------------------ --------------- ------------------------------ --------------- ---------------------------------------------------------------------
BDSQL_USER_MAP SYS INSERT BDSQL_ADMIN SYS TABLE
BDSQL_USER_MAP SYS DELETE BDSQL_ADMIN SYS TABLE
BDSQL_USER_MAP SYS SELECT BDSQL_ADMIN SYS TABLE
BDSQL_USER_MAP SYS READ BDSQL_USER SYS TABLE
KU$_USER_MAPPING_VIEW_TBL SYS SELECT SELECT_CATALOG_ROLE SYS TABLE
SDO_PREFERRED_OPS_USER MDSYS UPDATE PUBLIC MDSYS TABLE
SDO_PREFERRED_OPS_USER MDSYS INSERT PUBLIC MDSYS TABLE
SDO_PREFERRED_OPS_USER MDSYS SELECT PUBLIC MDSYS TABLE
SDO_PREFERRED_OPS_USER MDSYS DELETE PUBLIC MDSYS TABLE
USER_PRIVILEGE_MAP SYS READ PUBLIC SYS TABLE
10 rows selected.

Resources