Oracle SQL/PL - ORA-01843: not a valid month - oracle

I get the error message: ORA-01843: not a valid month after executing a sql plus script.
I try using the "standard" date format yyyy-mm-dd.
Is SQL/PL not understanding the alter session statement?
set linesize 200
set pagesize 1000
alter session set NLS_NUMERIC_CHARACTERS = ',.';
alter session set NLS_DATE_FORMAT = 'yyyy-mm-dd';
select
*
from my_table
where
date >= '2019-08-31';
exit

What you do need - from my point of view - is not to compare date values to strings.
Presuming that date here actually represent a DATE datatype column (why didn't you post table description?) (as already commented, you can't name a column that way, not unless you enclosed its name into double quotes), then
where date >= '2019-08-31'
---- ------------
DATE this is a string
datatype
Use date literal, which always has a DATE keyword and date in format 'yyyy-mm-dd':
where date >= date '2019-08-31'
Or, use to_date function with appropriate format mask:
where date >= to_date('2019-08-31', 'yyyy-mm-dd')
If date column (wrong name, as we already know) actually contains strings and you hope all of them are following the 'yyyy-mm-dd' format, well, some values don't. Storing dates into varchar2 datatype column is almost always a bad idea. Nobody prevents you from storing e.g. '2019-ac-31' into it, and that isn't a valid date value.

Related

Fetch Hours from Created date

I'm just trying to fetch Hour of my table from created date in Oracle 12c Database but it is showing error INVALID EXTRACT FIELD FOR EXTRACT FIELD. kindly guide me to fetch hour of my date my code is here...
SELECT
EXTRACT( HOUR FROM (TO_CHAR(CREATED_DATE,'RRRR-MM-DD HH:MI:SS')) ) HOUR
FROM
INVOICE_V;
my Date is stored as 6/1/2020 4:04:50 PM in this format and Extract function is not accept this function.
Do not store dates as strings.
But, since you have, convert it from a string to a date using TO_DATE:
SELECT EXTRACT( HOUR FROM TO_TIMESTAMP(CREATED_DATE,'DD/MM/YYYY HH12:MI:SS AM') ) AS HOUR
FROM INVOICE_V;
If, however, you meant that its just displaying in that format (and is actually a DATE data type) then CAST the date to a timestamp:
SELECT EXTRACT( HOUR FROM CAST( CREATED_DATE AS TIMESTAMP) ) AS HOUR
FROM INVOICE_V;
An hour can not be used in the EXTRACT function.
The only way to extract hour is to use TO_CHAR or subtract it from TRUNC date as follows:
TO_CHAR(created_date,'HH24') -- OR 'HH' as per your requirement
-- OR
FLOOR(24*(created_date- TRUNC(created_date)))
Please note that Oracle does not store dates in any format. It has its own binary representation. What you see while selecting from the table is based on the NLS_DATE_FORMAT parameter.
You can set it according to your requirement.
ALTER SESSION SET NLS_dATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'; -- like this
If you have a date column (or the-like), then:
select extract(hour from cast(created_date as timestamp)) as hr
from invoice_v
Alternatively:
select to_char(created_date, 'hh24') as hr
from invoice_v
The first expression returns an integer number, while the second produces a string.
Note that hour is a language keyword, hence not a good choice for an identifier (here, you used it as a column alias). I changed that.

Date mapping or translation in ORACLE

I have to use a schema on the table FOOTRADE.
When I look for a specific tradeid, it works fine, in this case it returns 1/7/2020.
select FOODATE from CASPER.FOOTRADE where tradeid = '0000000001';
FOODATE
========
1/7/2020
However when I want to look for all the rows that contains foodate 1/7/2020 - I get an error ORA-01843: not a valid month
select * from CASPER.FOOTRADE where TRADEDATE = '1/7/2020';
I suspect that the column is configured to somedate format and there has to be some mapping translation that needs to be done
Assuming TRADEDATE is actually an oracle DATE type, then you should not use direct literals to compare. Instead do:
where TRADEDATE = to_date('01/07/2020','MM/DD/YYYY');
The default date format mask is defined in NLS_DATE_FORMAT. So if that format does not match with your input you get an error. It is best to never assume what the default format may be on a system and do a to_date() call on the string.
Note that you can override the default and change the NLS_DATE_FORMAT for a session via:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY MM DD' .. etc whatever mask you need.

Invalid date format in datatype column in BODS job to Oracle

I am using SAP BODS and I am trying to fetch data from an ORACLE server using SQL query transormation. Now The table has a column named latest_changed_date which is a datetime column. I only want yesterday and current day data from that table. Now since the column is datetime, I need to convert it to date, but when I am using to_date function I get the following error.
SELECT *
FROM ABC.TEST
WHERE TO_DATE(LATEST_CHANGED_DATE) = TO_DATE(SYSDATE-1)
The database error message is
ORA-01843: not a valid month
I tried giving date format in TO_DATE condition as below:
SELECT *
FROM ABC.TEST
WHERE TO_DATE(LATEST_CHANGED_DATE,'YYYY-MM-DD') >= TO_DATE(SYSDATE-1,'YYYY-MM-DD')
Here I got the error:
date format picture ends before converting entire input string
I used trunc function also and again got either:
not a valid month
or
inconsistent datatypes: expected NUMBER got DATE
Below is a sample data for the column. I just need data for current and day before data from the column.
Update: I think the main issue is that I am not able to determine the proper datatype for the column in the source table and currently I don't have an option to determine that.
Rather than trying to implicitly cast your dates to strings and convert them back using TO_DATE( string_value, format_model ) you can use TRUNC() to truncate SYSDATE to the start of the day:
SELECT *
FROM ABC.TEST
WHERE LATEST_CHANGED_DATE >= TRUNC( SYSDATE-1 )
this will work:
SELECT *
FROM ABC.TEST
where sysdate-LATEST_CHANGED_DATE<=sysdate-(sysdate-2);
for example take this:
ALTER SESSION SET NLS_DATE_FORMAT = ' DD-MON-YYYY HH24:MI:SS';
SELECT * FROM d061_dates ;
03-DEC-2018 17:44:38
25-AUG-2018 17:44:42
30-AUG-2018 17:44:46
01-DEC-2018 17:44:49
02-DEC-2018 17:46:31
SELECT * FROM d061_dates
where sysdate-a<=sysdate-(sysdate-2);
03-DEC-2018 17:44:38
02-DEC-2018 17:46:31
you have to take sysdate minus on both sides to get comparision by a number which is less than equal to 2 to get day and day before yesterday and its giving the correct output.
thank you!!!!!!!!!!!!!

Formatting DATE in oracle

I have a date field in a table that contains date in dd-MMM-yy format .
I want to create a function that get this date check it for not null and then change it to yyyy/mm/dd format
but the problem is that oracle doesn't accept dd-MMM-yy formate date as a input parameter and
it say : Please Use yyyy-MM-dd date format !!!
how can I first change dd-MMM-yy formate to yyyy-MM-dd so oracle accept it as input then change it to yyyy/mm/dd
: Please Use yyyy-MM-dd date format !!!
That is no way related to an Oracle error.
I have a date field in a table that contains date in dd-MMM-yy format .
No, you are confused. Oracle does not store dates in the format you see. It stores it internally in 7 bytes with each byte storing different components of the datetime value.
Byte Description
---- -------------------------------------------------
1 Century value but before storing it add 100 to it
2 Year and 100 is added to it before storing
3 Month
4 Day of the month
5 Hours but add 1 before storing it
6 Minutes but add 1 before storing it
7 Seconds but add 1 before storing it
If you want to display, use TO_CHAR with proper FORMAT MODEL.
While inserting, use TO_DATE with proper FORMAT MODEL.
What you see as a format by default, is your locale specific NLS settings.
SQL> select parameter, value from v$nls_parameters where parameter='NLS_DATE_FORMAT';
PARAMETER VALUE
--------------- ----------------------------------------------------------------
NLS_DATE_FORMAT DD-MON-RR
SQL> select sysdate from dual;
SYSDATE
---------
03-FEB-15
SQL> select to_char(sysdate, 'mm/dd/yyyy hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'MM
-------------------
02/03/2015 17:59:42
SQL>
Update Regarding MMM format.
By MMM if you mean the month name up to three characters, then use MON.

how to insert current date into a DATE field in dd/mm/yyyy format in oracle

I have a field in my table with datatype as DATE in Oracle.
I want to insert the current date into that field, in format DD/MM/YYYY format.
I tried the below query:
select to_date(to_char(sysdate,'dd/mm/yyyy'),'dd/mm/yyyy') from dual
But it gives
1/8/2011 12:00:00 AM.
I want it to insert and show as
08/01/2011 12:00:00 AM.
Can anyone help me in this please ?
DATE is a built-in type in Oracle, which is represented in a fixed way and you have no control over it.
So:
I want it to insert [...] as 08/01/2011 12:00:00 AM
The above is nonsensical. You don't insert a string, you insert a date.
Format is useful only when you want:
to convert a string to an internal representation of date with TO_DATE (format mask: how to parse the string);
to convert an internal representation of date to a string with TO_CHAR (format mask: how to render the date).
So basically, in your example you take a DATE, you convert it to a STRING with some format, and convert it back to DATE with the same format. This is a no-op.
Now, what your client displays: this is because your Oracle Client won't display DATE fields directly and the NLS layer will convert any DATE field that is selected. So it depends on your locale by default.
What you want is SELECT TO_CHAR(SYSDATE,'DD/MM/YYYY') FROM dual; which will explicitly perform the conversion and return a string.
And when you want to insert a date in a database, you can use TO_DATE or date literals.
Alternatively, if you want to retrieve the date part of the DATE field, you may use truncate, i.e.
select to_char(trunc(sysdate),'dd/mm/yyyy') from dual;
When the column is of type DATE, you can use something like:
Insert into your_table(your_date_column) Select TRUNC(SYSDATE) from DUAL;
This removes the time part from SYSDATE.
Maybe this can help
insert into pasok values ('&kode_pasok','&kode_barang','&kode_suplier',
to_date('&tanggal_pasok','dd-mm-yyyy'),&jumlah_pasok);
note: '&' help we to insert data again, insert / end than enter to
insert again example: Enter value for kode_pembelian: BEL-E005 Enter
value for kode_barang: ELK-02 Enter value for kode_customer: B-0001
old 2: '&kode_pembelian','&kode_barang','&kode_customer', new 2:
'BEL-E005','ELK-02','B-0001', Enter value for tanggal_pembelian:
24-06-2002 Enter value for jumlah_pembelian: 2 old 3:
to_date('&tanggal_pembelian','dd-mm-yyyy'),&jumlah_pembelian) new 3:
to_date('24-06-2002','dd-mm-yyyy'),2)
1 row created.
SQL> / (enter)

Resources