Source on IFS & Local Development

This commit is contained in:
SJLennon
2024-04-10 16:16:48 -04:00
parent 57c4efd0aa
commit a2d8f9c33c
83 changed files with 5807 additions and 4011 deletions
+3 -3
View File
@@ -7,7 +7,7 @@ set path lennons1; -- CHANGE TO YOUR LIBRARY
DROP FUNCTION DATE_MDY
;
CREATE OR REPLACE FUNCTION DATE_MDY
(INDATE DECIMAL(8,0) )
(INDATE DECIMAL(8, 0) )
RETURNS DATE
PARAMETER STYLE SQL
LANGUAGE RPGLE
@@ -20,7 +20,7 @@ CREATE OR REPLACE FUNCTION DATE_MDY
DROP FUNCTION DATE_YMD
;
CREATE OR REPLACE FUNCTION DATE_YMD
(INDATE DECIMAL(8,0) )
(INDATE DECIMAL(8, 0) )
RETURNS DATE
PARAMETER STYLE SQL
LANGUAGE RPGLE
@@ -33,7 +33,7 @@ CREATE OR REPLACE FUNCTION DATE_YMD
DROP FUNCTION DATE_CYMD
;
CREATE OR REPLACE FUNCTION DATE_CYMD
(INDATE DECIMAL(8,0) )
(INDATE DECIMAL(8, 0) )
RETURNS DATE
PARAMETER STYLE SQL
LANGUAGE RPGLE
+196 -195
View File
@@ -1,207 +1,208 @@
/title SQL UDFs to convert numeric to true dates
//===============================================================
// The DATE_SQL service program contains routines that are
// registered as User Defined Functions to SQL and which
// convert legacy numeric dates to true dates. This makes doing
// date arithmetic in SQL much easier.
//
// For example, if DSTPT is a 6-digit date in YYMMDD format, in SQL
// you can code:
//
// SELECT PNOPT FROM MVPSPRTP
// WHERE DATE_YMD(DSTPT) >= CURDATE() - 9O DAYS
//
// On alder versions of the OS,you may need to cast character dates
// to numeric before using.
// For example, WHERE DECIMAL(DATE_YMD(DSTPT)) >= ...
//
// Function included are:
// DATE_YMD Accepts numeric dates in YMD format, with
// either 6 or 8 digits.
// DATE_MDY Accepts numeric dates in MDY format, with
// either 6 or 8 digits.
// DATE_CYMD Accepts 7 digit numeric dates. If the 1st
// digit is 0 then it is in the 1900s and if
// it is 1 then it is the 2000s. These are
// standard IBM seven byte dates.
// ??????? Similar routines could be added to
// accept other formats
//
// For YMD or MDY dates, it handles either 6 or 8 digits.
// If the date passed is greater then 999999 then is it
// assumed to already have the century.
//
// Invalid dates return a null value. This means the UDFs will
// not crash, but be aware that your results may be skewed if
// you have bad data. (Logic could be added to convert
// "special" bad dates into some corporately acceptable value,
// e.g., 999999 could be converted to 9999-12-31.)
//
// Originally coded late 1990s, before the Y2K cleanups. Since
// tidied up and converted to free form..
//
// To Create
// =========
// 1) CRTRPGMOD MODULE(DATE_SQL) SRCFILE(DATE_UDF)
// OPTION(*EVENTF) DBGVIEW(*SOURCE)
// 2) CRTSRVPGM SRVPGM(DATE_SQL) EXPORT(*ALL)
// TEXT('DATE_SQL Service Program')
// 3) Run the CREATE_FNSQL statements to register to SQL
//===============================================================
**free
/title SQL UDFs to convert numeric to true dates
//===============================================================
// The DATE_SQL service program contains routines that are
// registered as User Defined Functions to SQL and which
// convert legacy numeric dates to true dates. This makes doing
// date arithmetic in SQL much easier.
//
// For example, if DSTPT is a 6-digit date in YYMMDD format, in SQL
// you can code:
//
// SELECT PNOPT FROM MVPSPRTP
// WHERE DATE_YMD(DSTPT) >= CURDATE() - 9O DAYS
//
// On alder versions of the OS,you may need to cast character dates
// to numeric before using.
// For example, WHERE DECIMAL(DATE_YMD(DSTPT)) >= ...
//
// Function included are:
// DATE_YMD Accepts numeric dates in YMD format, with
// either 6 or 8 digits.
// DATE_MDY Accepts numeric dates in MDY format, with
// either 6 or 8 digits.
// DATE_CYMD Accepts 7 digit numeric dates. If the 1st
// digit is 0 then it is in the 1900s and if
// it is 1 then it is the 2000s. These are
// standard IBM seven byte dates.
// ??????? Similar routines could be added to
// accept other formats
//
// For YMD or MDY dates, it handles either 6 or 8 digits.
// If the date passed is greater then 999999 then is it
// assumed to already have the century.
//
// Invalid dates return a null value. This means the UDFs will
// not crash, but be aware that your results may be skewed if
// you have bad data. (Logic could be added to convert
// "special" bad dates into some corporately acceptable value,
// e.g., 999999 could be converted to 9999-12-31.)
//
// Originally coded late 1990s, before the Y2K cleanups. Since
// tidied up and converted to free form..
//
// To Create
// =========
// 1) CRTRPGMOD MODULE(DATE_SQL) SRCFILE(DATE_UDF)
// OPTION(*EVENTF) DBGVIEW(*SOURCE)
// 2) CRTSRVPGM SRVPGM(DATE_SQL) EXPORT(*ALL)
// TEXT('DATE_SQL Service Program')
// 3) Run the CREATE_FNSQL statements to register to SQL
//===============================================================
H NoMain
//=== Prototypes ================================================
D Date_YMD pr
D NumericDate 8p 0 const
d RealDate d
D Indicators 5i 0 dim(1)
D RetInd 5i 0
d SQLSTATE 5a
d FuncName 517a varying
d SpecificName 128a varying
d ErrText 1000a varying
Ctl-Opt NoMain;
//=== Prototypes ================================================
Dcl-PR Date_YMD;
NumericDate Packed(8:0) const;
RealDate Date;
Indicators Int(5) dim(1);
RetInd Int(5);
SQLSTATE Char(5);
FuncName Varchar(517);
SpecificName Varchar(128);
ErrText Varchar(1000);
End-PR;
D Date_CYMD pr
D NumericDate 8p 0 const
d RealDate d
D Indicators 5i 0 dim(1)
D RetInd 5i 0
d SQLSTATE 5a
d FuncName 517a varying
d SpecificName 128a varying
d ErrText 1000a varying
Dcl-PR Date_CYMD;
NumericDate Packed(8:0) const;
RealDate Date;
Indicators Int(5) dim(1);
RetInd Int(5);
SQLSTATE Char(5);
FuncName Varchar(517);
SpecificName Varchar(128);
ErrText Varchar(1000);
End-PR;
D Date_MDY pr
D NumericDate 8p 0 const
d RealDate d
D Indicators 5i 0 dim(1)
D RetInd 5i 0
d SQLSTATE 5a
d FuncName 517a varying
d SpecificName 128a varying
d ErrText 1000a varying
Dcl-PR Date_MDY;
NumericDate Packed(8:0) const;
RealDate Date;
Indicators Int(5) dim(1);
RetInd Int(5);
SQLSTATE Char(5);
FuncName Varchar(517);
SpecificName Varchar(128);
ErrText Varchar(1000);
End-PR;
//===============================================================
// DATE_YMD
// ========
// SQL User Defined Function (UDF) converts a 6 or 8 digit
// numeric date in YMD format to a true date.
//
// Returns
// =======
// If input date is valid, then a true date.
// If input date is invalid, returns null with warning 01H99.
//===============================================================
// DATE_YMD
// ========
// SQL User Defined Function (UDF) converts a 6 or 8 digit
// numeric date in YMD format to a true date.
//
// Returns
// =======
// If input date is valid, then a true date.
// If input date is invalid, returns null with warning 01H99.
p Date_YMD b export
d Date_YMD pi
d pDateIn 8p 0 const
d pDateOut d
d pIndicators 5i 0 dim(1)
d pRetInd 5i 0
d pSQLSTATE 5a
d pFuncName 517a varying
d pSpecificName 128a varying
d pErrText 1000a varying
Dcl-Proc Date_YMD export;
Dcl-PI Date_YMD;
pDateIn Packed(8:0) const;
pDateOut Date;
pIndicators Int(5) dim(1);
pRetInd Int(5);
pSQLSTATE Char(5);
pFuncName Varchar(517);
pSpecificNam Varchar(128);
pErrText Varchar(1000);
End-PI;
/FREE
pRetInd = 0;
pSQLSTATE = '00000';
monitor;
select;
// === 8 digit dates, yyyymmdd =================================
when pDateIn > 999999;
pDateOut = %date(pDateIn: *ISO);
// === 6 digit dates, yymmdd ===================================
other;
pDateOut = %date(pDateIn: *YMD);
endsl;
on-error;
pRetInd = -1;
pDateOut = %date('9999-01-03');
pSQLSTATE = '01H99';
pErrText = %char(pDateIn) + ' is not a (numeric) date';
endmon;
return;
/END-FREE
p Date_YMD e
pRetInd = 0;
pSQLSTATE = '00000';
monitor;
select;
// === 8 digit dates, yyyymmdd =================================
when pDateIn > 999999;
pDateOut = %date(pDateIn: *ISO);
// === 6 digit dates, yymmdd ===================================
other;
pDateOut = %date(pDateIn: *YMD);
endsl;
on-error;
pRetInd = -1;
pDateOut = %date('9999-01-03');
pSQLSTATE = '01H99';
pErrText = %char(pDateIn) + ' is not a (numeric) date';
endmon;
return;
End-Proc;
//===============================================================
// DATE_CYMD
// =========
// SQL User Defined Function (UDF) converts a 7 digit
// numeric date in CYMD format to a true date.
//
// Returns
// =======
// If input date is valid, then a true date.
// If input date is invalid, returns null with warning 01H99.
//===============================================================
// DATE_CYMD
// =========
// SQL User Defined Function (UDF) converts a 7 digit
// numeric date in CYMD format to a true date.
//
// Returns
// =======
// If input date is valid, then a true date.
// If input date is invalid, returns null with warning 01H99.
p Date_CYMD b export
d Date_CYMD pi
d pDateIn 8p 0 const
d pDateOut d
d pIndicators 5i 0 dim(1)
d pRetInd 5i 0
d pSQLSTATE 5a
d pFuncName 517a varying
d pSpecificName 128a varying
d pErrText 1000a varying
Dcl-Proc Date_CYMD export;
Dcl-PI Date_CYMD;
pDateIn Packed(8:0) const;
pDateOut Date;
pIndicators Int(5) dim(1);
pRetInd Int(5);
pSQLSTATE Char(5);
pFuncName Varchar(517);
pSpecificNam Varchar(128);
pErrText Varchar(1000);
End-PI;
/FREE
pRetInd = 0;
pSQLSTATE = '00000';
monitor;
pDateOut = %date(pDateIn: *CYMD);
on-error;
pRetInd = -1;
pDateOut = %date('9999-01-01');
pSQLSTATE = '01H99';
pErrText = %char(pDateIn) + ' is not a (numeric) date';
endmon;
return;
/END-FREE
p Date_CYMD e
pRetInd = 0;
pSQLSTATE = '00000';
monitor;
pDateOut = %date(pDateIn: *CYMD);
on-error;
pRetInd = -1;
pDateOut = %date('9999-01-01');
pSQLSTATE = '01H99';
pErrText = %char(pDateIn) + ' is not a (numeric) date';
endmon;
return;
End-Proc;
//===============================================================
// DATE_MDY
// ========
// SQL User Defined Function (UDF) converts a 6 or 8 digit
// numeric date in MDY format to a true date.
//
// Returns
// =======
// If input date is valid, then a true date.
// If input date is invalid, returns null with warning 01H99.
//===============================================================
// DATE_MDY
// ========
// SQL User Defined Function (UDF) converts a 6 or 8 digit
// numeric date in MDY format to a true date.
//
// Returns
// =======
// If input date is valid, then a true date.
// If input date is invalid, returns null with warning 01H99.
p Date_MDY b export
d Date_MDY pi
d pDateIn 8p 0 const
d pDateOut d
d pIndicators 5i 0 dim(1)
d pRetInd 5i 0
d pSQLSTATE 5a
d pFuncName 517a varying
d pSpecificName 128a varying
d pErrText 1000a varying
Dcl-Proc Date_MDY export;
Dcl-PI Date_MDY;
pDateIn Packed(8:0) const;
pDateOut Date;
pIndicators Int(5) dim(1);
pRetInd Int(5);
pSQLSTATE Char(5);
pFuncName Varchar(517);
pSpecificNam Varchar(128);
pErrText Varchar(1000);
End-PI;
/FREE
pRetInd = 0;
pSQLSTATE = '00000';
monitor;
select;
// === 8 digit dates, mmddyyyy =================================
when pDateIn > 999999;
pDateOut = %date(pDateIn: *USA);
// === 6 digit dates, mmddyy ===================================
other;
pDateOut = %date(pDateIn: *MDY);
endsl;
on-error;
pRetInd = -1;
pDateOut = %date('9999-01-02');
pSQLSTATE = '01H99';
pErrText = %char(pDateIn) + ' is not a (numeric) date';
endmon;
return;
/END-FREE
p Date_MDY e
pRetInd = 0;
pSQLSTATE = '00000';
monitor;
select;
// === 8 digit dates, mmddyyyy =================================
when pDateIn > 999999;
pDateOut = %date(pDateIn: *USA);
// === 6 digit dates, mmddyy ===================================
other;
pDateOut = %date(pDateIn: *MDY);
endsl;
on-error;
pRetInd = -1;
pDateOut = %date('9999-01-02');
pSQLSTATE = '01H99';
pErrText = %char(pDateIn) + ' is not a (numeric) date';
endmon;
return;
End-Proc;
+207
View File
@@ -0,0 +1,207 @@
/title SQL UDFs to convert numeric to true dates
//===============================================================
// The DATE_SQL service program contains routines that are
// registered as User Defined Functions to SQL and which
// convert legacy numeric dates to true dates. This makes doing
// date arithmetic in SQL much easier.
//
// For example, if DSTPT is a 6-digit date in YYMMDD format, in SQL
// you can code:
//
// SELECT PNOPT FROM MVPSPRTP
// WHERE DATE_YMD(DSTPT) >= CURDATE() - 9O DAYS
//
// On alder versions of the OS,you may need to cast character dates
// to numeric before using.
// For example, WHERE DECIMAL(DATE_YMD(DSTPT)) >= ...
//
// Function included are:
// DATE_YMD Accepts numeric dates in YMD format, with
// either 6 or 8 digits.
// DATE_MDY Accepts numeric dates in MDY format, with
// either 6 or 8 digits.
// DATE_CYMD Accepts 7 digit numeric dates. If the 1st
// digit is 0 then it is in the 1900s and if
// it is 1 then it is the 2000s. These are
// standard IBM seven byte dates.
// ??????? Similar routines could be added to
// accept other formats
//
// For YMD or MDY dates, it handles either 6 or 8 digits.
// If the date passed is greater then 999999 then is it
// assumed to already have the century.
//
// Invalid dates return a null value. This means the UDFs will
// not crash, but be aware that your results may be skewed if
// you have bad data. (Logic could be added to convert
// "special" bad dates into some corporately acceptable value,
// e.g., 999999 could be converted to 9999-12-31.)
//
// Originally coded late 1990s, before the Y2K cleanups. Since
// tidied up and converted to free form..
//
// To Create
// =========
// 1) CRTRPGMOD MODULE(DATE_SQL) SRCFILE(DATE_UDF)
// OPTION(*EVENTF) DBGVIEW(*SOURCE)
// 2) CRTSRVPGM SRVPGM(DATE_SQL) EXPORT(*ALL)
// TEXT('DATE_SQL Service Program')
// 3) Run the CREATE_FNSQL statements to register to SQL
//===============================================================
H NoMain
//=== Prototypes ================================================
D Date_YMD pr
D NumericDate 8p 0 const
d RealDate d
D Indicators 5i 0 dim(1)
D RetInd 5i 0
d SQLSTATE 5a
d FuncName 517a varying
d SpecificName 128a varying
d ErrText 1000a varying
D Date_CYMD pr
D NumericDate 8p 0 const
d RealDate d
D Indicators 5i 0 dim(1)
D RetInd 5i 0
d SQLSTATE 5a
d FuncName 517a varying
d SpecificName 128a varying
d ErrText 1000a varying
D Date_MDY pr
D NumericDate 8p 0 const
d RealDate d
D Indicators 5i 0 dim(1)
D RetInd 5i 0
d SQLSTATE 5a
d FuncName 517a varying
d SpecificName 128a varying
d ErrText 1000a varying
//===============================================================
// DATE_YMD
// ========
// SQL User Defined Function (UDF) converts a 6 or 8 digit
// numeric date in YMD format to a true date.
//
// Returns
// =======
// If input date is valid, then a true date.
// If input date is invalid, returns null with warning 01H99.
p Date_YMD b export
d Date_YMD pi
d pDateIn 8p 0 const
d pDateOut d
d pIndicators 5i 0 dim(1)
d pRetInd 5i 0
d pSQLSTATE 5a
d pFuncName 517a varying
d pSpecificName 128a varying
d pErrText 1000a varying
/FREE
pRetInd = 0;
pSQLSTATE = '00000';
monitor;
select;
// === 8 digit dates, yyyymmdd =================================
when pDateIn > 999999;
pDateOut = %date(pDateIn: *ISO);
// === 6 digit dates, yymmdd ===================================
other;
pDateOut = %date(pDateIn: *YMD);
endsl;
on-error;
pRetInd = -1;
pDateOut = %date('9999-01-03');
pSQLSTATE = '01H99';
pErrText = %char(pDateIn) + ' is not a (numeric) date';
endmon;
return;
/END-FREE
p Date_YMD e
//===============================================================
// DATE_CYMD
// =========
// SQL User Defined Function (UDF) converts a 7 digit
// numeric date in CYMD format to a true date.
//
// Returns
// =======
// If input date is valid, then a true date.
// If input date is invalid, returns null with warning 01H99.
p Date_CYMD b export
d Date_CYMD pi
d pDateIn 8p 0 const
d pDateOut d
d pIndicators 5i 0 dim(1)
d pRetInd 5i 0
d pSQLSTATE 5a
d pFuncName 517a varying
d pSpecificName 128a varying
d pErrText 1000a varying
/FREE
pRetInd = 0;
pSQLSTATE = '00000';
monitor;
pDateOut = %date(pDateIn: *CYMD);
on-error;
pRetInd = -1;
pDateOut = %date('9999-01-01');
pSQLSTATE = '01H99';
pErrText = %char(pDateIn) + ' is not a (numeric) date';
endmon;
return;
/END-FREE
p Date_CYMD e
//===============================================================
// DATE_MDY
// ========
// SQL User Defined Function (UDF) converts a 6 or 8 digit
// numeric date in MDY format to a true date.
//
// Returns
// =======
// If input date is valid, then a true date.
// If input date is invalid, returns null with warning 01H99.
p Date_MDY b export
d Date_MDY pi
d pDateIn 8p 0 const
d pDateOut d
d pIndicators 5i 0 dim(1)
d pRetInd 5i 0
d pSQLSTATE 5a
d pFuncName 517a varying
d pSpecificName 128a varying
d pErrText 1000a varying
/FREE
pRetInd = 0;
pSQLSTATE = '00000';
monitor;
select;
// === 8 digit dates, mmddyyyy =================================
when pDateIn > 999999;
pDateOut = %date(pDateIn: *USA);
// === 6 digit dates, mmddyy ===================================
other;
pDateOut = %date(pDateIn: *MDY);
endsl;
on-error;
pRetInd = -1;
pDateOut = %date('9999-01-02');
pSQLSTATE = '01H99';
pErrText = %char(pDateIn) + ' is not a (numeric) date';
endmon;
return;
/END-FREE
p Date_MDY e
+5 -5
View File
@@ -10,7 +10,7 @@ Legacy databases on the IBM i stored dates in numeric (or character) fields. Doi
## Development
What these functions do can also be done, with some work, directly in SQL. And I'm aware there are other open source date UDFs avaliable, e.g. [iDate](https://www.think400.dk/downloads.htm).
What these functions do can also be done, *with some work*, directly in SQL. And I'm aware there are other open source date UDFs avaliable, e.g. [iDate](https://www.think400.dk/downloads.htm).
However...
@@ -41,15 +41,15 @@ An invalid input value will return a null value and give a 01H99 SQLSTATE warnin
## DATE_SQL
The RPG code for the DATE_SQL service program, which contains the functions. It is free format but the D-Specs are still fixed, and it can be edited in SEU. (When I originally wrote it, it was in fixed form RPGIV.)
The RPG code for the DATE_SQL service program, which contains the functions.
## DATE_SQLFR
## DATE_SQLFX
This is DATE_SQL but converted to totally free form. I converted it using [RpgFreeWeb](https://github.com/worksofbarry/rpgfreeweb), which does a nice job.
This is DATE_SQL with the D-Specs in fixed form, as a convenience for any who might still be on older releases.
## DATECRTFN
This is SQL "Create Function" code that tells SQL where the functions are.
This is SQL "Create Function" code that tells SQL where the functions are. Use the RUNSQLSTM command or iACS Run SQL Scripts.
## TEST_CYMD/TEST_MDY/TEST_YMD