Function in where clause is executed and returns null instead a valid value

Hi all
i have a strange problem.
There is a access-application where i have a pass-through-sql.
This sql is fetching a foreign exchange rate from a history table which holds this rates for every day and i'm going to fetch the rate for the last day of the last month.
Example of the fraction which does not work and which i executed directly on the DB, Oracle 11.2.0.3.0:
select val
,last_day(add_months((trunc(sysdate)+3),-1)) tag
from k.obj_ts_hist th
where obj_id = 2660
and eff_date = last_day(add_months((trunc(sysdate)+3),-1))
--and      eff_date = '01-mar-2013'
eff_date on table k.obj_ts_hist is defined as date.
The function last_day in the where clause leads to null for both values in the select (val and tag).
If i use eff_date = '01-mar-2013' it's all ok, i get the rigth values.
I tested some combinations of the clause, e.g.
eff_date = to_date(to_char(last_day(add_months((trunc(sysdate)+3),-1)),'YYYYMMDD'),'YYYYMMDD')
or
to_char(eff_date,'YYYYMMDD') = to_char(last_day(add_months((trunc(sysdate)+3),-1)),'YYYYMMDD') , etc., but all of them do not work.
Also i tested the clause with select ... from dual, e.g.
select eff_date from
select last_day(add_months((trunc(sysdate)+3),-1)) eff_date from dual
where eff_date = last_day(add_months((trunc(sysdate)+3),-1))
This work's !
A cross check on Oracle 9.2.0.8.0: it works as expected !
Thanks in advance for your effort.
Regards, Konrad

a little simulation of your formula
select the_date,last_day(add_months((trunc(the_date) + 3),-1)) eff_date
  from (select to_date('20130224','yyyymmdd') + level - 1 the_date
          from dual
        connect by level <= 7
       )reveals you might have been querrying future rates
THE_DATE   EFF_DATE 
24.02.2013 31.01.2013
25.02.2013 31.01.2013
26.02.2013 28.02.2013  /* future date */
27.02.2013 28.02.2013  /* future date */
28.02.2013 28.02.2013  /* current date */
01.03.2013 28.02.2013
02.03.2013 28.02.2013Regards
Etbin

Similar Messages

  • Function in where clause being executed in subquery

    Oracle version 9.2.0.8
    I have a query of the form
    select cola
          ,colb
          ,expensive_function(colb) as colc
      from t
    where cola between 1 and 100This query returns 100 rows very fast.
    When I try to specify a where clause that uses the result of the expensive function the query takes 60 times longer (60 secs). Table t has a million rows.
    Long Query:
    select *
      from (
        select cola
              ,colb
              ,expensive_function(colb) as colc
          from t
         where cola between 1 and 100) t
    where colc = 'XXX'Could it be that Oracle is executing the function for each row in table t? I only want the function executed on the resultset but I can't seem to get it to work.
    Have tried many different hints and forms of the query without success, e.g.
    select *
      from (
        select cola
              ,colb
          from t
         where cola between 1 and 100) t
    where expensive_function(colb) = 'XXX'
    select /*+ NO_PUSH_PRED(t) */ *
      from (
        select cola
              ,colb
          from t
         where cola between 1 and 100) t
    where expensive_function(colb) = 'XXX'Message was edited by:
    SamB

    <s></s>Compare planing of two SQL, and post what is difference?
    @?/rdbms/admin/utlxplan
    explain plan for
    select cola
          ,colb
          ,expensive_function(colb) as colc
      from t
    where cola between 1 and 100
    @?/rdbms/admin/utlxpls
    explain plan for
    select *
       from (
        select cola
              ,colb
              ,expensive_function(colb) as colc
          from t
         where cola between 1 and 100) t
    where colc = 'XXX'
    @?/rdbms/admin/utlxpls
    explain plan for
    select cola
          ,colb
      from t
    where cola between 1 and 100
        and expensive_function(colb)='XXX'
    @?/rdbms/admin/utlxpls                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Clarification on using function in where clause of oracle sql query

    I have an issue in regarding function using where clause of sql query..
    We are facing performance issue while executing query, so in what ways to improve the performance of the query which i have posted below.
    select col ,case when my_function(parameter)
    from tab1 a ,tab2 b,tabl3 c
    where a.column1=b.column2
    and b.column3 =c.column6
    and my_function(parameter)>0
    Regards
    Dinesh
    Edited by: wild fire on May 18, 2012 4:15 PM

    Dinesh,
    remind that when you use a function in the where clause it normally will get started for each record in the table.
    So your answer is two-fold:
    1. make the function only start when needed by adding a function based index on the table (this will make inserts and updates slower)
    2. make the function faster by adding the DETERMINISTIC clause if possible. this will make Oracle "cache" the result of the function.
    Regards,
    Richard
    blog: http://blog.warp11.nl
    twitter: @rhjmartens
    If this question is answered, please mark the thread as closed and assign points where earned..

  • Help:alternate for calling function in where clause

    Hi ,
    In below query i'm calling function in where clause to avoid COMPLETE status records,due to this query taking 700 secs to return result.If i'm remove below function condition it's returning results with in 5 secs.Can you some one advice to any alternate idea for this?
    WHERE mark_status != 'COMPLETE'
    SELECT assessment_school,
      subject,
      subject_option,
      lvl,
      component,mark_status,
      mark_status
      NULL AS grade_status,
      NULL AS sample_status,
      :v_year,
      :v_month,
      :v_formated_date,
      :v_type,
      cand_lang
    FROM
      (SELECT assessment_school,
        subject,
        subject_option,
        lvl,
        programme,
        component,
        paper_code,
        cand_lang,
        mark_entry.get_ia_entry_status(:v_year, :v_month, assessment_school, subject_option, lvl, cand_lang, component, paper_code) AS mark_status
      FROM
        (SELECT DISTINCT ccr.assessment_school,
          ccr.subject,
          ccr.subject_option,
          ccr.lvl,
          ccr.programme,
          ccr.language AS cand_lang,
          ccr.paper_code,
          ccr.component
        FROM candidate_component_reg ccr
        WHERE ccr.split_session_year = :v_year
        AND ccr.split_session_month  = :v_month
        AND EXISTS
          (SELECT 1
          FROM IBIS.subject_component sc
          WHERE sc.year          = ccr.split_session_year
          AND sc.month           = ccr.split_session_month
          AND sc.paper_code      = ccr.paper_code
          AND sc.assessment_type = 'INTERNAL'
          AND sc.subject_option NOT LIKE '%self taught%'
          AND sc.component NOT IN ('PERFORMANCE  PRODUCTION','PRESENTATION WORK','REFLECTIVE PROJECT','SPECIAL SYLLABUS INT. ASSESSMENT')
        AND NVL(ccr.withdrawn,'N') = 'N'
        AND ccr.mark_status       != 'COMPLETE'
        AND EXISTS
          (SELECT 1
          FROM school s
          WHERE s.school_code   = ccr.assessment_school
          AND s.training_school = 'N'
    WHERE mark_status != 'COMPLETE';

    One thing you can test quickly is to put the function call in it's own select ...from dual.
    This might make a difference.
    However, only you can check this, I don't have your tables or data.
    So, what happens if you use:
        paper_code,
        cand_lang,
      (select mark_entry.get_ia_entry_status(:v_year, :v_month, assessment_school, subject_option, lvl, cand_lang, component, paper_code) from dual ) AS mark_status
      FROM
        (SELECT DISTINCT ccr.assessment_school,  --<< is the DISTINCT really needed?
          ccr.subject,
          ccr.subject_option,
    ...Also, try to find out the purpose of that above DISTINCT, is it really needed or is there some join missing?

  • My function in where clause? help me please.

    hello friends, I need to call my function in where clause as dummy example below:
    declare
    name_ table1.name%type;
    function return_id(id number) return number is
    begin
    return 1;
    end return_id;
    begin
    select name into name_
    from table1
    where id = return_id(table1.id);
    end;
    raise exception: 'the function doesn't used in where clause'. why????

    -- CREATING A FUNCTION AVAILABLE THROUGH A PACKAGE SPEC.
    SQL> ed
    Wrote file afiedt.buf
      1  create package mypackage is
      2    function myfunc(p_val NUMBER) RETURN NUMBER;
      3* end;
    SQL> /
    Package created.
    SQL> ed
    Wrote file afiedt.buf
      1  create or replace package body mypackage is
      2    function myfunc(p_val NUMBER) RETURN NUMBER IS
      3    begin
      4      RETURN (p_val*p_val)-1;
      5    end;
      6* end;
    SQL> /
    Package body created.
    SQL> declare
      2    v_myval NUMBER := 2;
      3  begin
      4    select mypackage.myfunc(v_myval)
      5    into   v_myval
      6    from   dual;
      7    dbms_output.put_line(v_myval);
      8    select mypackage.myfunc(v_myval)
      9    into   v_myval
    10    from   dual;
    11    dbms_output.put_line(v_myval);
    12  end;
    13  /
    3
    8
    PL/SQL procedure successfully completed.
    -- CREATING A STANDALONE DATABASE FUNCTION.
    SQL> create or replace function myfunc2(p_val number) return number is
      2  begin
      3    return (p_val*2)+1;
      4  end;
      5  /
    Function created.
    SQL> ed
    Wrote file afiedt.buf
      1  declare
      2    v_myval NUMBER := 2;
      3  begin
      4    select myfunc2(v_myval)
      5    into    v_myval
      6    from dual;
      7    dbms_output.put_line(v_myval);
      8    select myfunc2(v_myval)
      9    into    v_myval
    10    from dual;
    11    dbms_output.put_line(v_myval);
    12* end;
    SQL> /
    5
    11
    PL/SQL procedure successfully completed.
    -- CREATING A LOCAL FUNCTION IN THE ANONYMOUS PL/SQL BLOCK
    SQL> ed
    Wrote file afiedt.buf
      1  declare
      2    v_myval NUMBER := 2;
      3    function myfunc3(p_val number) return number is
      4    begin
      5      return (p_val*p_val*p_val);
      6    end;
      7  begin
      8    select myfunc3(v_myval)
      9    into    v_myval
    10    from dual;
    11    dbms_output.put_line(v_myval);
    12    select myfunc3(v_myval)
    13    into    v_myval
    14    from dual;
    15    dbms_output.put_line(v_myval);
    16* end;
    SQL> /
      select myfunc3(v_myval)
    ERROR at line 8:
    ORA-06550: line 8, column 10:
    PLS-00231: function 'MYFUNC3' may not be used in SQL
    ORA-06550: line 8, column 10:
    PL/SQL: ORA-00904: : invalid identifier
    ORA-06550: line 8, column 3:
    PL/SQL: SQL Statement ignored
    ORA-06550: line 12, column 10:
    PLS-00231: function 'MYFUNC3' may not be used in SQL
    ORA-06550: line 12, column 10:
    PL/SQL: ORA-00904: : invalid identifier
    ORA-06550: line 12, column 3:
    PL/SQL: SQL Statement ignored
    SQL>As you can see (and as previously mentioned by someone else) the function has to be available to the SQL engine either via a datavbase package or as a database function. If you declare the function locally within the anonymous PL/SQL block then the function only exists in the scope of that PL/SQL block and thus when your SQL statement is sent to the SQL engine for execution, the SQL engine can't see it.
    ;)

  • Using function in where clause

    I have created a function as follows
    create or replace FUNCTION get_codes RETURN varchar2 IS
    scodes varchar2(50) := 'A1,A2';
    BEGIN
    scodes := '('''||REPLACE(scodes,',',''',''')||''')';
    return scodes;
    END;
    this function returns ('A1','A2')
    now i want to use this in where clause, both below statements fetches no rows
    select * from tablea where code in (select get_codes from dual);
    select * from tablea where code in get_codes;
    but the following will fetch rows
    select * from tablea where code in ('A1','A2')
    how to use function in where clause
    Thanks

    Hi,
    The code that works:
    where code in ('A1','A2')is testing whther code is either of two 2-character strings, A1 or A2.
    The ones that don't work, such as:
    where code in get_codes;are comparing code to one 9-character string: 'A1','A2', where characters 1, 4, 6 and 9 are single-quotes. (The function can only return one value.)
    You can use dynamic SQL to embed that 9-character string in part of your query, where it will be interpreted as two 2-character strrings.
    [Oracle Base|http://www.oracle-base.com/articles/misc/DynamicInLists.php] and AskTom have good pages on the subject of dynamic IN-lists.
    Of you can use INSTR or LIKE:
    where INSTR ( get_codes
                , '''' || code || ''''
                ) > 0

  • Can't have aggregate function in WHERE clause clause

    Dear all,
    I've created object in BO XI 3.1 Designer with following criterias:
    http://img4.imageshack.us/img4/833/20111201124314.th.jpg
    It is a simple number - 1,2,3,4,5.
    Now I need to use this object as a criteria for WHERE function in another object.
    http://img607.imageshack.us/img607/1543/20111201124717.th.jpg
    I receive an error "Can't have aggregate function in WHERE clause <clause>"
    How can I overcome this?
    P.S. I'm sorry in advance if such topic already exist - I didn't found one.
    Edited by: Ashot Antonyan on Dec 1, 2011 9:50 AM
    Edited by: Ashot Antonyan on Dec 1, 2011 9:51 AM

    Hi,
    You will have to use Sub query to achieve this. Give more details on what is available and what you need then i could help you out with the complete solution.
    Thanks,
    Ravichandra K

  • Using round off function in where clause

    Hi All,
    I'm trying to use round off function in where clause, I seek help in completing this script.
    WITH CR_Details AS
    (Select
    request_id,
    parent_request_id,
    fcpt.user_concurrent_program_name Request_Name, phase_code, status_code,
    round((fcr.actual_completion_date - fcr.actual_start_date),3) * 24 * 60 as Run_Time,
    round(avg(round(to_number(actual_start_date - fcr.requested_start_date),3) * 1440),2) wait_time,
    fu.User_Name Requestor,
    fcr.argument_text parameters,
    to_char (fcr.requested_start_date, 'MM/DD HH24:mi:SS') requested_start,
    to_char(actual_start_date, 'MM/DD/YY HH24:mi:SS') ACT_START,
    to_char(actual_completion_date, 'MM/DD/YY HH24:mi:SS') ACT_COMP,
    fcr.completion_text
    From
    apps.fnd_concurrent_requests fcr,
    apps.fnd_concurrent_programs fcp,
    apps.fnd_concurrent_programs_tl fcpt,
    apps.fnd_user fu
    Where 1=1
    and fcr.concurrent_program_id = fcp.concurrent_program_id
    and fcp.concurrent_program_id = fcpt.concurrent_program_id
    and fcr.program_application_id = fcp.application_id
    and fcp.application_id = fcpt.application_id
    and fcr.requested_by = fu.user_id
    and fcpt.language = 'US'
    and fcr.actual_start_date like sysdate )
         select crd.*
         from CR_Details crd
         where Run_time <> '0'
         AND wait_time <> '0'
    GROUP BY
    crd.request_id,
    crd.parent_request_id,
    crd.fcpt.user_concurrent_program_name,
    crd.requested_start_date,
    crd.User_Name,
    crd.argument_text,
    crd.actual_completion_date,
    crd.actual_start_date,
    crd.phase_code,
    crd.status_code,
    crd.resubmit_interval,
    crd.completion_text,
    crd.resubmit_interval,
    crd.resubmit_interval_unit_code,
    crd.description
    Not sure about the GROUPBY function referencing the "crd." .

    Hi,
    The best thing for you to do is start over. Start as small as possible, then take baby steps.
    Pick one of the tables; fcr perhaps, and write a query that just uses that table, like this:
    SELECT    *
    FROM       apps.fnd_concurrent_requests     fcr
    WHERE       fcr.actual_start_date          >= TRUNC (SYSDATE)
    AND       fcr.actual_start_dt          <  TRUNC (SYSDATE) + 1
    ;(I think this is what you meant to do when you said "... LIKE SYSDATE".)
    Make sure this little query gets credible results. When that tiny query is working perfectly, add another line or two. You can cut and paste code from what you posted, if that helps you.
    If you get stuck, post the last version of your code that worked perfectly, and the latest version (only a line or two bigger) that has the problem. Describe what the problem is. If you get an error, post the complete error message. In any event, post CREATE TABLE and INSERT statements for all the tables and columns needed to run the query, and the results you want to get from that query.
    When you post any code, format it, so that how the code looks on the screen gives some clues about how it is working.
    When you post any formatted text on this site, type these 6 characters:
    \(small letters only, inside curly brackets) before and after each section of formatted text, to preserve spacing.
    If you going to use the AVG function in the sub-query, then you probably need to do a GROUP BY in the sub-query.
    If you're not using any aggregate functions (like AVG) in the main query, then you probably don't want to do a GROUP BY in the main query.
    I know this is a lot of work.  I'm sorry.  If there was an easier way, I wouldn't ask you to do all this.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Case function in where clause

    i insert the below rows in a table cash_book.
    PRJ_CODE PRJ_NAME
    1203 SHIFA
    1203 SHIFA
    1203 SHIFA
    1202 FATIMA
    1202 FATIMA
    1203 SHIFA
    if i select 1202 code then return 1202 code rows, if i select 1203 then returns 1203 code rows, if i select other than both values then returns all rows. how can i define in one query with use (case or decode function) in where clause ??

    perhaps something like this:
    create table test
    as
    select 1200 + rownum prj_code
      from dual
    connect by level <= 10;
    select * from test;
      PRJ_CODE
          1201
          1202
          1203
          1204
          1205
          1206
          1207
          1208
          1209
          1210
    var v_PRJ_CODE number
    exec :v_PRJ_CODE := 1200;
    select *
      from test
    where PRJ_CODE = :v_PRJ_CODE
        or 1 = case when :v_PRJ_CODE in (1202, 1203) then 0 else 1 end;
      PRJ_CODE
          1201
          1202
          1203
          1204
          1205
          1206
          1207
          1208
          1209
          1210
    exec :v_PRJ_CODE := 1203;
    select *
      from test
    where PRJ_CODE = :v_PRJ_CODE
        or 1 = case when :v_PRJ_CODE in (1202, 1203) then 0 else 1 end;
      PRJ_CODE
          1203Regards
    Martin

  • How can we use DECODE function in where clause.

    Hi Guys,
    I have to use DECODE function in where clause.
    like below
    select * from tab1,tab2
    where a.tab1 = b.tab2
    and decode(code, 'a','approved')
    in this manner its not accepting?
    Can any one help me on this or any other aproach?
    Thanks
    -LKR

    >
    I am looking for to decode the actual db value something in different for my report.
    like if A then Accepted
    elseif R then Rejected
    elseif D then Denied
    these conditions I have to check in where clause.
    >
    what are you trying to do?
    may be you are looking for
    select * from tab1,tab2
    where a.tab1 = b.tab2
    and
       (decode(:code, 'A','Accepted') = <table_column>
        or
        decode(:code, 'R','Rejected') = <table_column>
       or
        decode(:code, 'D','Denied') = <table_column>
       )

  • Which line in where clause gets executed first

    Hi everyone!
    I have some sqls which look like this
    select ...
    from table A, table B
    where a.name = b.name
    and a.name in (....)Now, which one of this is executed first? the where clause or the and clause?
    Joining the tables is preferably done in where clause?
    I am using Oracle 10g.
    Please give me some guidance.
    Thank You.
    Nith

    user645399 wrote:
    When I deal with very large tables I notice that it takes too long, so was wondering if I move the table join to the and clause, it can join and then apply the filter which could be faster instead of filtering and joining the table.Define "+too long+" - what metric and baseline are used?
    You need to have some kind of baseline of what acceptable performance is and then some metric to measure against the baseline to determine whether the process has acceptable performance or not.
    What I mean by this is that "+too long+" is an arbitrary statement that cannot be evaluated. It the workload is huge, that workload will take some time too process. If a workload is tiny, that will take less time to process.
    But "+too long+" gives no indication what the workload is. And "+large table+" is meaningless as a SQL against a billion row table can be minimal workload (e.g. unique index read), whereas a SQL against a small table can be a huge workload (e.g. cartesian join and full table scan).
    You first need to determine WHAT the workload is, before judging it as "+too slow+".
    I have no idea on how is the execution plan.And one of the first steps is looking at the execution plan. SQL code is source code (like C/C++ or Visual Basic source code). This cannot be executed - it needs to be parsed and compiled into an executable program.
    For C/C++ and Visual Basic, that is typically an +.exe+ or +.ddl+ executable. SQL source code is compiled into an executable program called a cursor. The execution plan of that cursor shows the structure of this program and what this program will (technically) do step-by-step.
    From the execution plan you can make calls such as, are the available indexes used optimally, did the CBO (the creator of the execution) made sane decisions based on the available data and stats it has for the tables and database?
    The execution plan can also highlight errors in the source code - for example, table foo is scanned twice using a full table scan. This does not make sense to hit the same data set twice in a single SQL - so why is the SQL source code written that way?
    The bottom line is that you need to know WHAT it is doing to determine if the performance is acceptable or not. If not, then you need to determine WHY it is doing what it is doing and whether there are better alternatives.

  • Bad performance when calling a function in where clause

    Hi All,
    I have a performance problem when executing a query that contains a function call in my where clause.
    I have a query with some joins and a where clause with some regular filters. But one of these filters is a function, and its input parameters are columns of the tables used in the query.
    When I run it with only a few rows in the tables, it goes ok. But as the number of rows grows, performance falls geometrically, even when my where clause filters the result to only a few rows.
    If I take the function call off of the where clause, then run the query and then call the function for each returned row, performance is ok. Even when the number of returned rows is big.
    But I need the function call to be in the where clause, because I can't build a procedure to execute it.
    Does anyone have any clue on how to improve performance?
    Thanks,
    Rafael

    You have given very little information...
    >
    If I take the function call off of the where clause, then run the query and then call the function for each returned row, performance is ok. Even when the number of returned rows is big. Can you describe how you measured the performance for a big result set without the function? For example lets say there had been 10.000 rows returned (which is not really big, but it is astarting point). Did you see all 10.000 rows? A typical mistake is to execute the query in some tool like Oracle SQL Developer or TOAD and measure how fast the first couple of rows are returned. Not the performance of the full select.
    As you can see from this little detail there are many questions that you need to address first before we can drill down to the root of your problem. Best way is to go through the thread that Centinul linked and provide all that information first. During the cause of that you might discover that you learn things on the way that help a lot for later tuning problems/approaches.
    Edited by: Sven W. on Aug 17, 2009 5:16 PM

  • Call of constant function in where clause

    Hi there,
    I want to execute the following query
    select a_field
    from a_table
    where another_field = a_func('10')
    where a_func is a stored function and returns a value dependent on its argument. Same argument returns same result. How to see, the argument is a_table-independent (constant), so the result is a constant. How can I prevent oracle from executing a_func for each row of a_table? I know, that the following code works:
    select a_field
    from a_table
    where another_field = (select a_func('10') from dual)
    but this less readable and harder to explain to low-level-users in my eyes. Is there any pragma or anything else I can do, so the first statement can executed with a single(!) execution of a_func?
    Thanks, ALu.
    null

    Unfortunately Variables do not help in this case. The query-text goes (in one of three uses) into a Delphi-TQuery-Object and after opening it the results are shown. Declaring Variables is not allowed this way. I want a single (very) easy(!) statement to be executed (see the first one above). To explain the use of the function is ok (instead of using any subselect this function calculates), but any subselect- or variable-usage is beyond most of my app-users that want access to the stored data. The solution must be found in declaration of a_func (to put it into a package an restrict it by WNPS, WNDS also did not help ...)
    Thanx anyway, ALu.
    <BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica">quote:</font><HR>Originally posted by Narayan Acharya ([email protected]):
    How about defining a variable, assigning it a value by calling the function, then using the variable in the where clause ?
    Trust that would work ?
    Narayan.<HR></BLOCKQUOTE>
    null

  • Regd. using functions in where clause

    Hi All,
    I need to apply a set of functions in sysdate and use that in a where clause to compare. My question is, will these functions on sysdate be executed for every record in the tables that I use? Will this have performance impact when i have millions of records returned by the select?
    Below is the scenario:
    Select * from table A inner join table B on A.c1 = B.c1 where
    TO_NUMBER(TO_CHAR(TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE, -1))),'YYYYMMDD')) BETWEEN Date1 and Date2
    Regards,
    Raj.D

    1005330 wrote:
    I need to apply a set of functions in sysdate and use that in a where clause to compare. My question is, will these functions on sysdate be executed for every record in the tables that I use? Will this have performance impact when i have millions of records returned by the select?
    Below is the scenario:
    Select * from table A inner join table B on A.c1 = B.c1 where
    TO_NUMBER(TO_CHAR(TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE, -1))),'YYYYMMDD')) BETWEEN Date1 and Date2
    Test it on a small data set - run a query and check the execution plan to see what the predicate section tells you.
    Oracle OUGHT to be smart enough to recognise that you've got a constant that it need only calculate once. If not, then change the usage to read:
        (select TO_NUMBER(TO_CHAR(TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE, -1))),'YYYYMMDD')) from dual) BETWEEN Date1 and Date2Note, by the way, that 'constant between col1 and col2' is generally a tough one as far as efficiency is concerned; it translates to:
        col1 <= constant
    and col2 >= constantIn many cases this means oracle has to access a large volume of data (for one of the predicates) and then filter that data (with the other predicate). A typical damage limitation strategy is to create an index on the two columns, arrangin the column order to minimise the range scan on the first column.
    Depending on your data patterns and the nature of the predicate there are alternative optimiisation strategies.
    Regards
    Jonathan Lewis

  • Urgent: Performance problem with where clause using IN and an OR condition

    Select statement is:
    select fl.feed_line_id
    from ap_expense_feed_lines_all fl
    where ((:1 is not null and
    fl.feed_line_id in (select distinct r2.object_id
    from xxdl_pcard_wf_routing_lists r2,
         per_people_f hr2
    where upper(hr2.full_name) like upper(:1||'%')
              and hr2.person_id = r2.person_id
    and r2.fyi_list is null
              and r2.sequence_number <> 0))
    or
    (:1 is null))
    If I modify the statement to remove the "or (:1 is null))" part at the bottom of the where clause, it returns in .16 seconds. If I modify the statement to only contain the "(:1 is null))" part of the where clause, it returns in .02 seconds. With the whole statement above, it returns in 477 seconds. Anyone have any suggestions?
    Explain plan for the whole statement is:
    (1) SELECT STATEMENT CHOOSE
    Est. Rows: 10,960 Cost: 212
    FILTER
    (2) TABLE ACCESS FULL AP.AP_EXPENSE_FEED_LINES_ALL [Analyzed]
    (2) Blocks: 8,610 Est. Rows: 10,960 of 209,260 Cost: 212
    Tablespace: APD
    (6) TABLE ACCESS BY INDEX ROWID HR.PER_ALL_PEOPLE_F [Analyzed]
    (6) Blocks: 4,580 Est. Rows: 1 of 85,500 Cost: 2
    Tablespace: HRD
    (5) NESTED LOOPS
    Est. Rows: 1 Cost: 4
    (3) TABLE ACCESS FULL XXDL.XXDL_PCARD_WF_ROUTING_LISTS [Analyzed]
    (3) Blocks: 19 Est. Rows: 1 of 1,303 Cost: 2
    Tablespace: XXDLD
    (4) UNIQUE INDEX RANGE SCAN HR.PER_PEOPLE_F_PK [Analyzed]
    Est. Rows: 1 Cost: 1
    Thanks in advance,
    Peter

    Thanks for the reply, but I have already checked what you are suggesting and I am pretty sure those are not causing the problem. The hr2.full_name column has an upper index and the (4) line of the explain plan shows that index being used. In addition, that part of the query executes on its own quickly.
    Because the sql is not displayed in an indented format on this page it is a little hard to understand the structure so I am going to restate what is happening.
    My sql is:
    select a_column
    from a_table
    where ((:1 is not null) and a_column in (sub-select statement)
    or
    (:1 is null))
    The :1 bind variable is set to a varchar2 entered on the screen of an application.
    If I execute either part of the sql without the OR condition, performance is good.
    If the :1 bind variable is null with the whole sql statement (so all rows or a_table are returned), performance is still good.
    If the :1 bind variable is a not-null value with the whole sql statement, performance stinks.
    As an example:
    where (('wa' is not null) and a_column in (sub-select statement)) -- fast
    where (('wa' is null)) -- fast
    where (('' is not null) and a_column in (sub-select statement) -- fast
    or
    ('' is null))
    where (('wa' is not null) and a_column in (sub-select statement) -- slow
    or
    ('wa' is null))

Maybe you are looking for