#ORA-01834 not a valid month [duplicate] - oracle

This question already has answers here:
SQL "not a valid month"
(6 answers)
Closed last year.
When I insert data into DB, it shows the messege "ORA-01834 not a valid month ".
My inserted value is like '17-07-19 06.34.11', I Want to know what's the correct value

Use TO_DATE function with appropriate format mask, e.g.
insert into your_table (date_column)
values (to_date('17-07-19 06.34.11', 'dd-mm-yy hh24:mi:ss'));
By the way, switch to a 4-digit year ("2019" instead of "19").

Related

Data provided to import into Oracle only has day and month. Year is missing. What DATE type to use?

Data provided to import into Oracle only has day and month. Year is missing. I need to run some queries to calculate number of days between dates. Eg. Checkin date: 03-April and Check out: 07-May.
What DATE type to use?
I need to run some queries to calculate number of days between dates. Eg. Check in date: 03-April and Check out: 07-May.
In general, you need a year to unambiguously calculate the number of days between two dates as you need to account for leap years (and, if you are being particularly precise, leap seconds).
You can use several methods:
Assume that your dates are always going to be in a non-leap year. Then you can pick any non-leap year and use it in your query as a default year.
Assume that your dates are always going to be in a leap year. Then you can pick any leap year and use it in your query as a default year.
Assume that your dates are always going to be of the current year.
They all have flaws:
If the assumption is wrong then you will get the wrong value if the dates are either side of Feb-29.
If you get the value Feb-29 then 1 & 3 can raise exceptions.
What DATE type to use?
If you are talking about how to store the value in a table then either store the value in a VARCHAR2 if you want to store the raw values or chose one of the three assumptions above and use a DATE data type and apply the default year.
For example, you could store the raw data and calculate the DATE values for the default year:
CREATE TABLE table_name (
check_in VARCHAR2(20),
check_out VARCHAR2(20),
check_in_1970 DATE GENERATED ALWAYS AS (TO_DATE(check_in || 1970 DEFAULT NULL ON CONVERSION ERROR, 'DD-MonthYYYY')),
check_out_1970 DATE GENERATED ALWAYS AS (TO_DATE(check_in || 1970 DEFAULT NULL ON CONVERSION ERROR, 'DD-MonthYYYY')),
check_in_2020 DATE GENERATED ALWAYS AS (TO_DATE(check_in || 2020 DEFAULT NULL ON CONVERSION ERROR, 'DD-MonthYYYY')),
check_out_2020 DATE GENERATED ALWAYS AS (TO_DATE(check_in || 2020 DEFAULT NULL ON CONVERSION ERROR, 'DD-MonthYYYY')),
);
INSERT INTO table_name (check_in, check_out) VALUES ('03-April', '07-May');
INSERT INTO table_name (check_in, check_out) VALUES ('01-January', '31-December');
INSERT INTO table_name (check_in, check_out) VALUES ('29-February', '29-February');
Then:
SELECT check_in,
check_out,
check_out_1970 - check_in_1970 AS diff_1970,
check_out_2020 - check_in_2020 AS diff_2020
FROM table_name;
Outputs:
CHECK_IN
CHECK_OUT
DIFF_1970
DIFF_2020
03-April
07-May
34
34
01-January
31-December
364
365
29-February
29-February
null
0
db<>fiddle here

I am getting error in date format in oracle [duplicate]

This question already has answers here:
A non-numeric character was found where a numeric was expected
(3 answers)
Oracle - literal does not match format string error [duplicate]
(2 answers)
Closed 1 year ago.
I want the date format in yyyy-mm-dd but I am getting error
Here is the code
table creation
create table orders
2 (ord_no int,
3 purch_amt float,
4 ord_date date,
5 customer_id int,
6 salesman_id int);
insertion in the table
insert all
2 into orders(ord_no,purch_amt,ord_date,customer_id,salesman_id)values(70001,150.5,'2012-10-05',3005,5002)
3 into orders(ord_no,purch_amt,ord_date,customer_id,salesman_id)values(70009,270.65,'2012-09-10',3001,5005)
4 into orders(ord_no,purch_amt,ord_date,customer_id,salesman_id)values(70002,65.26,'2012-10-05',3002,5001)
5 into orders(ord_no,purch_amt,ord_date,customer_id,salesman_id)values(70004,110.5,'2012-08-17',3009,5003)
6 into orders(ord_no,purch_amt,ord_date,customer_id,salesman_id)values(70007,948.5,'2012-09-10',3005,5002)
7 into orders(ord_no,purch_amt,ord_date,customer_id,salesman_id)values(70005,2400.6,'2012-07-27',3007,5001)
8 into orders(ord_no,purch_amt,ord_date,customer_id,salesman_id)values(70008,5760,'2012-09-10',3002,5001)
9 select * from dual;
into orders(ord_no,purch_amt,ord_date,customer_id,salesman_id)values(70001,150.5,'2012-10-05',3005,5002)
I am getting this error
into orders(ord_no,purch_amt,ord_date,customer_id,salesman_id)values(70001,150.5,'2012-10-05',3005,5002)
*
ERROR at line 2:
ORA-01861: literal does not match format string
'2012-10-05' is a string, not a DATE. Either
use DATE literal: DATE '2012-10-05'
explicit format specifier TO_DATE('2012-10-05', 'YYYY-MM-DD')
set default date format alter session NLS_DATE_FORMAT = 'YYYY-MM-DD';
Unless that is the default date format for the database or the default for the session (set via NLS_DATE_FORMAT, it won't work. I prefer to use the TO_DATE() function and specify the format and not rely on the default.

Split Date from Oracle Form to DB

I have a table with columns(year,day-month) -date type- in my database.
and a form with a text field for the user to enter a date.
how can I split the entered date to save it on db as following
year day_month
---- ---------
2018 03-04
I tried SUBSTR(TO_CHAR(TO_DATE(block.field)) in a trigger ,
but it didn't work bcz the column type is date, and I tried to add TO_DATE() as outer but the result was
year day_month
---------- ----------
03-04-2018 03-04-2018
How can I do it without changing my columns type?
I'd suggest you NOT to do that. Always store DATE values into DATE datatype columns. ALWAYS.
Later, if you want to present them differently, apply appropriate functions (such as TO_CHAR) to those values and display them any way you want.
In your example, that would be
TO_CHAR(date_column, 'yyyy') year
or
EXTRACT (year from date_column) year
and
TO_CHAR(date_column, 'dd-mm') day_month
[EDIT]
Once again (to repeat what I've said in a comment): the fact that you named columns in the database "year" (whose datatype is DATE) and "day_month" (whose datatype is also DATE) is completely useless.
Right now is (dd.mm.yyyy hh24:mi) 03.04.2018 10:32.
DATE datatype contains both date and time, so - how do you plan to put "2018" into the "year" column? What will you do with its month/day/hour/minutes/seconds component? It can't just "vanish", has to have some value. Is it the first of January at 00:00:00? Or what?
The same goes to your "day_month" column - it'll contain year, as well as hours/minutes/seconds, whether you want it or not.
Let's start with the "year": if you want to extract it from the Form item, that would be TO_CHAR, such as
to_char(:block.some_item, 'yyyy')
which results in a string, '2018'. You can't store it into a DATE datatype column, so you have to apply TO_DATE to it:
to_date(to_char(:block.some_item, 'yyyy'), 'yyyy')
and it will result in 01.04.2018 00:00:00 >>> see? Day, month, hours ... everything is here.
The alternative is to create those columns as VARCHAR2, but that's even worse.
Seriously, don't do that.
Try the following and make the necessary changes in Oracle Forms, substitute block and columns names instead of variables.
DECLARE
p_year VARCHAR2 (8);
p_date VARCHAR2 (8);
BEGIN
SELECT TO_CHAR (SYSDATE, 'YYYY') INTO p_year FROM DUAL;
SELECT TO_CHAR (SYSDATE, 'DD-MM') INTO p_date FROM DUAL;
DBMS_OUTPUT.put_line ('p_year --> ' || p_year || ' p_date --> ' || p_date);
END;
If your column is a DATE type, expect that it will require you to input a date data also.
In your case, you don't need to split a date. For the YEAR column, if the year value only matters to you, then you can use the TRUNC function
:BLK.YEAR_DATE_FIELD := TRUNC(:BLK.DATE_VALUE, 'YYYY');
and for the MONTH column, just save the date value there.
:BLK.MONTH_DATE_FIELD := :BLK.DATE_VALUE;
Also, maybe you just need to set the format mask of those two fields in Oracle forms. You can set the Format Mask of YEAR field to YYYY and MM-DD to the MONTH field.
The DATE data type is stored dates in tables as 7-bytes
byte 1 - century + 100
byte 2 - (year MOD 100 ) + 100
byte 3 - month
byte 4 - day
byte 5 - hour + 1
byte 6 - minute + 1
byte 7 - seconds+ 1
You CANNOT have a DATE data type that just stores year or month + day; it will always store all the components of the date/time.
So you either store the correct values in each column or you will have to make up values for the components you are not storing and will need to make sure that all the made up values are appropriate for the real values. It is just easier to use the real values in both columns.
So just do:
INSERT INTO your_table(
year,
day_month
) VALUES (
:BLK1.T_DATE,
:BLK1.T_DATE
);
Without splitting the date because a day_month without a year does not make sense (is 29th February a valid date? For the majority of years, no it isn't).
When you want to output it with a format then just format it as a string on output:
SELECT TO_CHAR( year, 'yyyy' ) AS year,
TO_CHAR( day_month, 'dd-mm' ) AS day_month
FROM your_table;

Which Data types are correct for storing numeric year input and numeric month in Oracle?

I am learning oracle 11g. I need to create columns to store Year and Month in the following sample format:
Year: 2015
Month: 6
I saw Date Time data type which takes whole date only .Also Number type may allow invalid year and month. But I want them in the given form while avoiding invalid month and year. Please tell me how to fix it.thanks
Updates: is this okay for such inputs?
CREATE TABLE FOOBAR (YYYY DATE, MM DATE);
The best solution is to store dates in DATE columns. Oracle has some pretty neat date functions, and you'll find it easy to work with storing the first of the month in a single DATE column. Otherwise you'll find yourself constantly extracting elements from other dates or cluttering your code with TO_CHAR() and TO_DATE() calls. Find out more.
However, if you have a rigid requirement, you can use strong typing and check constraints to avoid invalid months:
CREATE TABLE FOOBAR (
YYYY number(4,0) not null
, MM number(2,0) not null
, constraint foobar_yyyy_ck check (yyyy != 0)
, constraint foobar_mm_ck check (mm between 1 and 12)
);
This won't do what you want because it will default the missing elements:
CREATE TABLE FOOBAR (YYYY DATE, MM DATE);
We can't store just a year or just a month in DATE columns.
Use the DATE data type..
and when perform insert operation onto your db.. use
TO_DATE ('November 13, 1992', 'MONTH DD, YYYY')
For input and output of dates, the standard Oracle date format is DD-MON-YY, as follows:
'13-NOV-92'
perform insert operation/query like this:
INSERT INTO table_name (name, created_at) VALUES
('ANDY', TO_DATE ('November 13, 1992', 'MONTH DD, YYYY'));
Here is link to the guide as well:
https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#i1847
If you want to store month and year separately in the db you may use NUMBER & NUMBER(n)
https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#i22289
Hope this helps..

Checking valid date format in oracle [duplicate]

This question already has an answer here:
How to test if date format string is a valid date format string in Oracle
(1 answer)
Closed 8 years ago.
In source table we are having 4 date field columns. 2 columns are having DATE as their datatype and other are varchar2. What I want to check is the incoming data for date fields are valid, if not it should be rejected if we found it is having invalid format (other than dd/mm/yyyy) and if it like 32/02/1999 or 34/15/1999 etc.
Can you please give me a sql query to check it.
Thanks
DECLARE
in_txt VARCHAR2; -- to be converted
in_fmt_txt VARCHAR2 := 'DD-MON-YYYY'; -- optional format
BEGIN
-- Try to convert in_txt to a DATE. If it works, fine.
RETURN TO_DATE (in_txt, in_fmt_txt);
EXCEPTION -- If TO_DATE caused an error, then this is not a valid DATE: return NULL
WHEN OTHERS
THEN
RETURN NULL;
END ;

Resources