I get an error when the input for iv_from_date is given in this format 04/01/2013,it works perfectly when the input is in this format 04/Jan/2013.the nls date format is DD-MON_RR.My input should be in this format 04/01/2013.How do i do this
CREATE OR REPLACE procedure Sp_SaveNewTaxPercentage(iv_category_id number,
iv_tax_percentage number,
iv_from_date varchar2,
iv_to_date varchar2 default '12/31/9998',
iv_created_date date,
ov_err_code out nocopy varchar2,
ov_err_msg out nocopy varchar2) is
lv_category_id varchar2(25);
LV_TO_DATE varchar2(25);
lv_cat_id varchar2(12);
IV_TAX_ID VARCHAR2(12);
lv_tax_percentage varchar(20);
begin
ov_err_code := 0;
SELECT MAX(TAX_ID)
INTO IV_TAX_ID
FROM TAX_P
WHERE CATEGORY_ID IN (iv_category_id);
for J in (SELECT CATEGORY_ID, FROM_DATE, tax_percentage
FROM TAX_P
WHERE TAX_ID = IV_TAX_ID) loop
SELECT to_date(iv_from_date, 'dd/mm/yyyy') - 1
INTO LV_TO_DATE
FROM DUAL;
lv_cat_id := J.CATEGORY_ID;
lv_tax_percentage := j.tax_percentage;
begin
UPDATE TAX_P
SET TO_dATE = LV_TO_DATE
WHERE TAX_PERCENTAGE = lv_tax_percentage
and to_date = iv_to_date;
commit;
insert into tax_p
(TAX_ID,
CATEGORY_ID,
TAX_PERCENTAGE,
FROM_DATE,
TO_DATE,
CREATE_DATE)
values
(tax_seq.nextval,
iv_category_id,
to_char(iv_tax_percentage, '99D99'),
iv_from_date,
iv_to_Date,
sysdate);
commit;
end;
end loop;
IF LV_CAT_ID IS NULL THEN
insert into tax_p
(TAX_ID,
CATEGORY_ID,
TAX_PERCENTAGE,
FROM_DATE,
TO_DATE,
CREATE_DATE)
values
(tax_seq.nextval,
iv_category_id,
to_char(iv_tax_percentage, '99D99'),
iv_from_date,
IV_TO_DATE,
sysdate);
END IF;
commit;
select 'Successfully Saved' into ov_err_msg from dual;
commit;
Exception
when others then
rollback;
ov_err_code := 1;
ov_err_msg := 'Error while saving' || SQLERRM;
end Sp_SaveNewTaxPercentage;
Please avoid using VARCHAR2 type for variables and parameters thar are actually of type DATE. Oracle tries to convert your varchar parameter to date implicitly. When format is the same as set in NLS_DATE_FORMAT it succeeds else it fails. Make both iv_from_date and iv_to_date typed as DATE. If respective columns in table TAX_P are typed as varchar2 then make explicit format conversion in insert statement.
Related
How handling error in functon and return null instead any errors?
Simple example:
create or replace Function MY_FUNC
(
p_par IN number
)
RETURN varchar2
IS
BEGIN
return (Select name from my_table where id = p_par);
END;
create or replace Function MY_FUNC
(
p_year IN number,
p_month IN number,
p_day IN number
)
RETURN varchar2
IS
v_return varchar2(100);
BEGIN
Select to_char(p_day)||''||substr(to_char(TO_DATE(p_year || '-' || p_month || '-' || p_day, 'YYYY-MM-DD'),'DY'),0,1) into v_return from dual;
return v_return;
END;
Select MY_FUNC(2021,6,30) from dual; --OK
Select MY_FUNC(2021,6,31) from dual; --Need catch error
Return null if don't have record in table, or return null on ORA-01839: date not valid for month specified for anything.
My guess is that you want something like this where you catch the no_data_found exception
create or replace Function MY_FUNC
(
p_par IN my_table.id%type
)
RETURN my_table.name%type
IS
l_name my_table.name%type;
BEGIN
begin
select name
into l_name
from my_table
where id = p_par;
exception
when no_data_found
then
l_name := null;
end;
return l_name;
END;
I'm not sure where an "ORA-01839: date not valid for month" error could be coming from since there are no obvious dates in your code. You can, however, catch additional exceptions for other statements in your code in just the same way that I'm catching the no_data_found exception here.
create or replace Function MY_FUNC
(
p_year IN number,
p_month IN number,
p_day IN number
)
RETURN varchar2
IS
v_return varchar2(100);
invalid_date exception;
pragma exception_init( invalid_date, -01839 );
BEGIN
begin
Select to_char(p_day) || '' ||
substr(to_char(TO_DATE(p_year || '-' || p_month || '-' || p_day,
'YYYY-MM-DD'),
'DY'),
0,
1)
into v_return
from dual;
exception
when invalid_date
then
v_return := null;
end;
return v_return;
END;
In this specific case, though, you can simplify your logic (assuming you're on 12.2 or later)
create or replace Function MY_FUNC
(
p_year IN number,
p_month IN number,
p_day IN number
)
RETURN varchar2
IS
v_return varchar2(100);
v_dt date;
BEGIN
v_dt := to_date( p_year || '-' || p_month || '-' || p_day default null on conversion error,
'YYYY-MM-DD' );
if( v_dt is null )
then
v_return := null;
else
v_return := to_char(p_day) ||
substr( to_char(v_dt, 'DY' ),
0,
1 );
end if;
return v_return;
END;
You could use the EXCEPTION key word.
The NO_DATA_FOUND is the exception type.
If you don'nt know the type you can use the OTHERS key word.
Edit (Thanks to Justin)
Of course you have to store it in a variable.
To return the result.
create or replace Function MY_FUNC
(
p_par IN number
)
RETURN varchar2
IS
l_result varchar2;
BEGIN
Select name into l_result from my_table where id = p_par;
return l_result;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
END;
I want to bring a string which contains a date to a single format date.
EX:
13-06-2012 to 13-JUN-12
13/06/2012 to 13-JUN-12
13-JUN-2012 to
13-JUN-12
13/jun-2012 to 13-JUN-12
...
I tried to delete all special characters and after that use a function to transform that string into a single format of date. My function return more exceptions, I don't know why...
The function:
CREATE OR REPLACE FUNCTION normalize_date (data_in IN VARCHAR2)
RETURN DATE
IS
tmp_month VARCHAR2 (3);
tmp_day VARCHAR2 (2);
tmp_year VARCHAR2 (4);
TMP_YEAR_NUMBER NUMBER;
result DATE;
BEGIN
tmp_day := SUBSTR (data_in, 1, 2);
tmp_year := SUBSTR (data_in, -4);
--if(REGEXP_LIKE(SUBSTR(data_in,3,2), '[:alpha:]')) then
if(SUBSTR(data_in,3,1) in ('a','j','i','f','m','s','o','n','d','A','J','I','F','M','S','O','N','D')) then
tmp_month := UPPER(SUBSTR (data_in, 3, 3));
else
tmp_month := SUBSTR (data_in, 3, 2);
end if;
DBMS_OUTPUT.put_line (tmp_year);
TMP_YEAR_NUMBER := TO_NUMBER (tmp_year);
IF (tmp_month = 'JAN')
THEN
tmp_month := '01';
END IF;
IF (tmp_month = 'FEB')
THEN
tmp_month := '02';
END IF;
IF (tmp_month = 'MAR')
THEN
tmp_month := '03';
END IF;
IF (tmp_month = 'APR')
THEN
tmp_month := '04';
END IF;
IF (tmp_month = 'MAY')
THEN
tmp_month := '05';
END IF;
IF (tmp_month = 'JUN')
THEN
tmp_month := '06';
END IF;
IF (tmp_month = 'JUL')
THEN
tmp_month := '07';
END IF;
IF (tmp_month = 'AUG')
THEN
tmp_month := '08';
END IF;
IF (tmp_month = 'SEP')
THEN
tmp_month := '09';
END IF;
IF (tmp_month = 'OCT')
THEN
tmp_month := '10';
END IF;
IF (tmp_month = 'NOV')
THEN
tmp_month := '11';
END IF;
IF (tmp_month = 'DEC')
THEN
tmp_month := '12';
END IF;
-- dbms_output.put_line(tmp_day || '~'||tmp_year || '~' ||tmp_month);
IF (LENGTH (tmp_day || tmp_year || tmp_month) <> 8)
THEN
result := TO_DATE ('31122999', 'DDMMYYYY');
RETURN result;
END IF;
-- dbms_output.put_line('before end');
result:=TO_DATE (tmp_day || tmp_month ||tmp_year , 'DDMMYYYY');
-- dbms_output.put_line('date result: '|| result);
RETURN result;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
WHEN OTHERS
THEN
result := TO_DATE ('3012299', 'DDMMYYYY');
RETURN result;
RAISE;
END normalize_date;
Usage
SELECT customer_no,
str_data_expirare,
normalize_date (str_data_expirare_trim) AS data_expirare_buletin
FROM (SELECT customer_no,
str_data_expirare,
REGEXP_REPLACE (str_data_expirare, '[^a-zA-Z0-9]+', '')
AS str_data_expirare_trim
FROM (SELECT Q1.set_act_id_1,
Q1.customer_no,
NVL (SUBSTR (set_act_id_1,
INSTR (set_act_id_1,
'+',
1,
5)
+ 1,
LENGTH (set_act_id_1)),
'NULL')
AS str_data_expirare
FROM STAGE_CORE.IFLEX_CUSTOMERS Q1
WHERE Q1.set_act_id_1 IS NOT NULL
)
);
If you have a sound idea of all the possible date formats it might be easier to use brute force:
create or replace function clean_date
( p_date_str in varchar2)
return date
is
l_dt_fmt_nt sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll
('DD-MON-YYYY', 'DD-MON-YY', 'DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD'
, 'DD/MM/YYYY', 'MM/DD/YYYY', 'YYYY/MM/DD', 'DD/MM/YY', 'MM/DD/YY');
return_value date;
begin
for idx in l_dt_fmt_nt.first()..l_dt_fmt_nt.last()
loop
begin
return_value := to_date(p_date_str, l_dt_fmt_nt(idx));
exit;
exception
when others then null;
end;
end loop;
if return_value is null then
raise no_data_found;
end if;
return return_value;
exception
when no_data_found then
raise_application_error(-20000, p_date_str|| ' is unknown date format');
end clean_date;
/
Be aware that modern versions of Oracle are quite forgiving with date conversion. This function handled dates in formats which aren't in the list, with some interesting consequences:
SQL> select clean_date('20160817') from dual;
CLEAN_DAT
---------
17-AUG-16
SQL> select clean_date('160817') from dual;
CLEAN_DAT
---------
16-AUG-17
SQL>
Which demonstrates the limits of automated data cleansing in the face of lax data integrity rules. The wages of sin is corrupted data.
#AlexPoole raises the matter of using the 'RR' format. This element of the date mask was introduced as a Y2K kludge. It's rather depressing that we're still discussing it almost two decades into the new Millennium.
Anyway, the issue is this. If we cast this string '161225' to a date what century does it have? Well, 'yymmdd' will give 2016-12-15. Fair enough, but what about '991225'? How likely is that the date we really want is 2099-12-15? This is where the 'RR' format comes into play. Basically it defaults the century: numbers 00-49 default to 20, 50-99 default to 19. This window was determined by the Y2K issue: in 2000 it was more likely that '98 referred to the recent past than the near future, and similar logic applied to '02. Hence the halfway point of 1950. Note this is a fixed point not a sliding window. As we move further from the year 2000 the less useful that pivot point becomes. Find out more.
Anyway, the key point is that 'RRRR' does not play nicely with other date formats: to_date('501212', 'rrrrmmdd') hurlsora-01843: not a valid month. So, use'RR'and test for it before using'YYYY'`. So my revised function (with some tidying up) looks like this:
create or replace function clean_date
( p_date_str in varchar2)
return date
is
l_dt_fmt_nt sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll
('DD-MM-RR', 'MM-DD-RR', 'RR-MM-DD', 'RR-DD-MM'
, 'DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY-DD-MM');
return_value date;
begin
for idx in l_dt_fmt_nt.first()..l_dt_fmt_nt.last()
loop
begin
return_value := to_date(p_date_str, l_dt_fmt_nt(idx));
exit;
exception
when others then null;
end;
end loop;
if return_value is null then
raise no_data_found;
end if;
return return_value;
exception
when no_data_found then
raise_application_error(-20000, p_date_str|| ' is unknown date format');
end clean_date;
/
The key point remains: there's a limit to how smart we can make this function when it comes to interpreting dates, so make sure you lead with the best fit. If you think most of your date strings fit day-month-year put that first; you will still get some wrong casts but less that if you lead with year-month-day.
The String-to-Date Conversion Rules allow additional formatting rules (without any other modifiers being applied). (Also see this question) So:
MM also matches MON and MONTH;
MON also matches MONTH (and vice versa);
YY also matches YYYY;
RR also matches RRRR; and
The punctuation is optional.
Which means you can do:
CREATE OR REPLACE FUNCTION parse_Date_String(
in_string VARCHAR2
) RETURN DATE DETERMINISTIC
IS
BEGIN
BEGIN
RETURN TO_DATE( in_string, 'DD-MM-YY' );
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
BEGIN
RETURN TO_DATE( in_string, 'MM-DD-YY' );
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
BEGIN
RETURN TO_DATE( in_string, 'YY-MM-DD' );
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
RETURN NULL;
END;
/
Query:
WITH dates ( value ) AS (
SELECT '010101' FROM DUAL UNION ALL
SELECT '02JAN01' FROM DUAL UNION ALL
SELECT '03JANUARY01' FROM DUAL UNION ALL
SELECT '04012001' FROM DUAL UNION ALL
SELECT '05JAN2001' FROM DUAL UNION ALL
SELECT '06JANUARY2001' FROM DUAL UNION ALL
SELECT 'JAN0701' FROM DUAL UNION ALL
SELECT 'JANUARY0801' FROM DUAL UNION ALL
SELECT 'JAN0901' FROM DUAL UNION ALL
SELECT 'JANUARY1001' FROM DUAL UNION ALL
SELECT '990111' FROM DUAL UNION ALL
SELECT '99JAN12' FROM DUAL UNION ALL
SELECT '99JANUARY13' FROM DUAL UNION ALL
SELECT '19990114' FROM DUAL UNION ALL
SELECT '2001-01-15' FROM DUAL UNION ALL
SELECT '2001JAN16' FROM DUAL UNION ALL
SELECT '2001JANUARY17' FROM DUAL UNION ALL
SELECT '20010118' FROM DUAL
)
SELECT value, parse_Date_String( value ) AS dt
FROM dates;
Output:
VALUE DT
------------- -------------------
010101 2001-01-01 00:00:00
02JAN01 2001-01-02 00:00:00
03JANUARY01 2001-01-03 00:00:00
04012001 2001-01-04 00:00:00
05JAN2001 2001-01-05 00:00:00
06JANUARY2001 2001-01-06 00:00:00
JAN0701 2001-01-07 00:00:00
JANUARY0801 2001-01-08 00:00:00
JAN092001 2001-01-09 00:00:00
JANUARY102001 2001-01-10 00:00:00
990111 2099-01-11 00:00:00
99JAN12 2099-01-12 00:00:00
99JANUARY13 2099-01-13 00:00:00
19990114 1999-01-14 00:00:00
2001-01-15 2001-01-15 00:00:00
2001JAN16 2001-01-16 00:00:00
2001JANUARY17 2001-01-17 00:00:00
20010118 0118-01-20 00:00:00
(Note: the date formats you are using are ambiguous, as the last example demonstrates. You can swap the order the formats are parsed in the function to get different results but if you have 010203 is it 01-FEB-2003, 02-JAN-2003, 03-FEB-2001 or even 01-FEB-0003?)
If you want it in the format DD-MON-YY (but why YY and not YYYY?) then just use:
TO_CHAR( parse_Date_String( value ), 'DD-MON-YY' )
create or replace TRIGGER R_TRACKER_TRI
before insert on R_TRACKER
for each row
declare
v_number varchar2(15);
begin
if inserting then
:NEW.PROJECT_ID := PROJECT_ID(1);
:NEW.PRO_CREATED := LOCALTIMESTAMP;
:NEW.PRO_CREATED_BY := nvl(v('APP_USER'),USER);
IF :NEW.RECRUITMENT_TYPE= 'New' THEN
SELECT ('NEW/'||TO_CHAR(SYSDATE,'YY') || '/' || (NVL(MAX(SUBSTRB(PROJECT_ID,8)),10000)+1)) into v_number
FROM R_TRACKER
WHERE SUBSTRB(PROJECT_ID,1,3) = 'NEW';
:NEW.PROJECT_ID := v_number;
elsif :NEW.RECRUITMENT_TYPE= 'Replacement' THEN
SELECT ('REP/'||TO_CHAR(SYSDATE,'YY') || '/' || (NVL(MAX(SUBSTRB(PROJECT_ID,8)),10000)+1)) into v_number
FROM R_TRACKER
WHERE SUBSTRB(PROJECT_ID,1,3) = 'REP';
:NEW.PROJECT_ID := v_number;
end if;
INSERT INTO R_TRACKER
(
PROJECT_ID,
PRO_LOC,
DESIGNATION,
NO_OF_POSITION,
VACANCY_SINCE,
STATUS,
REMARKS,
UPLOAD,
RECRUITMENT_TYPE,
APPROVAL,
ACTION
)
VALUES
(
:NEW.PROJECT_ID,
:NEW.PRO_LOC,
:NEW.DESIGNATION,
:NEW.NO_OF_POSITION,
:NEW.VACANCY_SINCE,
:NEW.STATUS,
:NEW.REMARKS
:NEW.UPLOAD,
:NEW.RECRUITMENT_TYPE,
:NEW.APPROVAL,
:NEW.ACTION
);
end if;
end;
Looking at your code one can make out that you need to understand the use of Trigger. Please read it. In brief I wanted to tell that trigger is an event on a table. It is created to automate insertion/updation/deletion of column value of that table. In your case you are creating trigger on table R_TRACKER and then again at below inserting into it. This is wrong. See how you can do it.
--Table
CREATE TABLE R_TRACKER
(
PROJECT_ID VARCHAR2 (50),
PRO_LOC VARCHAR2 (50),
DESIGNATION VARCHAR2 (50),
NO_OF_POSITION VARCHAR2 (50),
VACANCY_SINCE VARCHAR2 (50),
STATUS VARCHAR2 (50),
REMARKS VARCHAR2 (50),
UPLOAD VARCHAR2 (50),
RECRUITMENT_TYPE VARCHAR2 (50),
APPROVAL VARCHAR2 (50),
ACTION VARCHAR2 (50)
);
--Trigger on table
CREATE OR REPLACE TRIGGER R_TRACKER_TRI
BEFORE INSERT ON R_TRACKER
FOR EACH ROW
DECLARE
v_number VARCHAR2 (15);
BEGIN
IF INSERTING
THEN
:NEW.PROJECT_ID := '1';--PROJECT_ID(1) -- This seems to be a function in your case;
--:NEW.PRO_CREATED := LOCALTIMESTAMP;
-- :NEW.PRO_CREATED_BY := NVL('APP_USER', USER);
IF :NEW.RECRUITMENT_TYPE = 'New'
THEN
SELECT ( 'NEW/'
|| TO_CHAR (SYSDATE, 'YY')
|| '/'
|| (NVL (MAX (SUBSTRB (PROJECT_ID, 8)), 10000) + 1))
INTO v_number
FROM R_TRACKER
WHERE SUBSTRB (PROJECT_ID, 1, 3) = 'NEW';
:NEW.PROJECT_ID := v_number;
ELSIF :NEW.RECRUITMENT_TYPE = 'Replacement'
THEN
SELECT ( 'REP/'
|| TO_CHAR (SYSDATE, 'YY')
|| '/'
|| (NVL (MAX (SUBSTRB (PROJECT_ID, 8)), 10000) + 1))
INTO v_number
FROM R_TRACKER
WHERE SUBSTRB (PROJECT_ID, 1, 3) = 'REP';
:NEW.PROJECT_ID := v_number;
END IF;
END IF;
END;
I have below procedure MY_PROC.
CREATE PROCEDURE MY_PROC(
IN_VAR_FROM_DATE IN VARCHAR2,
OUT_DATA OUT SYS_REFCURSOR )
AS
TEMP_DATE DATE;
BEGIN
TEMP_DATE : = NVL(TO_DATE(IN_VAR_FROM_DATE,'DD-MON-RRRR'),SYSDATE);
IF(IN_VAR_FROM_DATE='CM') THEN
TEMP_DATE := SYSDATE;
END IF;
OPEN OUT_DATA FOR SELECT * FROM TABLE_NAME WHERE DATE_COLUMN>=TRUNC(TEMP_DATE );
EXCEPTION
WHEN OTHERS THEN
NULL;
END MY_PROC;
Now in above proc, When i am passing null as input param, i am getting values for sysdate. i want same when i will pass "CM" as input param but instead i am getting no data.
Please help. Thanks in advance.
Hmmm. . . I think this is the logic you want:
OPEN OUT_DATA FOR
SELECT *
FROM TABLE_NAME
WHERE DATE_COLUMN >= (CASE WHEN IN_VAR_FROM_DATE IS NULL OR IN_VAR_FROM_DATE = 'CM'
THEN TRUNC(sysdate)
ELSE TO_DATE(IN_VAR_FROM_DATE, 'DD-MON-RRRR')
END);
I think this is due to when you are passing 'CM' as input parameter your procedure tries to convert the CM in to date and you are getting exception in this case.
CREATE PROCEDURE MY_PROC(
IN_VAR_FROM_DATE IN VARCHAR2,
OUT_DATA OUT SYS_REFCURSOR )
AS
TEMP_DATE DATE;
BEGIN
IF(IN_VAR_FROM_DATE='CM') THEN
TEMP_DATE := SYSDATE;
ELSE
TEMP_DATE : = NVL(TO_DATE(IN_VAR_FROM_DATE,'DD-MON-RRRR'),SYSDATE);
END IF;
OPEN OUT_DATA FOR SELECT * FROM TABLE_NAME WHERE DATE_COLUMN>=TRUNC(TEMP_DATE );
EXCEPTION
WHEN OTHERS THEN
NULL;
END MY_PROC;
I'm writing a package to learn Oracle. I want to create an OVERLAP function that checks if two date ranges overlap each other.
FUNCTION OVERLAP(p_START_DATE_1 DATE, p_END_DATE_1 DATE,
p_START_DATE_2 DATE, p_END_DATE_2 DATE) RETURN VARCHAR2 AS
lv_RESULT VARCHAR2(1);
BEGIN
lv_RESULT := SELECT 'T' AS overlap FROM dual
WHERE (p_START_DATE_1, p_END_DATE_1) overlaps (p_START_DATE_2, p_END_DATE_2);
IF (lv_RESULT = 'T')
RETURN 'T';
RETURN 'N';
END OVERLAP;
I tried to execute my function, but getting an error ORA-04063: package body 'XYZ' contains errors...
SELECT KP_XYZ_PACKAGE_SQL.OVERLAP(
TO_DATE('01/01/2014', 'DD/MM/YYYY'),
TO_DATE('01/12/2014', 'DD/MM/YYYY'),
TO_DATE('01/02/2014', 'DD/MM/YYYY'),
TO_DATE('01/05/2014', 'DD/MM/YYYY'))
FROM DUAL;
I think SELECT works fine. But the error occurs (I suppose) here: lv_RESULT := SELECT.... Why?
Try this:
CREATE OR REPLACE FUNCTION OVERLAP(p_START_DATE_1 DATE, p_END_DATE_1 DATE,
p_START_DATE_2 DATE, p_END_DATE_2 DATE) RETURN VARCHAR2 AS
lv_RESULT VARCHAR2(1);
BEGIN
lv_RESULT := 'N';
SELECT 'T' into lv_RESULT FROM dual
WHERE (p_START_DATE_1, p_END_DATE_1) overlaps (p_START_DATE_2, p_END_DATE_2);
IF (lv_RESULT = 'T') THEN
RETURN 'T';
END IF;
RETURN 'N';
END OVERLAP;
The IF statement was incomplete too - THEN and END IF were missing, which I have now added.
The documentation for SELECT INTO statement is here. There are links to examples at the end of the page.
Corrected version : return 'T' for True 'N' for False (?)
CREATE OR REPLACE FUNCTION OVERLAP(p_START_DATE_1 DATE, p_END_DATE_1 DATE,
p_START_DATE_2 DATE, p_END_DATE_2 DATE) RETURN VARCHAR2 AS
lv_RESULT VARCHAR2(1);
BEGIN
SELECT 'T' into lv_RESULT FROM dual WHERE (p_START_DATE_1, p_END_DATE_1) overlaps (p_START_DATE_2, p_END_DATE_2);
RETURN lv_RESULT;
EXCEPTION
WHEN NO_DATA_FOUND THEN lv_RESULT := 'N';
RETURN lv_RESULT;
END OVERLAP;
/