Hey Laurent!
This script of mine was written in the late 90s to show, in part, session inactivity in Oracle7, so it had the inelegant solution of:
SELECT
TO_CHAR(TRUNC(last_call_et/86400),‘FM00’) || ‘::’ ||
TO_CHAR(TRUNC(MOD(last_call_et,86400)/3600),‘FM00’) || ‘:’ ||
TO_CHAR(TRUNC(MOD(MOD(last_call_et,86400),3600)/60),‘FM00’) || ‘:’ ||
TO_CHAR(MOD(MOD(MOD(last_call_et,86400),3600),60),‘FM00’) “INACTIVITY”
FROM V$SESSION;
Fast forward to 11gR2 and there must be a subjectively better way, right? Or, more importantly, one more elegant, now that I need to actually document this simple script for coworkers or other DBAs to use. The above script fragment is both embarrassing to me and it kicks in my OCD. So it must be fixed. After perfunctory web searching and some regex needling, I came up with this:
SELECT
REGEXP_SUBSTR(NUMTODSINTERVAL(last_call_et,‘SECOND’),’(0*)(\d{2,3} \d{2}:\d{2}:\d{2})’,1,1,‘i’,2) “INACTIVITY”
FROM V$SESSION;
I don’t know if this is the best solution, but much more elegant than the TRUNC/MOD one it replaces. I removed the sign, because a negative here would result in a time travel paradox, ending our universe as we know it. The first regex group globs as many leading zeros off of the day portion as it can, ultimately to be thrown away by REGEXP_SUBSTR. The second group first grabs the day, using only 2 or 3 digits, because I will never have a database up for more than three years. The last part of the second group just grabs two digits for each of hour, minute and second, in that order. I don’t need the fractional seconds for this, so they’re left off. The rest of the arguments for REGEXP_SUBSTR should be easy to glean from a doc page.
I really want your TO_CHAR/TIMESTAMP to work, but the dagblammed “day” is getting in the way of it being preferred over my regex. I still blame Oracle.
Thanks for the suggestion! But the compactness of my regex appeases my OCD more.
[B]
Rich