ORA-00936: missing expression in SQL*LOADER control file - oracle

I have a control.ctl file and I'm using SQL*LOADER to load this data in the table.
LOAD DATA
INFILE 'data_for_insert.csv'
INSERT INTO TABLE TABLE_NAME
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
COL1,
COL2,
NEXT_MONDAY EXPRESSION "SELECT NEXT_DAY(SYSDATE, 'MONDAY') FROM dual",
TODAY SYSDATE
)
Error received:
Record 16: Rejected - Error on table TABLE_NAME, column NEXT_MONDAY .
ORA-00936: missing expression
I can't find what is the problem because the expression SELECT NEXT_DAY(SYSDATE, 'MONDAY') FROM dual works when I run it in SQL Developer.
If I take that expression out it works so there's no problems in the rest of the code. Can someone help? thanks!

If that's an expression, then use an expression, not the whole query; not that it won't work (you found out that it actually works), it's just unnecessary.
Control file:
load data
infile *
replace
into table test
fields terminated by ',' optionally enclosed by '"'
trailing nullcols
(col1,
col2,
next_monday expression "next_day (sysdate, 'MONDAY')",
today sysdate
)
begindata
1,2
3,4
Testing:
SQL> $sqlldr scott/tiger control=test9.ctl log=test9.log
SQL*Loader: Release 11.2.0.2.0 - Production on Pet Stu 26 21:24:37 2021
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 1
Commit point reached - logical record count 2
SQL> select * from test;
COL1 COL2 NEXT_MONDA TODAY
---------- ---------- ---------- ----------
1 2 29.11.2021 26.11.2021
3 4 29.11.2021 26.11.2021
SQL>

In the end this solution seems to have solved the problem. I added parentheses inside the double quotes.
NEXT_MONDAY EXPRESSION "(SELECT NEXT_DAY(SYSDATE, 'MONDAY') FROM dual)"

Related

Format string does't match

I have one problem in my query and I don't see where the problem is. So the problem is when I run the query I get error like
ORA-01861: literal does not match format string
01861. 00000 - "literal does not match format string"
*Cause: Literals in the input must be the same length as literals in
the format string (with the exception of leading whitespace). If the
"FX" modifier has been toggled on, the literal must match exactly,
with no extra whitespace.
*Action: Correct the format string to match the literal.
So far my query is here
SELECT rp.*
FROM responsible_persons rp
LEFT JOIN projects p ON p.ProjectID = rp.ProjectID
WHERE rp.UserID = 195
AND (SYSDATE BETWEEN p.StartDate AND p.EndDate)
So far I try to convert StartDate and EndDate to_date() but still I have problem.
What is wrong here ? Where I made mistake ?
You really shouldn't store dates as strings.
Now, having said that, you would want to change your code to
AND (SYSDATE BETWEEN TO_DATE(p.StartDate,'YYYY-MM-DD') AND TO_DATE(p.EndDate,'YYYY-MM-DD'))
But understand that if p.EndDate is '2020-08-28' and SYSDATE is 2020-08-28 07:49:30, then you won't get a match because your date strings don't contain the time component that SYSDATE contains. So you might also want to strip the time component off of SYSDATE with this
TRUNC(SYSDATE)
As suggested by Roberto, you could manipulate the NLS_DATE_FORMAT for your session to get past this problem. But if you have other dates stored as strings and they aren't in the same format, then you've just pushed another problem onto the stack.
Try to set the NLS_DATE_FORMAT in your session to the values in your table, that sysdate can get the same format as the data you have there:
ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD' ;
SELECT rp.*
FROM responsible_persons rp
LEFT JOIN projects p ON p.ProjectID = rp.ProjectID
WHERE rp.UserID = 195
AND (SYSDATE BETWEEN p.StartDate AND p.EndDate)
An example
SQL> create table t ( c1 varchar2(20) , c2 varchar2(20) ) ;
Table created.
SQL> insert into t values ( '22.01.2020 10:00:00' , '22.01.2020 21:00:00' ) ;
1 row created.
SQL> select * from t where ( sysdate between c1 and c2 ) ;
select * from t where ( sysdate between c1 and c2 )
*
ERROR at line 1:
ORA-01843: not a valid month
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss' ;
Session altered.
SQL> select * from t where ( sysdate between c1 and c2 ) ;
no rows selected
SQL>

Replace spaces after a dot in the string

I want to write a query in Oracle to remove any spaces after any dot in the string.
example :
select 'My name is Pramod. I am writing a query. Today is AUG 16TH.' from dual;
output requested is :
My name is Pramod.I am writing a query.Today is AUG 16TH.
A simple replace, based on your simple example:
SQL> with test (col) as
2 (select 'My name is Pramod. I am writing a query' from dual)
3 select replace(col, '. ', '.') result
4 from test;
RESULT
--------------------------------------
My name is Pramod.I am writing a query
SQL>
For not that simple examples:
SQL> with test (col) as
2 (select 'My name is Pramod. I am writing a query' from dual union all
3 select 'Right. As #Mathguy said. It won''t work.always' from dual
4 )
5 select regexp_replace(col, '\. +', '.') result
6 from test;
RESULT
--------------------------------------------------------------------------------
My name is Pramod.I am writing a query
Right.As #Mathguy said.It won't work.always
SQL>
Try this:
select regexp_replace('My name is Pramod. I am writing a query. Today is AUG 16TH.','\.(\s)*','.')
from dual
Sql fiddle Demo
Cheers!!
this works too.
select regexp_replace( 'Right. As #Mathguy said. It won''t work.always' ,'(\.)([[:space:]]*)', '.' ) from dual;

How to include a separator in the inserted data in SQL load, Oracle?

load data
infile 'c:\oracle_toad\sql_loader\v1_data.txt'
replace into table v1 fields terminated by ','
( a integer external, b char, c char )
1,2,"da,ta1"
2,4,"dat,a2"
2,4,"da,ta2"
"" are not supposed to be inserted as a part of data. That's just for reference.
I intentionally inserted "," in each of the data set.
I am hoping to insert 1, 2, "da,ta1" <<< like this. Is there a way that I can include the separator "," within the data set?
Here's an example:
Test table:
SQL> create table test (col1 number, col2 varchar2(20), col3 varchar2(20));
Table created.
Control file:
load data
infile *
replace
into table test
fields terminated by ',' optionally enclosed by '"'
trailing nullcols
(
col1,
col2,
col3
)
begindata
1,2,"da,ta1"
2,4,"dat,a2"
2,4,"da,ta2"
Loading session & the result:
SQL> $sqlldr scott/tiger control=test04.ctl log=test04.log
SQL*Loader: Release 11.2.0.2.0 - Production on Pon Kol 27 14:11:26 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 2
Commit point reached - logical record count 3
SQL> select * From test;
COL1 COL2 COL3
---------- -------------------- --------------------
1 2 da,ta1
2 4 dat,a2
2 4 da,ta2
SQL>

How to remove value of the column from flat files or replace column with some other value while load data from flat files in oracle tables

I have one temp table which is empty now. I want to load the data from that flat file to the oracle temp table. In one column col3 of the flat file mention as "X" but in the table i want to insert as "abc". If possible to remove column value from "X" in flat file then how it is possible? or replace value from "X" to "abc".
SQL*Loader lets you apply SQL operators to fields, so you can manipulate the value from the file.
Let's say you have a simple table like:
create table your_table(col1 number, col2 number, col3 varchar2(3));
and a data file like:
1,42,xyz
2,42,
3,42,X
then you could make your control file replace an 'X' value in col3 with the fixed value 'abc' using a case expression:
load data
replace
into table your_table
fields terminated by ',' optionally enclosed by '"'
trailing nullcols
(
col1,
col2,
col3 "CASE WHEN :COL3 = 'X' THEN 'abc' ELSE :COL3 END"
)
Running that file through with that control file inserts three rows:
select * from your_table;
COL1 COL2 COL
---------- ---------- ---
1 42 xyz
2 42
3 42 abc
The 'X' has been replaced, the other values are retained.
If you want to 'remove' the value, rather than replacing it, you could do the same thing but with null as the fixed value:
col3 "CASE WHEN :COL3 = 'X' THEN NULL ELSE :COL3 END"
or you could use nullif or defaultif:
col3 nullif(col3 = 'X')
DECODE, right?
SQL> create table test (id number, col3 varchar2(20));
Table created.
SQL> $type test25.ctl
load data
infile *
replace into table test
fields terminated by ',' trailing nullcols
(
id,
col3 "decode(:col3, 'x', 'abc', :col3)"
)
begindata
1,xxx
2,yyy
3,x
4,123
SQL>
SQL> $sqlldr scott/tiger#orcl control=test25.ctl log=test25.log
SQL*Loader: Release 11.2.0.2.0 - Production on ╚et O×u 29 12:57:56 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 3
Commit point reached - logical record count 4
SQL> select * From test order by id;
ID COL3
---------- --------------------
1 xxx
2 yyy
3 abc
4 123
SQL>

Loading date from an input file through sqlloader

I have a requirement to load the "dates" from a text file. I have tried like this
OPTIONS(skip=1)
load data
infile 'mypath\sample.txt'
APPEND
into table sample
fields terminated by "|"
TRAILING NULLCOLS
(
name CHAR(500) NULLIF (name=BLANKS)
, update_date date "MM/DD/RRRR HH:MI:SS" NULLIF (update_date=BLANKS)
)
My system date format is "6/21/2000 8:29:58 AM"
It is not showing any error in the BAD file. but 64 records were there in the bad file. please help me.
thanks
It would be better if you posted a few sample input lines; anyway, using the following example, it works fine in my case. Have a look, compare it with your attempt, make changes (if needed).
First, a table:
SQL> create table sample
2 (name varchar2(30),
3 update_date date);
Table created.
SQL>
Control file (which includes sample data):
options (skip=1)
load data
infile *
replace
into table sample
fields terminated by '|' trailing nullcols
(
name,
update_date "to_date(:update_date, 'mm/dd/yyyy hh:mi:ss am')"
)
begindata
name | update_date
little | 6/21/2000 8:29:58 AM
foot | 12/21/2007 10:15:12 PM
Loading session:
M:\a1_maknuto>sqlldr little/foot#orcl control=test19.ctl log=test19.log
SQL*Loader: Release 11.2.0.2.0 - Production on Pon Sij 8 07:17:52 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 1
Commit point reached - logical record count 2
M:\a1_maknuto>
Result:
SQL> select * from sample;
NAME UPDATE_DATE
------------------------------ -------------------
little 21.06.2000 08:29:58
foot 21.12.2007 22:15:12
SQL>
[EDIT: how to subtract 12 hours]
SQL> alter session set nls_date_format = 'mm/dd/yyyy hh:mi:ss am';
Session altered.
SQL> with test as
2 (select to_date('12/19/2017 12:49:48 PM', 'mm/dd/yyyy hh:mi:ss am') col
3 from dual
4 )
5 select
6 col,
7 col - 12/24 sub_12_hours
8 from test;
COL SUB_12_HOURS
---------------------- ----------------------
12/19/2017 12:49:48 PM 12/19/2017 12:49:48 AM
SQL>

Resources