SQL* Loader Handling formatted dates - sql

I'm developing this solution where I'll receive a spool file and I need to insert it to a table.
I always use SQL* Loader and it fits well. But I never used it with dates. I'm getting this error as I'll show:
Control File
OPTIONS (ERRORS=999999999, ROWS=999999999)
load data
infile 'spool.csv'
append
into table A_CONTROL
fields terminated by ","
TRAILING NULLCOLS
(
AStatus,
ASystem,
ADate,
AUser,
)
spool.csv
foo,bar,2015/01/12 13:22:21,User
But when I run the loader I got this error
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
AStatus FIRST * , CHARACTER
ASystem NEXT * , CHARACTER
ADate NEXT * , CHARACTER
AUser NEXT * , CHARACTER
Record 1: Rejected - Error on table A_CONTROL, column ADate.
ORA-01861: literal does not match format string
Table A_CONTROL:
0 Rows successfully loaded.
1 Row not loaded due to data errors.
0 Rows not loaded because all WHEN clauses were failed.
0 Rows not loaded because all fields were null.

Convert the string to date for insertion.
OPTIONS (ERRORS=999999999, ROWS=999999999)
load data
infile 'spool.csv'
append
into table A_CONTROL
fields terminated by ","
TRAILING NULLCOLS
(
AStatus,
ASystem,
ADate "TO_DATE(:ADate,'YYYY/MM/DD HH24:MI:SS')",
AUser,
)

Related

Oracle convert column which is varchar / hex to numeric format after loading data from xlsx file

I loaded an Excel file into a table and found out that some data in my varchar2 field is in HEX format.
When I execute my query, I have no problem, but when I try to insert my data into another table with a number format it does not work.
This query shows which column is in HEX format :
SELECT qty, TO_NUMBER(REPLACE(qty, CHR(32), '')) as nbkg, RAWTOHEX(qty) as Graphics
FROM (
SELECT nvl(qty, 0) AS qty,
case
when pkg_tools.f_is_number(qty) = 1 then 'OK'
else 'NOK'
end kg
FROM table
)
WHERE kg = 'NOK';
*qty is a varchar2(50)
My output :
qty nbkg Graphics
--- ---- --------
10 009,000 10009,000 3130203030392C303030 -- work
3 250,00 3250,00 33203235302C3030 -- work
1 000,00 1000,00 31203030302C3030 -- work
1 230,00 1 230,00 31A03233302C3030 -- Not work
1 750,00 1 750,00 31A03735302C3030 -- Not work
4 000,00 4 000,00 34A03030302C3030 -- Not work
1 980,00 1 980,00 31A03938302C3030 -- Not work
1 050,00 1 050,00 31A03035302C3030 -- Not work
1 050,00 1 050,00 31A03035302C3030 -- Not work
1 000,00 1 000,00 31A03030302C3030 -- Not work
39 950,00 39 950,00 3339A03935302C3030 -- Not work
3 000,00 3 000,00 33A03030302C3030
...
...
I am trying to convert it into a number before inserting my data :
SELECT TO_NUMBER(REPLACE(qty, CHR(32), ''))
FROM table;
SELECT TO_NUMBER(REGEXP_REPLACE(qty, '\s'))
FROM table;
and I am getting an error :
ORA-01722: invalid number
How can i convert this column which is varchar / hex to numeric format?
Thank you.
add a Format mask and NLS information by using to_number function.
so it could look like:
select to_number('1 250,000','999G999G999D99999','NLS_NUMERIC_CHARACTERS='', ''') as n
from dual
if you check the hex value e.g. 31A03030302C3030 you can see the A0 on the second Position. that is displayed as empty string but is and not a space that has a hex Position 20 in ASCII table. So just replace that 160 with 32
to_number(replace('1 250,000',chr(160),chr(32)),'999G999G999D99999','NLS_NUMERIC_CHARACTERS='', ''') as n
result:
n
------
1250

ÿ is not displaying while concatenate with other column in oracle

I have a problem regarding a special character. I have a table test as below:
SQL> desc test
Name Type Nullable Default Comments
-------------- ----------------- -------- ------- --------
DOT DATE Y
LOWVAL_CHAR VARCHAR2(3) Y
I am inserting data in this table using sqlldr. The data file is as below:
1984/01/10ÿ:-1 0 -99999+99999Sourav Bhattacharya
ctl file is as below:
LOAD DATA
CHARACTERSET AL32UTF8
APPEND
PRESERVE BLANKS
INTO TABLE TEST
(dot POSITION(1) CHAR(10) "TO_DATE(:DOT,'YYYY/MM/DD')",
lowval_char POSITION(11) CHAR(1),
highval_char POSITION(12) CHAR(1),
lowval_un_num POSITION(13) INTEGER EXTERNAL(6),
highval_un_num POSITION(19) INTEGER EXTERNAL(6),
lowval_si_num POSITION(25) INTEGER EXTERNAL(6),
highval_si_num POSITION(31) INTEGER EXTERNAL(6),
fn POSITION(37) CHAR(10),
mn POSITION(47) CHAR(5),
ln POSITION(52) CHAR(20)
)
Data got inserted correctly.
Now if I execute the query
select dot,lowval_char from test;
It is giving me correct result but if I concatenate i.e
select dot||lowval_char from test;
ÿ is not displaying, only the dot value is visible.
If I do not use SQL loader and do any insert into it is giving correct result for both the cases.
Settings:
character set is AL32UTF8
nls_language='AMERICAN'
NLS_LENGTH_SEMANTICS='BYTE'

Import csv date changes to 0000-00-00

LOAD DATA INFILE 'filename.csv' INTO TABLE table_name
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n' IGNORE 1 LINES
(Date,col2,col3,col4,col5,col6,col7,#dummy_variable)
Set dummy_variable = 0
Loads fine but date format shows reads 0000-00-00
Date in csv is in the style dd/mm/yyyy, can't be changed in csv file.
You need to adjust the date to a mysql format with str_to_date
Something like below should work.
LOAD DATA INFILE 'filename.csv' INTO TABLE table_name
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n' IGNORE 1 LINES
(#myDate,col2,col3,col4,col5,col6,col7,#dummy_variable)
Set dummy_variable = 0, Date = str_to_date(#myDate,'%d/%m/%Y')

update varchar field ; Diffrence between using single quotes and with out using

I am using Teradata as database,
Table
sno varchar(10) primary,
number varchar(10)
I was able to update number field like this
update ...
set number = '1'
or
set number = 1
I was able to get correct result in my select query [ had max(number) column ],when I updated second way i.e set number = 1 with out using any cast functions.
using this (i.e set number = '1' ) gives me the wrong result with my select query, with out
using cast functions
can any one explain the difference?
In short , I need difference between
update ...
set number = '1'
or
set number = 1
set number = 1
updates the VARCHAR to '1'
set number = 1
does an automatic Teradata style typecast (right aligned within FORMAT) and sets number to ' 1'.
SELECT (1 (VARCHAR(10))) || '#', FORMAT(1), TYPE(1);
*** Query completed. One row found. 3 columns returned.
*** Total elapsed time was 1 second.
(1||'#') Format(1) Type(1)
----------- ------------------------------ -------------
1# -(3)9 BYTEINT
What do you expect when you query MAX(col)?
For VarChars '9' is greater than '11', if you need numeric comparison you should use a numeric datatype.

LOAD DATA INFILE (*.csv) - ignore empty cells

I'm about to import a large (500 MB) *.csv file to a MySQL database.
I'm as far as that:
LOAD DATA INFILE '<file>'
REPLACE
INTO TABLE <table-name>
FIELDS
TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '"'
IGNORE 1 LINES ( #Header
<column-name1>,
<column-name2>,
...
);
I have a problem with one of the coluns (it's data type is int) - I get an error Message:
Error Code: 1366 Incorrect integer value: ' ' for column at row
I looked at this line in the *.csv-file. The cell that causes the error has just a whitespace inside (like this: ...; ;...).
How can I tell SQL to ignore whitespaces in this column?
As the *.csv-file is very big and I have to import even bigger ones afterwards, I'd like to avoid editing the *.csv-file; I'm looking for a SQL-solution.
Add a SET COLUMN like so:
LOAD DATA INFILE 'file.txt'
INTO TABLE t1
(column1, #var1)
SET column2 = #var1/100;
You need to replace the #var1/100 with an expression that handles the 'space' and convert to -Infinity or 0 or 42... not sure..
This answer was originally included in the question as an edit by #speendo; I have converted it into a proper answer.
The solution is:
LOAD DATA INFILE '<file>'
REPLACE
INTO TABLE <table-name>
FIELDS
TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '"'
IGNORE 1 LINES ( #Header
<column-name1>,
<column-name2>,
#var1 #the variable that causes the problem
...
)
SET <column-name-of-problematic-column> = CASE
WHEN #var1 = ' ' THEN NULL
ELSE #var1
END
;