We are working on Oracle Database SQL Query.
DataBase Structure:
(etd_log_id, region,sla_status,escaltion_level,added_ts)
escalation_level field has:
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9
1,2,3,4,5,6,7,8,
1,2,3,4,5,6,7,
1,2,3,4,5,6,
1,2,3,4,5,
1,2,3,4,
1,2,3
1,2
1
Requirement: We need to send alert based on level as a input, Lets say we get 6 as a input, we should get all these records :
1,2,3,4,5,6,
1,2,3,4,5,
1,2,3,4,
1,2,3
1,2
1
Java passes level as input in the where clause
`WHERE CAST(REGEXP_SUBSTR(ESCALATION_LEVEL, '[^,]*$') AS NUMBER) <= 10<--Input from Java`
Approach: We developed a SQL query initially wherein we had this
CAST(REGEXP_SUBSTR(ESCALATION_LEVEL, '[^,]*$') AS NUMBER) <= 6--<input from java>
But it threw an error as
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
Upon RCA we came to know that REGEXP is treating the value into ASCII values. So we changed the condition by removing CAST as NUMBER from the CLAUSE.( WHERE (REGEXP_SUBSTR(ESCALATION_LEVEL, '[^,]*$') <= ‘10’)Now 10 is treated as a character and comparison is made on the basis of ascii values.
The code failed in testing . I did RCA for the same and came to know that 1 and 10 have same ASCII value as ‘49’.
So here is the interesting part. 1 and 10 have ASCII value as 49. 2,3,4,5,6,7,8,9 have ASCII values as 50,51,52,53,…
When it reaches level 10, it shows output for escalation level 1 and 10 ( as we have WHERE (REGEXP_SUBSTR(ESCALATION_LEVEL, '[^,]*$') < =‘10’) because it satisfies the condition <=49(ascii value) for level 1 as well as 10. Also, when it reaches 10, and then we provide any level between 2 and 9 we get level 10 also in the output.(obviously because now string has 10 in it with lower ASCII value to satisfy the condition)
What I want?
- Is there any way we can convert regexp and the level to same format? ( I tried with TO_NUMBER and CAST as NUMBER)
- Is there any other approach you would suggest to solve this issue?
Your help will be highly appreciated!
QUERY
SELECT CAST( REGEXP_SUBSTR(ESCALATION_LEVEL, '[^,]*$') AS VARCHAR2(200)) "LEVEL",
ETD_ALERT_LOG_ID ,REGION, REQUIRED_PERCENTAGE AS SLA_SET,
----------------- THIS PART FETCHES START TIME FOR EMAIL ALERT---------------------------------------------------
CAST(TO_CHAR(
(FROM_TZ((SELECT ADDED_TS FROM (SELECT ADDED_TS, DENSE_RANK() OVER (PARTITION BY REGION ORDER BY ADDED_TS DESC) RNK
FROM CHRT_SMTFOMGR.ETD_ALERT_LOG WHERE UPPER(REGION) = UPPER('Southern Ohio')
AND ESCALATION_LEVEL ='1' AND SLA_STATUS = 'Missed SLA'
AND ADDED_TS > (SELECT ADDED_TS FROM (SELECT ADDED_TS, DENSE_RANK() OVER (PARTITION BY REGION ORDER BY ADDED_TS DESC) RNK
FROM CHRT_SMTFOMGR.ETD_ALERT_LOG WHERE UPPER(REGION) = UPPER(EAL.REGION)
AND (SLA_STATUS = 'In SLA' OR IS_SEND_ALERT = 'N') )
WHERE RNK = 1 AND ROWNUM = 1)
AND TRUNC(FROM_TZ(ADDED_TS, (SELECT TZ_OFFSET(TO_CHAR(SYSTIMESTAMP,'TZR')) FROM DUAL ))
AT TIME ZONE (SELECT TIMEZONE FROM CHRT_SMTFOMGR.ETD_ALERT_CONFIG EAC
WHERE UPPER(EAC.REGION) = UPPER(EAL.REGION) AND ROWNUM=1))=
TRUNC(SYSTIMESTAMP AT TIME ZONE (SELECT TIMEZONE FROM CHRT_SMTFOMGR.ETD_ALERT_CONFIG
WHERE UPPER(REGION) = UPPER(EAL.REGION) AND ROWNUM=1)))
WHERE RNK = 1 AND ROWNUM = 1), (SELECT TZ_OFFSET(TO_CHAR(SYSTIMESTAMP,'TZR')) FROM DUAL ))
AT TIME ZONE (SELECT TIMEZONE FROM CHRT_SMTFOMGR.ETD_ALERT_CONFIG EAC
WHERE UPPER(EAC.REGION)= UPPER(EAL.REGION) AND ROWNUM=1))
- NUMTODSINTERVAL((SELECT VALUE FROM CHRT_SMTFOMGR.APP_PROPERTY
WHERE UPPER(NAME) = 'ETD_ALERT_ESCALATION_INTERVAL'),'MINUTE')
,'HH:MI AM') AS VARCHAR2(10)) ||' '|| (SELECT TIMEZONE FROM CHRT_SMTFOMGR.ETD_ALERT_CONFIG EAC
WHERE UPPER(EAC.REGION)= UPPER(EAL.REGION) AND ROWNUM=1) AS ALERT_START_TIME,
----------------------END OF START TIME **WORKS FINE**-------------------------
------------------FETCHES END TIME FOR EMAIL TEMPLATE-------------------------------------
CAST(TO_CHAR(
(FROM_TZ(ADDED_TS, (SELECT TZ_OFFSET(TO_CHAR(SYSTIMESTAMP,'TZR')) FROM DUAL ))
AT TIME ZONE (SELECT TIMEZONE FROM CHRT_SMTFOMGR.ETD_ALERT_CONFIG EAC
WHERE UPPER(EAC.REGION)= UPPER(EAL.REGION) AND ROWNUM=1))
,'HH:MI AM') AS VARCHAR2(10)) ||' '|| (SELECT TIMEZONE FROM CHRT_SMTFOMGR.ETD_ALERT_CONFIG EAC
WHERE UPPER(EAC.REGION)= UPPER(EAL.REGION) AND ROWNUM=1)
AS ALERT_END_TIME,
-------------------------END TIME **WORKS FINE----------------------------------------------------
TOTAL_ETD, (TOTAL_ETD - TOTAL_MET_SLA) AS UCM_SLA_MISSED_ETD, CURRENT_PERCENTAGE AS ACTUAL_SLA
FROM CHRT_SMTFOMGR.ETD_ALERT_LOG EAL
---------------------WHERE CLAUSE MENTIONED IN THE MAIL--------------------------------------------
WHERE CAST(REGEXP_SUBSTR(ESCALATION_LEVEL, '[^,]*$') AS NUMBER) <= 10
----------------------------------------------------------------------------------------------------
--------------PART TO FILTER REGION AND CHECK IF THE ALERT IS ON FOR SENDING EMAIL----
AND UPPER(EAL.REGION) = UPPER('Southern Ohio') AND IS_SEND_ALERT = 'Y'
-----------------PART TO CONVERT THE TIME ZONE INTO REGION BASED TIMEZONE SO THAT ALERT IS SENT ONLY DURING CONFIGURED START AND END TIME-------------------------------------------
AND TRUNC(FROM_TZ(ADDED_TS, (SELECT TZ_OFFSET(TO_CHAR(SYSTIMESTAMP,'TZR')) FROM DUAL ))
AT TIME ZONE (SELECT TIMEZONE FROM CHRT_SMTFOMGR.ETD_ALERT_CONFIG EAC
WHERE UPPER(EAC.REGION) = UPPER(EAL.REGION) AND ROWNUM=1))=
TRUNC(SYSTIMESTAMP AT TIME ZONE (SELECT TIMEZONE FROM CHRT_SMTFOMGR.ETD_ALERT_CONFIG EAC
WHERE UPPER(EAC.REGION) = UPPER(EAL.REGION) AND ROWNUM=1))
---PART TO CHECK IF THE TICKETS MEET SLA OR THE ALERT WAS DISABLED IN BETWEEN THE RECORDS THAT ARE TO BE FETCHED SHOULD BE AFTER THAT 'In SLA' RECORD-----------------------------------------------------------------------
AND ADDED_TS > (SELECT ADDED_TS FROM (SELECT ADDED_TS, DENSE_RANK() OVER (PARTITION BY REGION ORDER BY ADDED_TS DESC) RNK
FROM CHRT_SMTFOMGR.ETD_ALERT_LOG WHERE UPPER(REGION) = UPPER(EAL.REGION)
AND (SLA_STATUS = 'In SLA' OR IS_SEND_ALERT = 'N') )
WHERE RNK = 1 AND ROWNUM = 1)
ORDER BY ADDED_TS DESC;