Background: The company has a stored procedure, and the insert operation is always unsuccessful. After debugging, we can see that the insert statement contains a function for date processing,
TO_CHAR (TO_DATE (v_slot_date, 'yyyy-mm-dd'), 'yyyy-mm ')
Check the value of v_slot_date when the exception is thrown out. It is found that v_slot_date is '2017. October 10 '.
The date string is invalid, so an inset exception occurs. Therefore, we need to prepare some functions to judge the correctness of the input date.
1. How to use this function
(1) In SQL statements:
SQL> SELECT FN_ISDATE(REPLACE('2015-05-12','-','')) FROM DUAL;FN_ISDATE(REPLACE('2015-05-12'------------------------------ 1SQL> SELECT FN_ISDATE(REPLACE('2015-05-32','-','')) FROM DUAL;FN_ISDATE(REPLACE('2015-05-32'------------------------------ 0SQL>
(2) In the stored procedure:
CREATE OR REPLACE PROCEDURE ISBEGINIF FN_ISDATE(slotDate)=1 THEN INSERT INTO PESK.R_HR_SLOT(....)VALUES(......); COMMIT;END IF;END
2. The content of the stored function is as follows:
Create or replace function FN_ISDATE (v_datestr VARCHAR2 -- Date input parameter) return number -- returns 1 as correct, 0 as error. As/* daily public function: date check function call example: select FN_ISDATE ('000000') from dual; interval */I _year number; -- year I _month number; -- month I _day number; -- date d_tjrq date; -- date type: beginif v_datestr is null then return 0; end if; if length (trim (v_datestr) <> 10 then return 0; end if; -- The Judgment date is composed of numbers. If regexp_substr (trim (v_datestr), '[[: digit:] +') is null then return 0; end if; -- extract year I _year: = to_number (substr (rtrim (v_datestr),); -- extract the month I _month: = to_number (substr (rtrim (v_datestr), 6, 2); -- extract the date I _day: = to_number (substr (rtrim (v_datestr), 9, 2); -- determines the month. It must be within the range from January 1, to January 1, if I _month not between 1 and 12 then begin return 0; end; end if; -- determines the date. Values: 1, 3, 5, 7, 8, and 10. The maximum days of January 1, and are 30. if the month is a leap year, 29 is displayed, 2 for other years 8. if I _day between 1 and 31 then begin if I _day = 31 and I _month not in (1, 3, 5, 7, 8, 10, 12) then begin return 0; end if; if I _month = 2 then begin -- Rules 1: a leap year that can be divisible by 4 and cannot be divisible by 100. -- Rules 2: The Year of the century can be divided by 400, which is a leap year. -- Rules 3: for a year with a large value, if the year can be divided into 3200 and 172800, It is a leap year. For example, 172800 is a leap year, And 86400 is not a leap year. If (mod (I _year, 4) = 0 and mod (I _year, 100) <> 0) or mod (I _year, 400) = 0 or (mod (I _year, 3200) = 0 and mod (I _year, 172800) = 0) then begin -- if it is a leap year, the maximum day of February is 29 if I _day> 29 then begin return 0; end if; end; else begin -- if it is not a leap year, the maximum day of February is 28 if I _day> 28 then begin return 0; end if; end; end if; return 1; end; else return 0; end if; end;
You are welcome to provide better suggestions for improvement.