Checking valid date format in oracle [duplicate] - oracle

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 ;

Related

#ORA-01834 not a valid month [duplicate]

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").

how can we change one date format to another format in oracle sql? ORA-01861

How can we change the date format from DD-MON-YYYY to this format YYYY-MM-DD.
I have a date type column in a table. I want to display that value of that date column in this format - YYYY-MM-DD.
I tried with this -
disp_date := to_char(to_date(disp_date,'dd-mm-rrrr'),'rrrr-mm-dd')
and
disp_date := to_char(to_date(disp_date,'dd-mm-yyyy'),'yyyy-mm-dd')
While executing the above I got an error message stating that:
ORA-01861 Literal does not match format string
Please note the below details of my system,
select value from v$nls_parameters where parameter = 'NLS_DATE_LANGUAGE';
--AMERICAN
select value from v$nls_parameters where parameter = 'NLS_DATE_FORMAT';
--DD-MON-RRRR
If column's datatype is DATE - which is what your sentence suggests:
I have a date type column in a table
then you don't to_date it - it already is a date. Just apply to_char with desired format mask, e.g.
select to_char(disp_date, 'yyyy-mm-dd') from your_table
If you want to change the default display format then run
alter session set nls_date_format = 'YYYY-MM-DD';
select disp_date from ...
Note, your client application may change the format again according to settings in this client application.
A date does not have a format - it is stored internally to the database as a binary value using 7-bytes (representing century, year-of-century, month, day, hour, minute and second). It is not until whatever user interface you are using (i.e. SQL/Plus, SQL Developer, Java, etc.) tries to display it to you, the user, that is is converted it into something you would find meaningful (usually a string) that the date is formatted (and that conversion is done by the user interface and not by the database).
How can we change one date format to another format in oracle?
Since a date does not have a format then this question does not make sense.
If instead, you ask:
How can we display a date in a format in oracle?
If you want to display the date with a specific format then you want to explicitly convert it from a date to a string using TO_CHAR (rather than relying on an implicit conversion by the user interface). Since it is already a DATE then you do not need to use TO_DATE on it and can just use:
DECLARE
date_value DATE := SYSDATE;
formatted_date VARCHAR2(10);
BEGIN
formatted_date := TO_CHAR(date_value, 'yyyy-mm-dd');
DBMS_OUTPUT.PUT_LINE( formatted_date );
END;
/
Now, if your disp_date variable is a string (and not a date) then your code works:
DECLARE
disp_date VARCHAR2(11) := TO_CHAR(SYSDATE, 'DD-MON-RRRR');
BEGIN
disp_date := TO_CHAR(TO_DATE(disp_date, 'DD-MON-RRRR'), 'yyyy-mm-dd');
DBMS_OUTPUT.PUT_LINE( disp_date );
END;
/
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.

How do I return null if a CAST fails? [duplicate]

This question already has answers here:
ORACLE - Select Count on a Subquery
(3 answers)
Oracle Custom IsNumber Function with Precision and Scale
(1 answer)
Invalid numbers
(3 answers)
Closed 5 years ago.
In the SELECT statement below I'm casting a varchar2 to an integer value. How do I return NULL if the cast fails? The CAST would fail if the text, e.g. 'dog' cannot be cast to a integer. The column contains integers stored as strings (varchar2) and NULL.
SELECT CAST(text_column AS NUMBER(*,0)) column_alias
FROM schema.table#dblink;
Update - SELECT * FROM V$VERSION; reveals Oracle Database 12c Enterprise Edition Release 12.1.0.2.0
You need to check if the value is indeed an integer and handle it yourself; there is no "error handling" in SQL, as there is in procedural languages.
For example, if you don't have too much data, you may be fine with a check using regular expressions.
Something like
select cast ( case when regexp_like(text_column, '^(+|-)?\d+$')
then text_column -- else NULL; this is the default anyway
end
as number(*,0)
) as column_alias
from .......
If you are using Oracle 12.2 you can use TO_NUMBER with the new ON CONVERSION ERROR clause. See http://docs.oracle.com/database/122/SQLRF/TO_NUMBER.htm#SQLRF06140
Example:
select to_number('dog' default null on conversion error) from dual;

sqlloader date conversion: inconsistent data type

Am trying to load some data to an Oracle database using SQLLoader but I keep getting the errors ORA-00932: inconsistent datatypes: expected DATE got NUMBER or expecting char got date
The date comes in the format of e.g. 20130815 and it is to be stored into a database with a column of type Date.
The logic should be that if someone passes an invalid date a null or say an invalid month in the date string e.g. 20131301, then I want to insert a default date e.g. 19990101.
Here is the SQLLoader code I have so far:
COLUMN_DOB DATE 'YYYYMMDD' "CASE:COLUMN_DOB WHEN 'isdate(:COLUMN_DOB)=1' THEN :COLUMN_DOB ELSE to_date('19000101', 'YYYYMMDD') END",,
The immediate issue is that you're calling to_date() on the fixed value. The then part is returning the original string value of the date from the file; the else is returning a date; which leads to the 'expecting char got date' message.
If you remove the to_date() part then it will load all the values as 1900-01-01, because you have the case statement wrong. You're comparing the :COLUMN_DOB value with the string 'isdate(:COLUMN_DOB)=1'. It isn't calling the function, it's a fixed string, and your date field is never going to exactly match that text. So the case always goes into the else and gets the fixed value. You also seem to be mixing up the two forms of case statement.
So it should be:
... "CASE WHEN isdate(:COLUMN_DOB)=1 THEN :COLUMN_DOB ELSE '19000101' END"
Which, assuming you've built an isdate() function - since that is not an Oracle built-in - with a default format mask, something like this one based on an AskTom version:
create or replace function isdate (p_string in varchar2,
p_fmt in varchar2 := 'YYYYMMDD')
return number as
l_date date;
begin
if l_date is null then
return 0;
end if;
l_date := to_date(p_string, p_fmt);
return 1;
exception
when others then
return 0;
end;
/
... will put in valid dates as supplied, and invalid dates as 1900-01-01. The null check also means nulls will be inserted as 1900-01-01; it's perhaps simpler to have it here than to try to handle that separately in the control file.
You could maybe simplify it further by having a function that tries to convert the string and returns a date, and just calling that in the control file, without the date mask or the case statement. That approach is covered in that AskTom link too.
Personally I'd probably prefer to see the column left null rather than giving it a magic number. It isn't impossible to have someone with a valid DOB of 1900-01-01.
If you are creating a new function anyway, you could do this instead:
create or replace function my2date(p_str in varchar2) return date is
begin
return to_date(nvl(p_str, '19000101'), 'YYYYMMDD');
exception
when others then -- just about acceptable here
return date '1900-01-01';
end;
/
which you can execute from SQL*Plus, SQL Developer, Toad or whatever client you're using. And then you control file would have:
COLUMN_DOB "my2date(:COLUMN_DOB)"
I don't think there's a way of doing this without using a function. If you used an external table instead then you could use an anonymous block to do the conversion I suppose, but if you're stuck with SQL*Loader then I believe a function is the only way to stop a bad date causing the whole row to be rejected.

Resources