Home > Blogroll, dba, sql > variable in a view

variable in a view

April 4th, 2007

Imagine you have a view and you want to have a parameter in your view. You cannot have a bind variable in your view. But you could have a function which return a package variable. And this package variable could be set manually for your session

Here we go

SQL> create or replace package p is n number; end p;
  2  /

Package created.

SQL> create or replace function f return number is 
  2  begin return p.n; end;
  3  /

Function created.

SQL> create or replace view v as select ename from 
  2  emp where empno=f;

View created.

SQL> select * from v;

no rows selected

SQL> exec p.n:=7788

PL/SQL procedure successfully completed.

SQL> select * from v;

ENAME
----------
SCOTT

  1. April 4th, 2007 at 14:35 | #1

    Simple and clever, thank you for sharing :)

  2. April 4th, 2007 at 15:08 | #3

    The alternative to a packaged global variable is an application context using SYS_CONTEXT.

  3. andrew
    April 4th, 2007 at 17:34 | #4

    Worth a read. Behavior may vary in later database versions…

    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1288401763279#3302928446952

  4. April 4th, 2007 at 17:48 | #5

    I’ve been using this technique for year. Everything started in Oracle 8 when pushing predicates into complex view didn’t work as expected. It solved many performance problems.

  5. Chris
    April 5th, 2007 at 13:20 | #6

    Stuff like this is very often used in “thick DB” or “database centric” approaches which I find very promising. Consider for example the papers of Toons Koppelaars (http://web.inter.nl.net/users/T.Koppelaars/).

    Using contexts will probably be faster, because it doesn’t involve a context switch to pl/sql and the optimizer can make better use of it. If you use a function, you might want to say it’s deterministic, btw.

  6. April 5th, 2007 at 14:48 | #7

    thanks all for the pointers to sys_context.

    Chris, the function is not deterministic

  7. Chris
    April 5th, 2007 at 19:10 | #8

    Thanks for mentioning that I am mistaken, Laurent. I was under the impression that the “deterministic” clause refers to the time span of running a sql statement, which is nonsense. You live and learn, e.g. not to rely on heresay but read the docs and test ;-)

  8. April 5th, 2007 at 21:00 | #9

    by the way I am reading your document with great interest. I am currently in a J2EE project where the database has no importance for the developers. So your document give me some lights about how to argue that there is something more than select/insert/update in an Oracle Database. I wonder if I ever will write about this. For the moment it is more political than technical, so now no post about hibernate and OptimalJ :evil:

  9. Chris
    April 6th, 2007 at 07:58 | #10

    Glad that you’re interested. The papers of Paul Dorsey (http://www.dulcian.com/Papers%20by%20topic/Methodology.htm) could help you in this discussion, too. The “The Thick Database Approach - Revisited” paper for example compares the development time / LOC of Java centric vs. database centric solutions. I suppose you will like the conclusion:

    “In our experience, moving code from the middle tier to the database had the following benefits:

    * Reduced the total amount of code
    * Reduced development time
    * Improved performance
    * Reduced network traffic
    * Reduced the complexity of the application

    Therefore, the thick database approach is a viable alternative to the conventional wisdom of reducing reliance on the database. It leverages existing database talent and can result in dramatic improvements in performance. The current trend in moving logic to the middle tier may have been premature given the experiences detailed in this paper.”

  10. April 7th, 2007 at 16:51 | #11

    I agree that this can be done. I’m missing something though. Why would you, why not just push predicate to the view when the view merge occurs (basically just using a where with this in the SQL that accesses the view)?

    That would be more effective as just one call needs to be executed. I’m sure this is useful somehow, but I’m not really sure when.

  11. April 7th, 2007 at 16:58 | #12

    it makes the view somehow dynamic, for example if the view is selected from a reporting tool like BO, you can hide the logic.
    I have never used it myself

  12. andrew
    May 10th, 2007 at 18:52 | #13

    Mathias: predicates can’t be pushed past agregating clauses like union, distinct, count, sum etc. (see Pawel’s comment above). For performance you usually want to get the filtering done at the earliest stage. Oracle fine grained access (FGAC) uses the “context” approach.

  1. No trackbacks yet.