year value in table in oracle - oracle

I have this query in oracle:
DELETE FROM my_table
WHERE to_date(last_update, 'DD/MM/YYYY') < to_date('01/01/2000', 'DD/MM/YYYY');
when I run this, I get this error:
ORA-01841: (full) year must be between -4713 and +9999 and must not be 0
there is not any 0 value in the table.
any one knows what is the problem?

I am assuming that you have stored your dates as a string with the DD/MM/YYYY format; it would be better if you stored them all as a DATE data type and then you would not have to do this conversion (and you would be using the most appropriate data type for the data).
From Oracle 12, you can use:
SELECT *
FROM my_table
WHERE TO_DATE( last_update, 'DD/MM/YYYY' DEFAULT NULL ON CONVERSION ERROR ) IS NULL;
To identify the rows that are raising that exception.
If you are already storing them as a DATE data type then don't use TO_DATE on a value that is already a DATE as TO_DATE expects a string so Oracle will implicitly cast your DATE to a string and then try to convert it back and your query is effectively:
DELETE FROM my_table
WHERE TO_DATE(
TO_CHAR(
last_update,
( SELECT value FROM NLS_SESSION_SETTINGS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
),
'DD/MM/YYYY'
) < to_date('01/01/2000', 'DD/MM/YYYY');
And if the NLS_DATE_FORMAT and your format model do not match then you will get errors (or, worse, the query will succeed and your data will be inconsistent as it may have swapped days and months or months and years).
Instead, just use:
DELETE FROM my_table
WHERE last_update < DATE '2000-01-01';

If the datatype of last_update is date, don't use the to_date function:
DELETE FROM my_table
WHERE last_update < to_date('01/01/2000', 'DD/MM/YYYY');

Related

Getting error while running session as not avalid month

I have a oracle view in which we have column called dayofset which defined from subtraction of two date columns like(to_date(date_column1)-to_date(date_column2)) and it is stored as number(38) datatype.
2.so,when I run session in informatica to get data from oracle view to redshift.im getting error like "not a valid month".
3.Input values for that column is like (25-JAN-21,10-APR-13)
4.im getting the output values like 1,2,3,4... Like this all are integer values.(this column just do the datediff operation) and provide the difference between two dates.
Could you guys please help on this.
I have a oracle view in which we have column called dayofset which defined from subtraction of two date columns like to_date(date_column1)-to_date(date_column2) and it is stored as number(38) datatype.
Never use TO_DATE on a column that is already a DATE data type. Just use.
CREATE VIEW your_view (dayofset)
SELECT date_column1 - date_column2
FROM your_table;
If you use TO_DATE then it takes a string as the first argument so you are effectively performing an implicit conversion to a string to convert it back to a date and your code is the equivalent of:
CREATE VIEW your_view (dayofset)
SELECT TO_DATE(
TO_CHAR(
date_column1,
(SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
),
(SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
)
-
TO_DATE(
TO_CHAR(
date_column2,
(SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
),
(SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
)
FROM your_table;
Depending on your NLS_DATE_FORMAT session parameter, this could just be a waste of time or it could truncate the date and give you an unexpected result; however, any user can change their session parameters at any time so you may get different results for different users so you should NEVER rely on implicit conversions.
If your columns are not a DATE data-type but are strings then use an explicit format model (and, if required, language) in the conversion:
CREATE VIEW your_view (dayofset)
SELECT TO_DATE(string_column1, 'DD-MON-RR', 'NLS_DATE_LANGUAGE=English')
- TO_DATE(string_column2, 'DD-MON-RR', 'NLS_DATE_LANGUAGE=English')
FROM your_table;

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

Oracle - Date comparison with SYSDATE

I need to compare date with date of current day, using SYSDATE, something like this:
SELECT * FROM my_table
WHERE date_column BETWEEN TO_DATE(SYSDATE -3,'dd.mm.yyyy') AND TO_DATE(SYSDATE,'dd.mm.yyyy');
However, this produces no result....My question :
Based on accepted answer here we should NEVER EVER compare strings with date. But in other side, a SYSDATE is allready a Date data type, and we should not compare It to a date - see here.
If I replace TO_DATE with TO_CHAR in upper SQL things go working again. But TO_CHAR function converts into String, so Oracle (I pressume) needs to convert this string again to date so you force Oracle to do an implicit data type conversion.
So, what should be a correct comparison with date and SYSDATE, in order to avoid Oracle working a bit slowly ?
You should not need to call either TO_DATE or TO_CHAR:
SELECT *
FROM my_table
WHERE date_column >= TRUNC(SYSDATE - 3) AND date_column < TRUNC(SYSDATE + 1);
Assuming date_column is a date type, you should be able to directly compare it against SYSDATE, or SYSDATE offset by some number of days.

extract month and year in oracle

Why does below query work successfully?
select to_char(sysdate,'MM-YYYY') from dual;
But the following queries give an invalid number error:
select to_char('28-JUL-17','MM-YYYY') from dual;
select to_char('7/28/2017','MM-YYYY') from dual;
Though, below query gives you the same date format.
select sysdate from dual; -- 7/28/2017 11:29:01 AM
TO_CHAR function accepts only date or number. Maybe you can try this
select to_char(to_date('28-JUL-17', 'DD-MON-YY'),'MM-YYYY') from dual;
As a side note, if you're planning to convert a bunch of dates to strings so you can look for all records in a certain month of a certain year, be aware that the TRUNC function can be used to reduce the precision of a date (e.g. to "month and year"). The following query pulls all records created this month, from the table. It should be faster than converting dates to char and doing string comparison..
SELECT * FROM table WHERE trunc(create_date, 'MON') = trunc(sysdate, 'MON')
Because function TO_CHAR() accepts date or timestamp values. However, neither '28-JUL-17' nor '7/28/2017' are dates or timestamps - they are STRINGS.
Oracle gently tries to convert these stings into DATE values. This implicit conversion may work or may fail, it depends on your current session NLS_DATE_FORMAT, resp. NLS_TIMESTAMP_FORMAT settings.
As given already in other answers you have to convert the string explicitly:
TO_DATE('28-JUL-17', 'DD-MON-RR')
TO_DATE('7/28/2017', 'MM/DD/YYYY')
to_char() isn't expecting you to start with a char value. If you really want that to work, you'll need to wrap it around a to_date() function.
to_char(
to_date(
'28-JUL-17'
, 'DD-Mon-YY'
)
,'MM-YYYY'
)
You are using an incorrect mask, for more information read here.
The correct one should be:
select to_char(to_date('28-JUL-17','DD-MON-YY'), 'MON-YY') from dual;
You can also extract the month using EXTRACT:
select EXTRACT (MONTH FROM to_date('28-JUL-17','DD-MON-YY')) from dual;
Cheers

Oracle virtual column, date and timestamp

I have a problem in Oracle, with a virtual column (I need the timestamp starting from a date column); here my example:
CREATE TABLE TBDATETIME(
DATETIME_1 DATE,
DATETIME_2 TIMESTAMP(9) GENERATED ALWAYS AS (
CAST( TO_CHAR(DATETIME_1, 'DD/MM/YYYY HH24:MI:SS')
|| '.' || TO_CHAR(DATETIME_1, 'FF9') AS TIMESTAMP(9))
) VIRTUAL
);
INSERT INTO TBDATETIME(DATETIME_1)
VALUES(SYSDATE);
COMMIT;
SELECT *
FROM TBDATETIME;
ORA-01821: date format not recognized
01821. 00000 - "date format not recognized"
*Cause:
*Action:
Where is the problem fetching data? I tried a lot of format masks, but nothing helps...
DATETIME_1 DATE
TO_CHAR(DATETIME_1, 'FF9')
That's the problem - DATE doesn't have fraction seconds
And it's dangerous to cast char to timestamp (the result depends on nls settings)
I suppose you want this:
CREATE TABLE TBDATETIME(DATETIME_1 DATE, DATETIME_2 TIMESTAMP(9) GENERATED ALWAYS AS (CAST(DATETIME_1 AS TIMESTAMP(9))) VIRTUAL);

Resources