Skip to Main Content
  • Questions
  • FUNCTION with RESULT_CACHE and RELIES_ON... SYSDATE?

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, John.

Asked: November 09, 2015 - 5:05 pm UTC

Last updated: November 10, 2015 - 6:50 am UTC

Version: 11.2.0.3

Viewed 1000+ times

You Asked

Hi- My general understanding of function using result_cache is that if the underlying data has changed, the function knows to self-invalidate the cached result. What if the function doesn't use any underlying data, but is doing math off sysdate? How do we control the cached result invalidation?

A similar function to the example provided is from some big stupid looping legacy query to get the Sunday of any number of weeks out. Rather than rewrite the code to eliminate need for a function, I got lazy and threw a RESULT_CACHE on the function to speed everything up. All last week it correctly returned the Sunday of last week for select find_sunday(1) from dual. This Monday, it was still returning last Sunday! The result was still cached, and of course it should be; there is no table referenced in the function that would invalidate the cached result. I assume RELIES_ON could help me here, but all examples of RELIES_ON use a table name. I found I could get RELIES_ON(sysdate) to compile... but I presume that would invalidate immediately because it's never the same sysdate for long. On the flip side, that might never invalidate because sysdate isn't really "data" and it's definition is not changing ever. RELIES_ON(trunc(sysdate)) will not compile, but basically that's what I would be looking for in a function like this...

In the end I just got rid of the function (and the cursor, and the when others... you pick your battles), but I'm still left with the question of how to make logic-only, probably date based, function where the invalidation could be controlled?

Thanks, John


CREATE OR REPLACE FUNCTION FIND_SUNDAY (p_week_num IN NUMBER)
RETURN DATE RESULT_CACHE
IS
tmp_dt DATE;
tmp_num NUMBER;
BEGIN
tmp_dt := TRUNC (SYSDATE);
tmp_num := (p_week_num - 1) * 7;


IF p_week_num < 1
THEN
tmp_dt := TO_DATE ('01/01/2000', 'MM/DD/YYYY');
ELSE
SELECT (TRUNC (SYSDATE, 'd') + tmp_num) INTO tmp_dt FROM DUAL;
END IF;


RETURN (tmp_dt);
END FIND_SUNDAY;

and Connor said...


Some good info here

https://blogs.oracle.com/plsql-and-ebr/resource/How_To_Write_A_Safe_Result_Cached_Plsql_Function1.pdf

but one of the things that defines the "key", ie, to see if this function has been run and can use the result cache, is the parameters passed to it (obviously).

So in your example, if you were to *pass* the day (ie, trunc(sysdate) ) as a parameter, then when that value changes on the *call*, the cache would be invalidated (or more accurately, a new value for the 'next' day would be entered into the cache).

But its pretty rare to need a result cache for anything doesnt either do SQL or call something externally (like a webservice etc).

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Thanks for document link

John, November 10, 2015 - 3:27 pm UTC

Ok I basically get it. If you want to invalidate the function daily, send the date! Works for me.


More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library