From 23a23b1747352a5d1048b44f5c5a876fcc726b91 Mon Sep 17 00:00:00 2001 From: Alex Zaw Date: Wed, 25 Feb 2026 23:06:07 +0000 Subject: [PATCH] Update Function SFP_GET_OEE_TRENDS --- RESTAPI/Functions/SFP_GET_OEE_TRENDS.sql | 292 ++++++++++++++++++++++- 1 file changed, 291 insertions(+), 1 deletion(-) diff --git a/RESTAPI/Functions/SFP_GET_OEE_TRENDS.sql b/RESTAPI/Functions/SFP_GET_OEE_TRENDS.sql index 6869e59..8a8341d 100644 --- a/RESTAPI/Functions/SFP_GET_OEE_TRENDS.sql +++ b/RESTAPI/Functions/SFP_GET_OEE_TRENDS.sql @@ -1 +1,291 @@ -@@\@^@ % %@@@@Kmmm@M@ %m@M]@]@ %@M]@@@ %@@ %@Kmmm@ %@@ %@@@ %@@@@ %@@@@~@\@k@ %@~@\@k@ %@~@\@k@ %@~@Mk@k@]@k@ %@~@\@k@ %@~@\@k@ %@~@\@@@ %@ %@@@M@@]@@}}@^@ %@m@@@@^@ %@m@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@m@@M@@]@@}}@^@ %@@@M@@]@@}}@^@ %@mm@@M@@@]@@}}@^@ %``@ř@@@ %@m@@M@@]@@}}@^@ %@m@@@@^@ %@m@@M@@]@@}}@^@ %@mm@@@@^@ %@mm@@@@^@ %``@Ö@@@@@ %@@@@@}}@@``@ɕ@@ %@ %@m@~@}}@^@ %@@@@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@}}@@``@դ@@@@ %@ %@m@~@}}@^@ %@@@@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@}}@@``@Ֆ@@@ %@ %@m@~@}}@^@ %@m@~@}Ֆ@@@@@@}@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@}}@@``@Ֆ@@ %@ %@m@~@}}@^@ %@@@@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@}}@@``@ւ@@@ %@ %@m@~@}}@^@ %@@@@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %@@@@@ %@ %@@@@ %m@~@m@k@ %m@~@mm@k@m@~@m@^@ %@mm@~@@^@ %@mm@~@@^@ %@^@ %``@ׁ@@@ %@m@~@@M@@M@m@M@m@k@}[K}@]@]@k@@]@^@ %@m@~@@M@m@M@m@k@}[K}@]@k@}}@]@^@ %@m@~@@M@m@M@m@k@}[K}@]@k@}}@]@^@ %@m@~@@M@m@M@m \ No newline at end of file +SET PATH *LIBL ; + +CREATE OR REPLACE FUNCTION RESTAPI.SFP_GET_OEE_TRENDS ( + IN_PARM CLOB(2147483647) ) + RETURNS CLOB(2147483647) + LANGUAGE SQL + SPECIFIC RESTAPI.SFP_GET_OEE_TRENDS + NOT DETERMINISTIC + MODIFIES SQL DATA + CALLED ON NULL INPUT + SET OPTION ALWBLK = *ALLREAD , + ALWCPYDTA = *OPTIMIZE , + COMMIT = *NONE , + DECRESULT = (31, 31, 00) , + DYNDFTCOL = *NO , + DYNUSRPRF = *USER , + SRTSEQ = *HEX + BEGIN +DECLARE ENV VARCHAR ( 20 ) DEFAULT '' ; +DECLARE V_DAYS INTEGER DEFAULT 30 ; +DECLARE V_PLANT VARCHAR ( 15 ) DEFAULT '' ; +DECLARE V_DEPT VARCHAR ( 15 ) DEFAULT '' ; +DECLARE V_WC VARCHAR ( 5 ) DEFAULT '' ; +DECLARE V_SITE VARCHAR ( 3 ) DEFAULT '' ; +DECLARE LL VARCHAR ( 1024 ) DEFAULT '' ; +DECLARE V_IN_PARM CLOB ( 2 G ) DEFAULT '' ; +-- Error handling variables +DECLARE V_SQLSTATE CHAR ( 5 ) DEFAULT '00000' ; +DECLARE V_SQLCODE INTEGER DEFAULT 0 ; +DECLARE V_ERRMSG VARCHAR ( 500 ) DEFAULT '' ; +DECLARE V_HTTP_STATUS INTEGER DEFAULT 200 ; +DECLARE V_HAS_ERROR INTEGER DEFAULT 0 ; +-- Continue handlers for error capture +DECLARE CONTINUE HANDLER FOR SQLSTATE '22007' -- Invalid datetime +BEGIN +SET V_SQLSTATE = '22007' ; +GET DIAGNOSTICS CONDITION 1 V_ERRMSG = MESSAGE_TEXT ; +SET V_HTTP_STATUS = 400 ; +SET V_HAS_ERROR = 1 ; +END ; +DECLARE CONTINUE HANDLER FOR SQLSTATE '22003' -- Numeric out of range +BEGIN +SET V_SQLSTATE = '22003' ; +GET DIAGNOSTICS CONDITION 1 V_ERRMSG = MESSAGE_TEXT ; +SET V_HTTP_STATUS = 400 ; +SET V_HAS_ERROR = 1 ; +END ; +DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' -- No data found +BEGIN +SET V_SQLSTATE = '02000' ; +SET V_ERRMSG = 'No data found for the specified criteria' ; +SET V_HTTP_STATUS = 404 ; +SET V_HAS_ERROR = 1 ; +END ; +DECLARE CONTINUE HANDLER FOR SQLSTATE '42501' -- Not authorized +BEGIN +SET V_SQLSTATE = '42501' ; +GET DIAGNOSTICS CONDITION 1 V_ERRMSG = MESSAGE_TEXT ; +SET V_HTTP_STATUS = 403 ; +SET V_HAS_ERROR = 1 ; +END ; +DECLARE CONTINUE HANDLER FOR SQLSTATE '42704' -- Object not found +BEGIN +SET V_SQLSTATE = '42704' ; +GET DIAGNOSTICS CONDITION 1 V_ERRMSG = MESSAGE_TEXT ; +SET V_HTTP_STATUS = 404 ; +SET V_HAS_ERROR = 1 ; +END ; +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION +BEGIN +GET DIAGNOSTICS CONDITION 1 +V_SQLSTATE = RETURNED_SQLSTATE , +V_SQLCODE = DB2_RETURNED_SQLCODE , V_ERRMSG = MESSAGE_TEXT ; +SET V_HTTP_STATUS = 500 ; +SET V_HAS_ERROR = 1 ; +END ; +-- Parse input parameters +SET V_DAYS = COALESCE ( INT ( JSON_VALUE ( IN_PARM , '$.days' ) ) , 30 ) ; +SET V_PLANT = COALESCE ( JSON_VALUE ( IN_PARM , '$.plant' ) , '' ) ; +SET V_DEPT = COALESCE ( JSON_VALUE ( IN_PARM , '$.department' ) , '' ) ; +SET V_WC = COALESCE ( JSON_VALUE ( IN_PARM , '$.workcenter' ) , '' ) ; +SET V_SITE = COALESCE ( JSON_VALUE ( IN_PARM , '$.site' ) , '' ) ; +-- Extract env handling all input formats (object, array, string) +SET V_IN_PARM = IN_PARM ; +WHILE CISTOOLS . JSON_TYPE ( V_IN_PARM ) IN ( 'object' , 'array' , 'string' ) +DO +SET V_IN_PARM = +CASE CISTOOLS . JSON_TYPE ( V_IN_PARM ) +WHEN 'object' THEN JSON_VALUE ( V_IN_PARM , '$.env' ) +WHEN 'array' THEN JSON_VALUE ( V_IN_PARM , '$[0]' ) +WHEN 'string' THEN REPLACE ( V_IN_PARM , '"' , '' ) +ELSE TRIM ( V_IN_PARM ) +END ; +END WHILE ; +SET ENV = V_IN_PARM ; +SET LL = CISTOOLS . SET_LIBRARY_LIST ( ENV ) ; +-- Validate environment was set +IF ENV = '' +OR ENV IS NULL THEN +RETURN +JSON_OBJECT ( +'error' : JSON_OBJECT ( +'http_status' : 400 , 'sqlstate' : '22001' , +'message' : 'Environment parameter is required' +) +) ; +END IF ; +-- Check for errors from library list setup +IF V_HAS_ERROR = 1 THEN +RETURN +JSON_OBJECT ( +'error' : JSON_OBJECT ( +'http_status' : V_HTTP_STATUS , 'sqlstate' : V_SQLSTATE , +'message' : V_ERRMSG +) +) ; +END IF ; +RETURN +WITH DATE_RANGE AS ( +SELECT +( ZONED ( CURRENT_DATE - V_DAYS DAYS ) - 19000000 ) +AS FROM_CY , +( ZONED ( CURRENT_DATE ) - 19000000 ) AS THRU_CY +FROM SYSIBM . SYSDUMMY1 +) , +-- Group by workcenter, site, and date from host file +DAILY_WC_DATA AS ( +SELECT TRIM ( P . KIWKCTR ) AS WKCTR , TRIM ( P . KISTID ) AS STID , +TRIM ( P . KIGRP1 ) AS PLANT , TRIM ( P . KIGRP2 ) AS DEPT , +P . KIDATE , SUM ( P . KIUP ) AS UP_SEC , +SUM ( P . KIUDWN ) AS UDWN_SEC , SUM ( P . KIGAP ) AS GAP_SEC , +SUM ( P . KIRCVD ) AS GOOD_QTY , SUM ( P . KISCRP ) AS BAD_QTY , +SUM ( P . KIEXPT ) AS TARGET_QTY +FROM SFCPERI P , DATE_RANGE R +WHERE P . KIDATE BETWEEN R . FROM_CY AND R . THRU_CY +AND TRIM ( P . KIGRP1 ) = COALESCE ( +NULLIF ( V_PLANT , '' ) , TRIM ( P . KIGRP1 ) ) +AND TRIM ( P . KIGRP2 ) = COALESCE ( +NULLIF ( V_DEPT , '' ) , TRIM ( P . KIGRP2 ) ) +AND TRIM ( P . KIWKCTR ) = COALESCE ( +NULLIF ( V_WC , '' ) , TRIM ( P . KIWKCTR ) ) +AND TRIM ( P . KISTID ) = COALESCE ( +NULLIF ( V_SITE , '' ) , TRIM ( P . KISTID ) ) +GROUP BY P . KIWKCTR , P . KISTID , P . KIGRP1 , P . KIGRP2 , +P . KIDATE +) , +DAILY_WC_OEE AS ( +SELECT WKCTR , STID , PLANT , DEPT , KIDATE , +DATE ( +TIMESTAMP_FORMAT ( +CHAR ( KIDATE + 19000000 ) , 'YYYYMMDD' ) ) +AS OEE_DATE , +INT ( +( COALESCE ( +( DECFLOAT ( UP_SEC - UDWN_SEC - GAP_SEC ) / +NULLIF ( DECFLOAT ( UP_SEC ) , 0 ) ) , 0 ) * +COALESCE ( +( DECFLOAT ( GOOD_QTY + BAD_QTY ) / +NULLIF ( DECFLOAT ( TARGET_QTY ) , 0 ) ) , 0 ) * +COALESCE ( +( DECFLOAT ( GOOD_QTY ) / +NULLIF ( DECFLOAT ( GOOD_QTY + BAD_QTY ) , 0 ) +) , 0 ) * 100 ) + 0.5 ) AS OEE_PCT , +INT ( +( COALESCE ( +( DECFLOAT ( UP_SEC - UDWN_SEC - GAP_SEC ) / +NULLIF ( DECFLOAT ( UP_SEC ) , 0 ) ) , 0 ) * 100 ) + +0.5 ) AS AVAILABILITY_PCT , +INT ( +( COALESCE ( +( DECFLOAT ( GOOD_QTY + BAD_QTY ) / +NULLIF ( DECFLOAT ( TARGET_QTY ) , 0 ) ) , 0 ) * 100 ) ++ 0.5 ) AS PERFORMANCE_PCT , +INT ( +( COALESCE ( +( DECFLOAT ( GOOD_QTY ) / +NULLIF ( DECFLOAT ( GOOD_QTY + BAD_QTY ) , 0 ) ) , +0 ) * 100 ) + 0.5 ) AS QUALITY_PCT +FROM DAILY_WC_DATA +) , +-- Build daily trend JSON for each workcenter +JSON_DAYS AS ( +SELECT WKCTR , STID , PLANT , DEPT , +JSON_OBJECT ( +'date' : TO_CHAR ( OEE_DATE , 'YYYY-MM-DD' ) , +'dayLabel' : TO_CHAR ( OEE_DATE , 'Dy' ) , +'oeePercentage' : OEE_PCT , +'availabilityPercentage' : AVAILABILITY_PCT , +'performancePercentage' : PERFORMANCE_PCT , +'qualityPercentage' : QUALITY_PCT +) AS DAY_OBJ , KIDATE +FROM DAILY_WC_OEE +) , +-- Aggregate trends by workcenter +JSON_WORKCENTERS AS ( +SELECT WKCTR , STID , PLANT , DEPT , +JSON_OBJECT ( +'workcenter' : CAST ( +WKCTR AS VARCHAR ( 5 ) CCSID 37 ) , +'site' : CAST ( STID AS VARCHAR ( 3 ) CCSID 37 ) , +'plant' : CAST ( PLANT AS VARCHAR ( 15 ) CCSID 37 ) , +'department' : CAST ( +DEPT AS VARCHAR ( 15 ) CCSID 37 ) , +'trends' : JSON_ARRAYAGG ( +DAY_OBJ FORMAT JSON +ORDER BY KIDATE +) +) AS WC_OBJ +FROM JSON_DAYS +GROUP BY WKCTR , STID , PLANT , DEPT +ORDER BY WKCTR , STID ) , +-- Calculate overall daily totals for summary +DAILY_TOTALS AS ( +SELECT KIDATE , +DATE ( +TIMESTAMP_FORMAT ( +CHAR ( KIDATE + 19000000 ) , 'YYYYMMDD' ) ) +AS OEE_DATE , SUM ( UP_SEC ) AS UP_SEC , +SUM ( UDWN_SEC ) AS UDWN_SEC , SUM ( GAP_SEC ) AS GAP_SEC , +SUM ( GOOD_QTY ) AS GOOD_QTY , SUM ( BAD_QTY ) AS BAD_QTY , +SUM ( TARGET_QTY ) AS TARGET_QTY +FROM DAILY_WC_DATA +GROUP BY KIDATE +) , +DAILY_TOTAL_OEE AS ( +SELECT KIDATE , OEE_DATE , +INT ( +( COALESCE ( +( DECFLOAT ( UP_SEC - UDWN_SEC - GAP_SEC ) / +NULLIF ( DECFLOAT ( UP_SEC ) , 0 ) ) , 0 ) * +COALESCE ( +( DECFLOAT ( GOOD_QTY + BAD_QTY ) / +NULLIF ( DECFLOAT ( TARGET_QTY ) , 0 ) ) , 0 ) * +COALESCE ( +( DECFLOAT ( GOOD_QTY ) / +NULLIF ( DECFLOAT ( GOOD_QTY + BAD_QTY ) , 0 ) +) , 0 ) * 100 ) + 0.5 ) AS OEE_PCT , +INT ( +( COALESCE ( +( DECFLOAT ( UP_SEC - UDWN_SEC - GAP_SEC ) / +NULLIF ( DECFLOAT ( UP_SEC ) , 0 ) ) , 0 ) * 100 ) + +0.5 ) AS AVAILABILITY_PCT , +INT ( +( COALESCE ( +( DECFLOAT ( GOOD_QTY + BAD_QTY ) / +NULLIF ( DECFLOAT ( TARGET_QTY ) , 0 ) ) , 0 ) * 100 ) ++ 0.5 ) AS PERFORMANCE_PCT , +INT ( +( COALESCE ( +( DECFLOAT ( GOOD_QTY ) / +NULLIF ( DECFLOAT ( GOOD_QTY + BAD_QTY ) , 0 ) ) , +0 ) * 100 ) + 0.5 ) AS QUALITY_PCT +FROM DAILY_TOTALS +) , +JSON_TOTAL_TRENDS AS ( +SELECT +JSON_OBJECT ( +'date' : TO_CHAR ( OEE_DATE , 'YYYY-MM-DD' ) , +'dayLabel' : TO_CHAR ( OEE_DATE , 'Dy' ) , +'oeePercentage' : OEE_PCT , +'availabilityPercentage' : AVAILABILITY_PCT , +'performancePercentage' : PERFORMANCE_PCT , +'qualityPercentage' : QUALITY_PCT +) AS DAY_OBJ , KIDATE +FROM DAILY_TOTAL_OEE +) SELECT JSON_OBJECT ( +'workcenters' : ( SELECT JSON_ARRAYAGG ( +WC_OBJ FORMAT JSON +) +FROM JSON_WORKCENTERS ) FORMAT JSON , 'totals' : ( +SELECT JSON_OBJECT ( +'trends' : JSON_ARRAYAGG ( +DAY_OBJ FORMAT JSON +ORDER BY KIDATE +) +) +FROM JSON_TOTAL_TRENDS ) FORMAT JSON , +'periodDays' : V_DAYS , 'generatedAt' : TO_CHAR ( +CURRENT_TIMESTAMP , 'YYYY-MM-DD HH24:MI:SS' ) +) +FROM SYSIBM . SYSDUMMY1 ; +END ; + +GRANT ALTER , EXECUTE +ON SPECIFIC FUNCTION RESTAPI.SFP_GET_OEE_TRENDS +TO AMAPICS WITH GRANT OPTION ; + +GRANT EXECUTE +ON SPECIFIC FUNCTION RESTAPI.SFP_GET_OEE_TRENDS +TO PUBLIC ; +