Scaleability with Functions in SQL queries

Hi,
In one of our applications we have many views that use a packaged function in the where clause to filter data. This function uses a SYS_CONTEXT() to set and get values. There are couple of issues while using this approach:
1/ The deterministic function doesn't allow any scability with PQ-server.
2/ Another issue with this function and also the SYS_CONTEXT-function, they manuipulate the estimated CBO-statistics.
  CREATE TABLE TAB_I
  COLUMN1 NUMBER(16, 0) NOT NULL
, COLUMN2 VARCHAR2(20)
, CONSTRAINT TAB_I_PK PRIMARY KEY
    COLUMN1
  ENABLE
CREATE TABLE TAB_V
    I_COL1     NUMBER(16,0) NOT NULL ENABLE,
    VERSION_ID NUMBER(16,0) NOT NULL ENABLE,
    CRE_DATIM TIMESTAMP (6) NOT NULL ENABLE,
    TERM_DATIM TIMESTAMP (6) NOT NULL ENABLE,
    VERSION_VALID_FROM DATE NOT NULL ENABLE,
    VERSION_VALID_TILL DATE NOT NULL ENABLE,
    CONSTRAINT TAB_V_PK PRIMARY KEY (I_COL1, VERSION_ID) USING INDEX NOCOMPRESS LOGGING ENABLE,
    CONSTRAINT COL1_FK FOREIGN KEY (I_COL1) REFERENCES TAB_I (COLUMN1) ENABLE
CREATE OR REPLACE
PACKAGE      app_bitemporal_rules IS
FUNCTION f_knowledge_time RETURN TIMESTAMP DETERMINISTIC;
END app_bitemporal_rules;
create or replace
PACKAGE BODY      app_bitemporal_rules IS
FUNCTION f_knowledge_time RETURN TIMESTAMP DETERMINISTIC IS
BEGIN
     RETURN TO_TIMESTAMP(SYS_CONTEXT ('APP_USR_CTX', 'KNOWLEDGE_TIME'),'DD.MM.YYYY HH24.MI.SSXFF');
END f_knowledge_time;
END app_bitemporal_rules;
explain plan for select *
FROM tab_i
JOIN tab_v
ON tab_i.column1 = tab_v.i_col1
AND           app_bitemporal_rules.f_knowledge_time BETWEEN tab_v.CRE_DATIM AND tab_v.TERM_DATIM
where tab_i.column1 = 11111;
select * from table(dbms_xplan.display);
Plan hash value: 621902595
| Id  | Operation                    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT             |          |     1 |    95 |     5   (0)| 00:00:06 |
|   1 |  NESTED LOOPS                |          |     1 |    95 |     5   (0)| 00:00:06 |
|   2 |   TABLE ACCESS BY INDEX ROWID| TAB_I    |     1 |    25 |     1   (0)| 00:00:02 |
|*  3 |    INDEX UNIQUE SCAN         | TAB_I_PK |     1 |       |     1   (0)| 00:00:02 |
|*  4 |   TABLE ACCESS FULL          | TAB_V    |     1 |    70 |     4   (0)| 00:00:05 |
Predicate Information (identified by operation id):
   3 - access("TAB_I"."COLUMN1"=11111)
   4 - filter("TAB_V"."I_COL1"=11111 AND
              "TAB_V"."CRE_DATIM"<="APP_BITEMPORAL_RULES"."F_KNOWLEDGE_TIME"() AND
              "TAB_V"."TERM_DATIM">="APP_BITEMPORAL_RULES"."F_KNOWLEDGE_TIME"())
Note
   - 'PLAN_TABLE' is old version
   - dynamic sampling used for this statement (level=2)
explain plan for select *
FROM tab_i
JOIN tab_v
ON tab_i.column1 = tab_v.i_col1
AND           '10-OCT-2011' BETWEEN tab_v.CRE_DATIM AND tab_v.TERM_DATIM
where tab_i.column1 = 11111;
select * from table(dbms_xplan.display);  
Plan hash value: 621902595
| Id  | Operation                    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT             |          |   256 | 24320 |     5   (0)| 00:00:06 |
|   1 |  NESTED LOOPS                |          |   256 | 24320 |     5   (0)| 00:00:06 |
|   2 |   TABLE ACCESS BY INDEX ROWID| TAB_I    |     1 |    25 |     1   (0)| 00:00:02 |
|*  3 |    INDEX UNIQUE SCAN         | TAB_I_PK |     1 |       |     1   (0)| 00:00:02 |
|*  4 |   TABLE ACCESS FULL          | TAB_V    |   256 | 17920 |     4   (0)| 00:00:05 |
Predicate Information (identified by operation id):
   3 - access("TAB_I"."COLUMN1"=11111)
   4 - filter("TAB_V"."I_COL1"=11111 AND "TAB_V"."CRE_DATIM"<=TIMESTAMP'
              2011-10-10 00:00:00.000000000' AND "TAB_V"."TERM_DATIM">=TIMESTAMP' 2011-10-10
              00:00:00.000000000')
Note
   - 'PLAN_TABLE' is old version
   - dynamic sampling used for this statement (level=2)   As can be seen in the second plan the cardinality has been guessed correctly, but not in the first case.
I have also tried with:
ASSOCIATE STATISTICS WITH packages app_bitemporal_rules DEFAULT COST (1000000/*246919*/,1000,0) DEFAULT SELECTIVITY 50;
But, this just leads to a increased cost, but no change in cardinality.
The (1) problem gets solved if I directly use "TO_TIMESTAMP(SYS_CONTEXT ('APP_USR_CTX', 'KNOWLEDGE_TIME'),'DD.MM.YYYY HH24.MI.SSXFF')" in the where clause. But am not able to find a solution for the (2) issue.
Can you please help.
Regards,
Vikram R

Hi Vikram,
On the subject of using [url http://download.oracle.com/docs/cd/E11882_01/server.112/e26088/statements_4006.htm#i2115932]ASSOCIATE STATISTICS, having done a little investigation on 11.2.0.2, I'm having trouble adjusting selectivity via "associate statististics ... default selectivity" but no problems with adjusting default cost.
I've also tried to do the same using an interface type and am running into other issues.
It's not functionality that I'm overly familiar with as I try to avoid/eliminate using functions in predicates.
Further analysis/investigation required.
Including test case of what I've done so far in case anyone else wants to chip in.
SQL> select * from v$version;
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE    11.2.0.2.0      Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production
SQL> drop table t1;
Table dropped.
SQL>
SQL> create table t1
  2  as
  3  select rownum col1
  4  from   dual
  5  connect by rownum <= 100000;
Table created.
SQL>
SQL> exec dbms_stats.gather_table_stats(USER,'T1');
PL/SQL procedure successfully completed.
SQL>
SQL> create or replace function f1
  2  return number
  3  as
  4  begin
  5   return 1;
  6  end;
  7  /
Function created.
SQL>
SQL> create or replace function f2 (
  2   i_col1 in number
  3  )
  4  return number
  5  as
  6  begin
  7   return 1;
  8  end;
  9  /
Function created.
SQL> Created one table with 100000 rows.
Two functions - one without arguments, one with (for later).
With no associations:
SQL> select * from user_associations;
no rows selected
SQL> Run a statement that uses the function:
SQL> select count(*) from t1 where col1 >= f1;
  COUNT(*)
    100000
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID  gm7ppkbzut114, child number 0
select count(*) from t1 where col1 >= f1
Plan hash value: 3724264953
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT   |      |       |       |   139 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     5 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   |  5000 | 25000 |   139  (62)| 00:00:01 |
Predicate Information (identified by operation id):
   2 - filter("COL1">="F1"())
19 rows selected.
SQL> Shows that default selectivity of 5% for an equality predicate against function.
Let's try to adjust the selectivity using associate statistics - the argument for selectivity should be a percentage between 0 and 100:
(turning off cardinality feedback for clarity/simplicity)
SQL> alter session set "_optimizer_use_feedback" = false;
Session altered.
SQL>
SQL> ASSOCIATE STATISTICS WITH FUNCTIONS f1 default selectivity 100;
Statistics associated.
SQL> select count(*) from t1 where col1 >= f1;
  COUNT(*)
    100000
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID  gm7ppkbzut114, child number 1
select count(*) from t1 where col1 >= f1
Plan hash value: 3724264953
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT   |      |       |       |   139 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     5 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   |  5000 | 25000 |   139  (62)| 00:00:01 |
Predicate Information (identified by operation id):
   2 - filter("COL1">="F1"())
19 rows selected.
SQL> Didn't make any difference to selectivity.
An excerpt from a 10053 trace file had the following:
** Performing dynamic sampling initial checks. **
** Dynamic sampling initial checks returning FALSE.
  No statistics type defined for function F1
  No default cost defined for function F1So, crucially what's missing here is a clause saying:
No default selectivity defined for function F1But there's no other information that I could see to indicate why it should be discarded.
Moving on, adjusting the cost does happen:
SQL>exec spflush;
PL/SQL procedure successfully completed.
SQL> disassociate statistics from functions f1;
Statistics disassociated.
SQL>
SQL> ASSOCIATE STATISTICS WITH FUNCTIONS f1 default selectivity 100 default cost (100,5,0);
Statistics associated.
SQL> select count(*) from t1 where col1 >= f1;
  COUNT(*)
    100000
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID  gm7ppkbzut114, child number 0
select count(*) from t1 where col1 >= f1
Plan hash value: 3724264953
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT   |      |       |       |   500K(100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     5 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   |  5000 | 25000 |   500K  (1)| 00:41:41 |
Predicate Information (identified by operation id):
   2 - filter("COL1">="F1"())
19 rows selected.
SQL> And we see the following in a 10053:
  No statistics type defined for function F1
  Default costs for function F1 CPU: 100, I/O: 5So, confirmation that default costs for function were found and applied but nothing else about selectivity again.
I wondered whether the lack of arguments for function F1 made any difference, hence function F2.
Didn't seem to:
Vanilla:
SQL> select count(*) from t1 where col1 >= f2(col1);
  COUNT(*)
    100000
SQL>
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID  2wxw32wadgc1v, child number 0
select count(*) from t1 where col1 >= f2(col1)
Plan hash value: 3724264953
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT   |      |       |       |   139 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     5 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   |  5000 | 25000 |   139  (62)| 00:00:01 |
Predicate Information (identified by operation id):
   2 - filter("COL1">="F2"("COL1"))
19 rows selected.
SQL> Plus association:
SQL>exec spflush;
PL/SQL procedure successfully completed.
SQL>
SQL> associate statistics with functions f2 default selectivity 90 default cost (100,5,0);
Statistics associated.
SQL> select count(*) from t1 where col1 >= f2(col1);
  COUNT(*)
    100000
SQL>
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID  2wxw32wadgc1v, child number 0
select count(*) from t1 where col1 >= f2(col1)
Plan hash value: 3724264953
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT   |      |       |       |   500K(100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     5 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   |  5000 | 25000 |   500K  (1)| 00:41:41 |
Predicate Information (identified by operation id):
   2 - filter("COL1">="F2"("COL1"))
19 rows selected.
SQL> Just to confirm associations:
SQL> select * from user_associations;
OBJECT_OWNER                   OBJECT_NAME                    COLUMN_NAME                    OBJECT_TY
STATSTYPE_SCHEMA               STATSTYPE_NAME                 DEF_SELECTIVITY DEF_CPU_COST DEF_IO_COST DEF_NET_COST
INTERFACE_VERSION MAINTENANCE_TY
RIMS                           F2                                                            FUNCTION
                                                                           90          100           5
                0 USER_MANAGED
RIMS                           F1                                                            FUNCTION
                                                                          100          100           5
                0 USER_MANAGED
SQL> So.... started thinking about whether using an interface type would help?
SQL> CREATE OR REPLACE TYPE test_stats_ot AS OBJECT
  2  (dummy_attribute NUMBER
  3  ,STATIC FUNCTION ODCIGetInterfaces (
  4     ifclist                OUT SYS.ODCIObjectList
  5   ) RETURN NUMBER
  6  ,STATIC FUNCTION ODCIStatsSelectivity (
  7      pred                   IN  SYS.ODCIPredInfo,
  8      sel                    OUT NUMBER,
  9      args                   IN  SYS.ODCIArgDescList,
10      strt                   IN  NUMBER,
11      stop                   IN  NUMBER,
12      --i_col1                 in  NUMBER,
13      env                    IN  SYS.ODCIEnv
14   ) RETURN NUMBER
15  --,STATIC FUNCTION ODCIStatsFunctionCost (
16  --    func                   IN  SYS.ODCIPredInfo,
17  --    cost                   OUT SYS.ODCICost,
18  --    args                   IN  SYS.ODCIArgDescList,
19  --    i_col1                 in  NUMBER,
20  --    env                    IN  SYS.ODCIEnv
21  -- ) RETURN NUMBER
22  );
23  /
Type created.
SQL> CREATE OR REPLACE TYPE BODY test_stats_ot
  2  AS
  3   STATIC FUNCTION ODCIGetInterfaces (
  4    ifclist                OUT SYS.ODCIObjectList
  5   ) RETURN NUMBER
  6   IS
  7   BEGIN
  8    ifclist := sys.odciobjectlist(sys.odciobject('SYS','ODCISTATS2'));
  9    RETURN odciconst.success;
10   END;
11   STATIC FUNCTION ODCIStatsSelectivity
12   (pred                   IN  SYS.ODCIPredInfo,
13    sel                    OUT NUMBER,
14    args                   IN  SYS.ODCIArgDescList,
15    strt                   IN  NUMBER,
16    stop                   IN  NUMBER,
17    --i_col1                 in  NUMBER,
18    env                    IN  SYS.ODCIEnv)
19   RETURN NUMBER
20   IS
21   BEGIN
22     sel := 90;
23     RETURN odciconst.success;
24   END;
25  -- STATIC FUNCTION ODCIStatsFunctionCost (
26  --  func                   IN  SYS.ODCIPredInfo,
27  --  cost                   OUT SYS.ODCICost,
28  --  args                   IN  SYS.ODCIArgDescList,
29  --  i_col1                 in  NUMBER,
30  --  env                    IN  SYS.ODCIEnv
31  -- ) RETURN NUMBER
32  -- IS
33  -- BEGIN
34  --  cost := sys.ODCICost(10000,5,0,0);
35  --  RETURN odciconst.success;
36  -- END;
37  END;
38  /
Type body created.
SQL> But this approach is not happy - perhaps not liking the function with no arguments?
SQL> disassociate statistics from functions f1;
Statistics disassociated.
SQL> ASSOCIATE STATISTICS WITH FUNCTIONS f1 USING test_stats_ot;
Statistics associated.
SQL> select count(*) from t1 where col1 >= f1;
select count(*) from t1 where col1 >= f1
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-06550: line 12, column 22:
PLS-00103: Encountered the symbol "ÀÄ" when expecting one of the following:
) , * & = - + < / > at in is mod remainder not rem =>
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
SQL> So, back to F2 again (uncommenting argument i_col1 in ODCIStatsSelectivity):
SQL> disassociate statistics from functions f1;
Statistics disassociated.
SQL> disassociate statistics from functions f2;
Statistics disassociated.
SQL> ASSOCIATE STATISTICS WITH FUNCTIONS f2 USING test_stats_ot;
Statistics associated.
SQL> select count(*) from t1 where col1 >= f2(col1);
  COUNT(*)
    100000
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID  2wxw32wadgc1v, child number 0
select count(*) from t1 where col1 >= f2(col1)
Plan hash value: 3724264953
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT   |      |       |       |   139 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     5 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   |  5000 | 25000 |   139  (62)| 00:00:01 |
Predicate Information (identified by operation id):
   2 - filter("COL1">="F2"("COL1"))
19 rows selected.
SQL> Nothing obviously happening.
You'll note also in my interface type implementation that I commented out a declaration of ODCIStatsFunctionCost.
This post is probably already too long already so I've skipped some of the detail.
But when ODCIStatsFunctionCost was used with function F2, I presume I've made a mistake in the implementation because I had an error in the 10053 trace as follows:
  Calling user-defined function cost function...
    predicate: "RIMS"."F2"("T1"."COL1")
  declare
     cost sys.ODCICost := sys.ODCICost(NULL, NULL, NULL, NULL);
     arg0 NUMBER := null;
    begin
      :1 := "RIMS"."TEST_STATS_OT".ODCIStatsFunctionCost(
                     sys.ODCIFuncInfo('RIMS',
                            'F2',
                            NULL,
                            1),
                     cost,
                     sys.ODCIARGDESCLIST(sys.ODCIARGDESC(2, 'T1', 'RIMS', '"COL1"', NULL, NULL, NULL))
                     , arg0,
                     sys.ODCIENV(:5,:6,:7,:8));
      if cost.CPUCost IS NULL then
        :2 := -1.0;
      else
        :2 := cost.CPUCost;
      end if;
      if cost.IOCost IS NULL then
        :3 := -1.0;
      else
        :3 := cost.IOCost;
      end if;
      if cost.NetworkCost IS NULL then
        :4 := -1.0;
      else
        :4 := cost.NetworkCost;
      end if;
      exception
        when others then
          raise;
    end;
ODCIEnv Bind :5 Value 0
ODCIEnv Bind :6 Value 0
ODCIEnv Bind :7 Value 0
ODCIEnv Bind :8 Value 4
  ORA-6550 received when calling RIMS.TEST_STATS_OT.ODCIStatsFunctionCost -- method ignoredThere was never any such feedback about ODCIStatsSelectivity.
So, in summary, more questions than answers.
I'll try to have another look later.

Similar Messages

  • How to use WITH functionality in sql server

    How to get year wise total between two dates from invoice table , if table not contain Years also will be display
    Example:  10-04-2013 ,20-2-2015. These are From and To Dates
    Hear i want to display
      Total Amount           year
      Null                          2013
      10000000                2014
      NUll                         2015
    My table contain only  dates between 01-01-2014 to till date Records
     

    The use of a CTE is not required - and an actual calendar table should be.  You can find many many suggestions for building a calendar table (dynamically or permanently) by searching.  Your example is fairly trivial, but real data (in real quantities)
    will benefit from the calendar approach in a number of ways.  For future reference, have a look at the sticky posts at the top of the forum - they provide suggestions for posting questions and including useful, relevant, and needed information. 
    Among these are a script that can be used to demonstrate your issue.  Here is one example using a derived table - it can be easily changed to use a CTE for the current dates derived table (which you should try to do if that is your goal since you will
    learn more in the process):
    set nocount on;
    declare @table table (tran_date date, amount decimal(14,2));
    insert @table (tran_date, amount) values ('20140215', 100), ('20140430', 20.55);
    select *
    from @table as t inner join ( values (cast('20130101' as date), cast('20131231' as date)), ('20140101', '20141231'), ('20150101', '20151231')) as dates(d_start, d_end)
    on t.tran_date between dates.d_start and dates.d_end
    select year(dates.d_end) as [Year], sum(t.amount) as Total
    from @table as t right join ( values (cast('20130101' as date), cast('20131231' as date)), ('20140101', '20141231'), ('20150101', '20151231')) as dates(d_start, d_end)
    on t.tran_date between dates.d_start and dates.d_end
    group by dates.d_end
    order by dates.d_end

  • Using User Defined Function is SQL

    Hi
    I did the following test to see how expensive it is to use user defined functions in SQL queries, and found that it is really expensive.
    Calling SQRT in SQL costs less than calling a dummy function that just returns
    the parameter value; this has to do with context switchings, but how can we have
    a decent performance compared to Oracle provided functions?
    Any comments are welcome, specially regarding the performance of UDF in sql
    and for solutions.
    create or replace function f(i in number) return number is
    begin
      return i;
    end;
    declare
      l_start   number;
      l_elapsed number;
      n number;
    begin
      select to_char(sysdate, 'sssssss')
        into l_start
        from dual;
      for i in 1 .. 20 loop
        select max(rownum)
          into n
          from t_tdz12_a0090;
      end loop;
      select to_char(sysdate, 'sssssss') - l_start
        into l_elapsed
        from dual;
      dbms_output.put_line('first: '||l_elapsed);
      select to_char(sysdate, 'sssssss')
        into l_start
        from dual;
      for i in 1 .. 20 loop
        select max(sqrt(rownum))
          into n
          from t_tdz12_a0090;
      end loop;
      select to_char(sysdate, 'sssssss') - l_start
        into l_elapsed
        from dual;
      dbms_output.put_line('second: '||l_elapsed);
      select to_char(sysdate, 'sssssss')
        into l_start
        from dual;
      for i in 1 .. 20 loop
        select max(f(rownum))
          into n
          from t_tdz12_a0090;
      end loop;
      select to_char(sysdate, 'sssssss') - l_start
        into l_elapsed
        from dual;
      dbms_output.put_line('third: '||l_elapsed);
    end;
    Results:
       first: 303
       second: 1051
       third: 1515
    Kind regards
    Taoufik

    I find that inline SQL is bad for performance but
    good to simplify SQL. I keep thinking that it should
    be possible somehow to use a function to improve
    performance but have never seen that happen.inline SQL is only bad for performance if the database design (table structure, indexes etc.) is poor or the way the SQL is written is poor.
    Context switching between SQL and PL/SQL for a User defined function is definitely a way to slow down performance.
    Obviously built-in Oracle functions are going to be quicker than User-defined functions because they are written into the SQL and PL/SQL engines and are optimized for the internals of those engines.
    There are a few things you can do to improve function
    performance, shaving microseconds off execution time.
    Consider using the NOCOPY hints for your parameters
    to use pointers instead of copying values. NOCOPY
    is a hint rather than a directive so it may or may
    not work. Optimize any SQL in the called function.
    Don't do anything in loops that does not have to be
    done inside a loop.Well, yes, but it's even better to keep all processing in SQL where possible and only resort to PL/SQL when absolutely necessary.
    The on-line documentation has suggested that using a
    DETERMINISTIC function can improve performance but I
    have not been able to demonstrate this and there are
    notes in Metalink suggesting that this does not
    happen. My experience is that DETERMINISTIC
    functions always get executed. There's supposed to
    be a feature in 11g that acually caches function
    return values.Deterministic functions will work well if used in conjunction with a function based index. That can improve access times when querying data on the function results.
    You can use DBMS_PROFILER to get run-time statistics
    for each line of your function as it is executed to
    help tune it.Or code it as SQL. ;)

  • Conditional display of region with PL/SQL function returning SQL query

    Hello,
    ApEx 2.0.
    I use PL/SQL functions that return SQL queries to display the contents of a region.
    How could I conditionally display such region ? If no data is found, the region shouldn't be shown. I tried with "SQL query returns at least one row" but this doesn't seem to work.
    Thanks,
    Matthias

    Hi Matthias,
    Are the regions in question report regions? So your PL/SQL process is returning a SQL query and then populating a report?
    The EXISTS(SQL Query returns at least one row) condition should work, try running the query you are using in the Expression 1 textarea inside SQL*Plus, or SQL developer using the same parameters, and see what gets returned.
    If you are still stuck, can you post the query you are using inside your Expression 1 textarea of the Conditions section and I can take a look at it for you.
    Hope this helps,
    Cj

  • Erratic Report Region Behavior with Dynamic SQL Queries

    I'm running HTMLDB v 1.5.1.00.12 and I've noticed some odd behavior with report regions using dynamic SQL queries. Every so often, our testers will run a page containing a dynamic sql report region and get the following error, (despite the fact the query was working only moments ago and no other developer has touched it):
    ORA-06502: PL/SQL: numeric or value error: character string buffer too small
    or sometimes
    failed to parse SQL query:ORA-01403: no data found
    The only solution I've found so far is to:
    1) Make a copy of the failed report region.
    2) Disable or delete the original failed report region.
    The new copy of the report region runs without issue.
    My search of the forums turned up the following two threads, but neither provided me with a clear explanation of the cause, and how to avoid it:
    ORA-06502:PL/SQL: numeric or value error: character string buffer too small
    Re: Import Export Error (ORA-06502)
    The columns being returned are below the 4000 character limit, and the rows being returned are far less than 32k in size.
    Could this have anything to do with the way HTMLDB is internally storing the PL/SQL used to generate the dynamic SQL Query? Is there any known issue related to this with that version of HTMLDB?
    This problem occurs without any discernable pattern or consistency, making it hard to determine where I should focus my efforts in tracking down the cause.

    Hi all,
    My report seems to be behaving correctly once i set it to "Use Generic Column Names (parse query at runtime only)" :)
    Cheers,
    Joel

  • Tuning with functions in the SQL Query

    Hi there,
    I am trying to tune a query that has functions in the select section. Wondering how to see the results of the explain plan with these functions included. Is there a qs to include them when running the explain plan
    Thanks
    Hilton
    Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
    PL/SQL Release 11.2.0.3.0 - Production
    "CORE 11.2.0.3.0 Production"
    TNS for Linux: Version 11.2.0.3.0 - Production
    NLSRTL Version 11.2.0.3.0 - Production

    Not really. A function comprises SQL and PL/SQL. PL/SQL cannot possibly be included in an explain plan. Yet, you may take any SQL statement in a function and get its explain plan.
    As a hint, it is generally not good to include functions in the where clause of a query unless that query has some other filter condition that does a drastic filtering of the results. Running a function for tens of thousands of records may be a killer. In that case, it may be better to use joins and/or exists subquerries in you SQL rather than a function that opens a cursor.

  • How to use SQL functions in the queries

    hey guys i wanna know how to use SQL functions in the queries is it possible or not .

    Hi,
    Wat exactly that set values are?
    those from sql query?
    How to use count():
    The COUNT() function returns the number of rows that matches a specified criteria.
    SQL COUNT(column_name) Syntax
    The COUNT(column_name) function returns the number of values (NULL values will not be counted) of the specified column:
    SELECT COUNT(column_name) FROM table_name
    SQL COUNT(*) Syntax
    The COUNT(*) function returns the number of records in a table:
    SELECT COUNT(*) FROM table_name
    SQL COUNT(DISTINCT column_name) Syntax
    The COUNT(DISTINCT column_name) function returns the number of distinct values of the specified column:
    SELECT COUNT(DISTINCT column_name) FROM table_name
    The IN function helps reduce the need to use multiple OR conditions.
    The syntax for the IN function is:
    SELECT columns
    FROM tables
    WHERE column1 in (value1, value2, .... value_n);

  • Problem with DBMS_OUTPUT and SQL statment with a function

    I am using SQL Developer version 3.0.04 and I have a function that has a dbms_output statment in it. I am running the following SQL to select the output of that statment.
    select A.A_FUCTION('TEST') from dual;
    The output works fine but the dbms_output line does not show in the dbms_output window. I turned on the output window etc. and i can get the select to print out the output if i wrap it in a declare begin end wrapper... and then change the query to insert the return value into variable.
    just wondering if there is way to get the dbms_output to flush out with just an SQL statment instead of in a begin end wrapper etc.

    just wondering if there is way to get the dbms_output to flush out with just an SQL statment instead of in a begin end wrapper etc.works fine in sql*plus, so I guess it must be a preference or sth. in sql*developer:
    SQL> set serverout on
    SQL> create or replace function f1 (r int)
      2    return int
      3  as
      4  begin
      5    dbms_output.put_line ('Hello World ' || r);
      6    return r;
      7  end f1;
      8  /
    Function created.
    SQL>
    SQL> select f1 (rownum) f1 from dual connect by level <= 3
      2  /
            F1
             1
             2
             3
    3 rows selected.
    Hello World 1
    Hello World 2
    Hello World 3
    SQL>

  • Using 'Function Returning SQL Query' with Flash charts

    I have created a pl/sql function that returns a SQL query as a varchar2 of this form:
    select null link
    <x value> value
    <Series1 y value> Series 1 Label
    <Series2 y value> Series 2 Label
    <Series3 y value> Series 3 Label
    from tablea a
    join tableb b
    on a.col = b.col
    order by <x value>
    If I now call the function from a Flash Chart Series SQL box with the Query Source Type set to 'Function Returning SQL Query' like this:
    return functionname(to_date('30-sep-2010', 'dd-mon-yyyy'))
    it parses correctly and the page is saved; however, when I run the page I don't get any output - nor any error messages or other indication of a problem.
    Now, if I call the function in a SQL client, capture the SQL query output using dbms_output and paste that into the Flash Chart Series SQL box - changing the Query Source Type to SQL Query - and save the page it works fine when I run it and returns a multi-series flash chart.
    Can anyone suggest either;
    1. What have I might have missed or done wrong?
    2. Any way to usefully diagnose the problem...
    I have tried using the Apex debugger - which is very nice, by the way - but it doesn't provide any info on what my problem might be. I even tried writing my own debug messages from my function using the apex_debug_message package - got nothing...
    Thanks,
    Eric

    Hi Eric,
    Try expressing the source as this:
    begin
       return functionname(to_date('30-sep-2010', 'dd-mon-yyyy'));
    end;That works fine for me, and if I take out the begin-end and the trailing semicolon from the return statement I get the same behavior as you.
    It does mention in the help for the source (only during the wizard though) that this source type has to be expressed that way, but I agree it would be helpful if the tool would validate for this format when 'Function Returning SQL Query' is used or give some sort of indication of the trouble. Anyway, this should get you going again.
    Hope this helps,
    John
    If you find this information useful, please remember to mark the post "helpful" or "correct" so that others may benefit as well.

  • SQL Queries, filter with multiple radio Buttons

    I am trying to figure out how to filter my datagridview with SQL queries so that both of them have to be met for data to show up not just one.
    My datagridview is bound to an Access Database.
    I basically would want it filtered by 'Width' and 'Wood Type'
    I have radio buttons in group boxes so a width and wood can be selected. However only one Query is applied at a time.

    Public Class Form1
    Private Sub StickersBindingNavigatorSaveItem_Click(sender As Object, e As EventArgs)
    Me.Validate()
    Me.StickersBindingSource.EndEdit()
    Me.TableAdapterManager.UpdateAll(Me.TestDataSet)
    End Sub
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    'TODO: This line of code loads data into the 'TestDataSet.Stickers' table. You can move, or remove it, as needed.
    Me.StickersTableAdapter.Fill(Me.TestDataSet.Stickers)
    AcceptButton = Button1
    End Sub
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    End Sub
    Private Sub RadioButton1_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton1.CheckedChanged
    Try
    Me.StickersTableAdapter.Wood_Oak(Me.TestDataSet.Stickers)
    Catch ex As System.Exception
    System.Windows.Forms.MessageBox.Show(ex.Message)
    End Try
    End Sub
    Private Sub RadioButton2_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton2.CheckedChanged
    Try
    Me.StickersTableAdapter.Wood_Walnut(Me.TestDataSet.Stickers)
    Catch ex As System.Exception
    System.Windows.Forms.MessageBox.Show(ex.Message)
    End Try
    End Sub
    Private Sub RadioButton3_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton3.CheckedChanged
    Try
    Me.StickersTableAdapter.Width14(Me.TestDataSet.Stickers)
    Catch ex As System.Exception
    System.Windows.Forms.MessageBox.Show(ex.Message)
    End Try
    End Sub
    Private Sub RadioButton4_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton4.CheckedChanged
    Try
    Me.StickersTableAdapter.Width18(Me.TestDataSet.Stickers)
    Catch ex As System.Exception
    System.Windows.Forms.MessageBox.Show(ex.Message)
    End Try
    End Sub
    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    If RadioButton5.Checked = True Then
    If TextBox1.Text = "" Then
    Else
    Me.StickersBindingSource.Filter = "Width LIKE '" & TextBox1.Text & "%'"
    DataGridView1.Refresh()
    End If
    ElseIf RadioButton6.Checked = True Then
    If TextBox1.Text = "" Then
    Else
    Me.StickersBindingSource.Filter = "[Wood Type] LIKE '" & TextBox1.Text & "%'"
    DataGridView1.Refresh()
    End If
    ElseIf RadioButton5.Checked = False And RadioButton6.Checked = False Then
    MsgBox("Please Select a Search Criteria")
    End If
    End Sub
    Private Sub TextBox2_TextChanged(sender As Object, e As EventArgs) Handles TextBox2.TextChanged
    Try
    Me.StickersTableAdapter.SearchWood(Me.TestDataSet.Stickers)
    Catch ex As System.Exception
    System.Windows.Forms.MessageBox.Show(ex.Message)
    End Try
    End Sub
    End Class

  • Sql queries for retrieving setups data for functional modules

    Hi,
    Can anyone give me the sql queries for retrieving setups data for functional modules (GL, AP, AR, FA, and CM) from Database.

    Hi,
    Can anyone give me the sql queries for retrieving setups data for functional modules (GL, AP, AR, FA, and CM) from Database.

  • Problem with "&#34" using PL/SQL extract function ( XMLTYPE)

    Hi,
    When I use extract function (PL/SQL), it does not transform well "&#34". Insted of returning ' " ' , it returns ' &quot '.
    I know this works changing the code replacing xml.extract for SELECT extractvalue(xml,'//A/text()') into v from dual;
    But Is there another way to do this using PL/SQL? any patch, option..?
    Regards

    Hi,
    cursor proct is select * from proc22;
    cursor proct5 is select *from proc24;
    fetch proct into proctval;
    fetch proct5 into proctval5;
    if proct.symbol=proct5.symbolThat's strange to join two tables like this. You will have chance if you enter in your if condition.
    Why not create only one cursor with this join condition on the two tables ?
    re5:=re5/proctval.previousprice5;Furthermore, what do you make with r5 variable ? It seems nothing to do. Your proc does no much job.
    What do you want to achieve exactly ?
    Nicolas.

  • Generate ER Diagram with Sql Queries ?

    Hi Expertie,
    I am new to Oracle Sql Developer Data Modeler.
    I am having doubt in Oracle Sql Developer Data Modeler. Can we create ER Diagram with sql queries ?
    Ex: select Ename, EAge, Eemail, ESalary, DDept, Dname, Estatus from Emp E join Dept D on E.EmpId = D.Empid
          Where EAge in (20, 25, 30, 35)
    Please provide me the answer and suggestion. It will be greatful for me.
    Thanks & Regards
    Bhaskar

    Yes, you can engineer your physical model to a logical one, then you'll have an ERD as well. It's a right-click on the model I believe.
    To be more specific, if you relational model is loaded, you can use the button in the toolbar that looks like a double-blue-arrow, or you can mouse-right-click on your relational model in the tree. This will engineer your model to a logical one. You'll then have your ERD.
    Edited by: Jeff Smith SQLDev PM on Apr 29, 2013 9:53 AM

  • Links with sql queries to practice

    Hi all,
    Can someone give me the links with sql queries for practice to preparing for OCP
    Thanks
    Shekar.

    Hi,
    Can u repost?? as its very difficult to understand ur problem.
    Vasu Natari.

  • SQL Queries for open sales orders with no invoice.

    Hello all!
    Is there a way to make a query to find out if there are any uninvoiced sales orders older than 5 days?  I am having difficulty figuring out how the invoice is linked to the sales order.
    I am more familiar with excel than SQL but I'm guessing it will be similar to the following:
    SELECT * FROM ORDR WHERE today's date - posting date>5 AND (not sure what to check here for the invoice having been created)
    **Note: my syntax is of course not exactly correct, this is just to give you an idea of what I'm looking for
    Has anyone had to do this before or know how it would be done?  It would be very useful for me.
    Thanks!
    Mike

    Hi Mike
    The document link is built on row level so the RDR1 should be used instead of ORDR to server your propose.
    You could use this query to get all the lines do not link to a invoice.
    *targettype 13 refers to target document invoice
    select t0.docentry,t0.docdate,t0.linenum,t0.itemcode,t0.quantity,t0.price,t0.linetotal
    from rdr1 t0 join ordr t1 on t0.docentry= t1.docentry
    where t0.trgetentry is null and t0.DocDate < dateadd("d",-5, getdate()) and t1.docstatus = 'O'
    or just use this query instead to find those lines do not link to any document
    select t0.docentry,t0.docdate,t0.linenum,t0.itemcode,t0.quantity,t0.price,t0.linetotal
    from rdr1 t0 join ordr t1 on t0.docentry= t1.docentry
    where t0.targettype !='13' and t0.DocDate < dateadd("d",-5, getdate()) and t1.docstatus = 'O'
    Please modify the code according to your needs.
    Regards,
    Syn Qin
    SAP Business One Forums Team
    Edited by: Syn Qin on Aug 11, 2008 5:20 AM

Maybe you are looking for