CASE Condition Causing Plan Difference

Version
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
5 rows selected.
Optimizer
SQL> show parameter optimizer
NAME                                 TYPE        VALUE
_optimizer_autostats_job             boolean     FALSE
_optimizer_join_elimination_enabled  boolean     FALSE
optimizer_capture_sql_plan_baselines boolean     FALSE
optimizer_dynamic_sampling           integer     2
optimizer_features_enable            string      11.2.0.2
optimizer_index_caching              integer     0
optimizer_index_cost_adj             integer     100
optimizer_mode                       string      ALL_ROWS
optimizer_secure_view_merging        boolean     FALSE
optimizer_use_invisible_indexes      boolean     FALSE
optimizer_use_pending_statistics     boolean     FALSE
optimizer_use_sql_plan_baselines     boolean     TRUE
Problem
We have a vendor system that constructs the SQL to be sent to the database. These queries have the following generic structure for a WHERE clause condition:
CASE WHEN <condition> THEN <table>.<column> END = '<value>'We've noticed significantly different execution plans when the optimizer compares numbers instead of varchar2. The examples below demonstrate that. In our case this difference is impacting the execution plans of a larger query effectively doubling buffer gets and resulting in execution times that are 2-4 times as worse.
Query 1
SQL> SELECT /*+gather_plan_statistics*/ * FROM DUAL WHERE CASE WHEN 1=1 THEN 'X' END = dummy;
D
X
1 row selected.
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
SQL_ID  6ghjubgpwpr61, child number 0
SELECT /*+gather_plan_statistics*/ * FROM DUAL WHERE CASE WHEN 1=1 THEN
'X' END = dummy
Plan hash value: 272002086
| Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
|   0 | SELECT STATEMENT  |      |      1 |        |      1 |00:00:00.02 |       2 |      2 |
|*  1 |  TABLE ACCESS FULL| DUAL |      1 |      1 |      1 |00:00:00.02 |       2 |      2 |
Predicate Information (identified by operation id):
   1 - filter("DUMMY"='X')
Query 2
SQL> SELECT /*+gather_plan_statistics*/ * FROM DUAL WHERE CASE WHEN 'A'='A' THEN 'X' END = dummy;
D
X
1 row selected.
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
SQL_ID  gcpwzksqr2w9n, child number 0
SELECT /*+gather_plan_statistics*/ * FROM DUAL WHERE CASE WHEN 'A'='A'
THEN 'X' END = dummy
Plan hash value: 272002086
| Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
|   0 | SELECT STATEMENT  |      |      1 |        |      1 |00:00:00.01 |       2 |
|*  1 |  TABLE ACCESS FULL| DUAL |      1 |      1 |      1 |00:00:00.01 |       2 |
Predicate Information (identified by operation id):
   1 - filter("DUMMY"=CASE  WHEN ('A'='A') THEN 'X' END )In my eyes the condition 'A' = 'A' is equivalent to the condition 1=1. How come in the case of the numeric comparison Oracle can eliminate the case expression but in the character comparison it cannot?
Thanks!

Centinul wrote:
In my eyes the condition 'A' = 'A' is equivalent to the condition 1=1. Well, issue is Oracle looks at 'A' = 'A' as string comparison. And string comparison result is NLS setting dependent. That's why it can't evaluate CASE at compile time.
SY.

Similar Messages

  • Plant for PR in case of Centralized planning plant

    Dear All,
    In case of centralized planning, if a Service PR is created then  it is taking the plant as the planning plant & not the maintenance plant.
    For example: Maintenance pLant A & Maintenance Plant B have a common planning plant as "A" & if a PR is created for maintenance plant "B" then it is taking the plant as "A" & not the other.
    please suggest where we can change the plant in case of service pr created through the maintenance order.
    Regards,
    Ritesh

    Hi,
    The planning plant will always be passed to the purchase requisition as you have found. Only alternative is to use a user exit
    For components use exit COZF0002 (EXIT_SAPLCOZF_002). The exit is called on creating purchase requisitions for components from PM/CS orders. Customer exit COZF0001 can be used for external operations.
    This exit allows change of fields in structure EBAN_ORD_CUST. Field WERKS is not included in this structure but you can append this field to the structure.  After that you have to add a line into your exit (example):         
    ... move afvgd-werks to EBAN_ORD_CUST-WERKS...                      
    Through this method it should be possible to change the plant on the requisition.
    -Paul
    Use the forum Enterprise Asset Management (EAM) for PM/CS specific topics
    Enterprise Asset Management (SAP EAM)

  • How to change the status of test cases in Test Plan from Design to Ready using Excel VBA

    HI,
    How to change the status of test cases in Test Plan from Design to Ready using Excel VBA

    Thanks Florin,
    Your piece of code has worked alot, and it was very helpful in changing the Status of the Workitem to "READY" for all the Users fo the workitem.
    Points have been rewarded for your help.
    Process: We have acheived this using the "Work Item Exits", Usng "AFTER_EXECUTION" Method.
    Note: The Exit will be executed if "exit_cancelled"  statement is present/used in the work item method. if not it is not taking to the exit code. I'm unable to find the reason for it. Florin can u please explain this point.
    Please check the link for adding the code in Work Item Exits.
    http://wiki.sdn.sap.com/wiki/display/ABAP/ProgramExitsIn+Workflow
    Please find the Code:
    method IF_SWF_IFS_WORKITEM_EXIT~EVENT_RAISED.
    Get the context of the workitem
      me->wi_context = im_workitem_context.
    After execution of the workitem call the method AFTER_EXECUTION
      if im_event_name eq swrco_event_after_execution.
        me->after_execution( ).
      endif.
    endmethod.
    METHOD AFTER_EXECUTION.
    This method acts as the Event Handler for SWRCO_EVENT_AFTER_EXECUTION
      DATA: LCL_L_WID TYPE SWW_WIID,
            L_STATUS TYPE SWR_WISTAT-STATUS,
            L_NEW_STATUS  TYPE SWR_WISTAT,
            L_SWR_MESSAG  TYPE STANDARD TABLE OF SWR_MESSAG,
            L_SWR_MSTRUC  TYPE STANDARD TABLE OF SWR_MSTRUC.
    Get work item
      CALL METHOD WI_CONTEXT->GET_WORKITEM_ID
        RECEIVING
          RE_WORKITEM = LCL_L_WID.
      L_STATUS = 'READY'.
      CALL FUNCTION 'SAP_WAPI_SET_WORKITEM_STATUS'
        EXPORTING
          WORKITEM_ID    = LCL_L_WID
          STATUS         = L_STATUS
          USER           = SY-UNAME
          LANGUAGE       = SY-LANGU
          DO_COMMIT      = 'X'
        IMPORTING
          NEW_STATUS     = L_NEW_STATUS
         RETURN_CODE    = SY-SUBRC
        TABLES
          MESSAGE_LINES  = L_SWR_MESSAG
          MESSAGE_STRUCT = L_SWR_MSTRUC.
      IF SY-SUBRC EQ 0.
      ENDIF.
    ENDMETHOD.
    Thank You Once Again,
    Ajay Kumar Chippa

  • How to assign the parameter in case condition?

    Dear All,
    I have one procedure say p1. I want to pass one parameter like d_forcd = 'IN' and ALC_Code in ('11', '21', '31') from this procedure.
    In begin part I have one query. Can I pass this paramer in case condition in that query.
    If possible please hint me.
    Thanks in advance,
    Prathamesh.
    [pre]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

    There is probably a way using CASE, but it seems easier without:
    SQL> var param varchar2(10)
    SQL>
    SQL> exec :param := 'IN'
    PL/SQL procedure successfully completed.
    PARAM
    IN
    SQL> SELECT * FROM dual
      2  WHERE  (    :param = 'IN' AND dummy IN ('A','B','X','Y')
      3          OR  NVL(:param,'?') != 'IN' );
    D
    X
    1 row selected.Substitute your actual PL/SQL parameter for the SQL*Plus variable.

  • 9i 10g upgrade execution plan differences.

    Hi all,
    I am tring to find execution plan differences after I upgrade production system from 9i to 10gR2. So I have restored only needed tablespaces from my production system (9i) to a new machine and then upgraded thiat Oracle server to 10GR2. At this new server I run a script to get new execution plans of 10g. What suprises me is that query plans of 10g is different and most of new plans choose to access tables via indexes instead of full table scans stated in the original plans taken from 9i. My idea about those differences is that the optimizer takes some values for its cost formula from other system tables that I do not have in 10g server.I guess I am missing something which is not documented in upgrade book.
    any idea?
    Regards.

    9i database is my production database and I regularly run cron jobs for missing or stale statistics on all tables. So there is no possibility to hit a problem on object level statistics. I guess that I am missing something about system level statistics which are the part of the formula (single block read time etc) for cost calculating. So I tried to use setting some statastics via dbms_stat.set_system_statistics procedure, but it did not work.
    Any idea?
    Regards.
    ALPER ÖNEY

  • Case condition in where clause

    Hi
    I'm a SQL beginner but according to my reading of the manual, this syntax should be acceptable. I'm using it in application express but tested it also in SQL developer and finding that it fails with an "invalid relational operator" error, with the line number pointing to the ELSE clause of the CASE condition, but a column number pointing to white space.
    This is a nested select but that shouldn't matter. The fragment in question is this:
    select some columns
    from res
    where res.villaid = :P605_VILLAID
    and INSTR(:P604_RES_STATES, res.states) != 0
    and (CASE :P604_EXCLUDE_ZERO
    WHEN 'Y' THEN 'res.rate > 0'
    ELSE 'res.rate >= 0'
    END)
    and res.DEPARTDATE > :P605_STARTDATE
    and res.ARRIVEDATE <= :P605_ENDDATE,
    I hope this formats ok when posted. The code is looking for reservations in a date range (which works fine when the other conditions are commented out), and should only output zero-rate rows (complimentary nights) if the user asks for this in the P604_EXCLUDE_ZERO bind variable. There are probably other ways to go about this, but I am too stubborn to give up on this. Well, not yet anyway.
    Thanks and regards
    CS

    select some columns
      from res
    where res.villaid = :p605_villaid
           and instr (:p604_res_states, res.states) != 0
           and sign (res.rate) >= case when :p604_exclude_zero = 'Y' then 1 else 0 end
           and res.departdate > :p605_startdate
           and res.arrivedate <= :p605_enddate

  • Case condition

    Hi,
    this is some diff question from same logic,
    i wanted to use timestamp format in case condition
    case when start
    date > '2019-08-08 00:00:00' then TIMESTAMPDIFF(SQLTSI_MINUTE,"Esr"."Power Off",TIMESTAMP '2011-08-22 00:00:00' )
    getting error message
    Oracle Error code: 1843, message: ORA-01843: not a valid month at OCI call
    Pleasehelp
    thanks

    I think the real issue here is that you are dealing with 2 different datatype in one column...
    You have start_date which is date, but your timestampdiff fucntion will give you result in number. So the bottomline is that you can't have 2 different data type in one field..
    I'd leave start_date column as it is and create another field called timediff and use timestampdiff expression in that column. So column timediff column will give you results in number for all of the start dates..
    Then based on the result of timediff column, for example, if you can spot that for everything that the start date > 2019-08-08 00:00:00, the timediff value is > 300 (just an example). Then you can apply filter or even a case statement there to pick everything greater than 300..
    Let me know if it makes sense

  • Diff between two timestamp in minutes on case condition

    Hi Gurus,
    I wanted to find the diff between two timestamp in minutes on case condition
    when type=1 then min(col2) and type=2 then max(col2)
    type-(datatype-numeric)
    col2-(datatype-timestamp)
    how can i do this
    Thanks

    Hi,
    Is this a question about the Berkeley DB SQL product?
    If so, you should look at the documentation on time fields in the SQLite page here:
    http://www.sqlite.org/datatype3.html#datetime
    Otherwise, you are asking this on the wrong forum.
    Regards,
    Alex Gorrod
    Oracle Berkeley DB.

  • Case Condition not working

    I am trying to create a calculation based on the following case condition. For some reason its working fine on a existing report but now when I am creating a new report based on this, its giving error "Invalid Combinations of Condition and Calculations" any thoughts?
    I have also found out that when I am adding "ELSE" in the condition then only it's throwing that error otherwise working fine. I have also tried to recreate this case condition in my select statement and tested in TOAD and it runs without a problem.
    CASE WHEN ( Reference Date < TO_DATE(:Date) ) AND ( Support Start Date > TO_DATE(:Date) ) THEN TO_DATE(:Date) ELSE Reference Date END

    Try to wrap the "AND" and re-select the items into
    the case since it looks like the " are missing.
    CASE WHEN ( "Reference Date" < TO_DATE(:Date) AND
    "Support Start Date" > TO_DATE(:Date) ) THEN
    TO_DATE(:Date) ELSE "Reference Date" ENDTried that too but no luck :(. As I said before the same condition is working fine in another existing similar report. I am working on some changes in the existing report and when I am putting this condition it just throws this error message.
    Message was edited by:
    DiscoverDiscoverer

  • What are the cases that cause the I/O error writing to output file

    may i ask what are the cases that cause the I/O error writing to output file ??
    cause i have the write path and the input file has data
    any ideas???

    and the permission is to write first time then append to itBy "permission" is meant the operating system controlled rights that let
    particular users do specified things with specified files or directories.
    the error message is a the title of the message
    I/O error writing to output fileThe java runtime actually creates a much more useful error message than
    this but, unfortunately, your program is swallowing this error message and
    replacing it with the message you see.
    Somewhere in your code you have something like:try {
        // all sorts of stuff goes here
        // including the code that is intended to
        // write to the file
    } catch(IOException ioe) {
        System.out.println("I/O error writing to output file");
            // add this line
        //ioe.printStackTrace();
    }It might say Exception rather than IOException.
    To get a much more useful error message add the commented line.

  • Timestamp in minutes on case condition

    Hi Gurus,
    I wanted to find the diff between two timestamp in minutes on case condition
    when type=1 then min(col2) and type=2 then max(col2)
    type-(datatype-numeric)
    col2-(datatype-timestamp)
    how can i do this
    Thanks

    Hi,
    Sorry, the question could means diozens of different things.
    This is the answer to one of them:
    SELECT     id
    ,       ...   -- other columns from individual rows
    ,     MAX ( CASE
                WHEN  type = 2
                THEN     col2
               END
             ) OVER (PARTITION BY  id)
          -     MIN ( CASE
                WHEN  type = 1
                THEN     col2
               END
             ) OVER (PARTITION BY  id)     AS dif
    FROM    table_x
    ;The dif column will be an INTERVAL DAY TO SECOND., which you can convert to a number if you need to.
    Whenever you have a question, post a little sample data (CREATE TABLE and INSERT statements) and the results you want from that data. Explain how you get those results from that data.
    Always say what version of Oracle you are using.

  • IPhone leather case can cause scratches?

    Hi guys!
    I just bought the Apple iPhone leather case for my 5s, since i read so many positive reviews about it.
    I tried it on, and it feels very nice. No complains about that.
    But its really tight fit, so i had to struggle a while to take it off.
    My concern is: is it likely that the case can cause scratches on my phone, (especially corners and sides) when i put it on/take it off since its so tight?
    I feel like the tight fit could wear/scratch the frame because it take some struggle to remove it?

    Oceandreams wrote:
    I would like to get confirmation from Apple, since the Apple site is ambiguous!
    What's in the Box?
    iPhone 5s Case
    Compatibility
    Questions about compatibility? Call 1-800-MY-APPLE or Chat now
    iPhone models
    iPhone 5
    iPhone 5s
    Don't know how that could be ambiguous......

  • Case condition- color change

    Hi,
    i wanted to add a case condition in which it sshould change the colour of the row else none. it possible in obiee
    thanks

    Hi,
    Create a new column in your report with your case statement : CASE condition then 1 else 0 End (and hide it)
    Go to your column for which you want to change the color of the row the go to the properties and specify a conditional formatting based on your condition.
    If 1 then apply color elso nothing.
    Regards
    Adil

  • BOM is not getting displayed in case of centralized planning plant.

    Dear All,
    there are 2 plants for which we have centralized planning. the users have created Equipment BOM for the two plants. but in case of the second plant for which the planning plant is different from the maintenance plant, the BOM is not getting displayed in the Maintenance Order (i.e. in the components tab).
    kindly through some light on it. whether i have to do some settings for it.
    Regards,
    Ritesh Kapoor

    Hi,
    Yes while using IH01, i have ticked the BOM explosion option, but when i am giving the plant there then only it is displaying the BOM of that equipment.
    Also when i am creating an order for the same equipment, then it does not displays the BOm & shows the message which i have written in my previous mail.
    Ritesh

  • When using program RFDM3000/Automatic creation of dispute cases what is the difference with the option of Automatic incoming payment and Open items?

    We currently have a batch jobs running for each, automatic incoming payment and open items.  This was set up in the past and we are trying to determine what the difference is for each of these functions?  Do you need to have the automatic incoming run prior to the open items for residuals and payments on accounts?

    Hi Chris,
    Program RFDM3000 creates dispute cases for residual items arising during automatic incoming payments (account statement, lockbox), during check presentation, or in postprocessing.
    Alternatively, you can use the program to create dispute cases for open receivables items. You can use the selection criteria to restrict the quantity of open items (for example, using the document type and posting key for residual items from incoming payment postings).
    You will find more information in the link below
    http://help.sap.com/saphelp_erp2004/helpdata/en/0b/e07340b0c6980ae10000000a155106/content.htm
    Regards,
    Jose

Maybe you are looking for

  • How can I get an invoice for my ExportPDF subscription?

    Hi, i just paid the anulaste for my pdfexport licence, is there a way to get the reciept/check for the payment? i did not get an email confirmaron for the payment. Thanks

  • How to restore library from backup on external hard drive

    I am helping my wife move her library to a new computer after the old one crashed. I backed up my wife's music library to an external hard drive by simply copying and pasting all the files in her My Music >> iTunes folder into the external hard drive

  • ORA-01665 : control file is not a standby control file

    I've already tested Dataguard configuration on Oracle 10g Enterprise edition for Windows. While configuring the same in Sun Solaris, I'm receiving this error: ORA-01665: control file is not a standby control file Steps I follow are as below: 1) Creat

  • Q about DNS with PIX 501 as PPPoE client

    Hi! I've got PIX 501 (PixOS 6.3.5) acting as PPPoE client. Outside interface gets IP and DNS addresses from access concentrator. There is an example in config guide how to set DNS address (got from concentrator) for DHCH daemon in PIX, so clients in

  • Flash video into Dreamweaver 5.5

    I'm not a web designer but, I'm trying to keep cost down by building my own web site.  So, I'm re-building my website with Dreamweaver 5.5.  I'm using 5 flash videos to discribe what I do.  I made the movies and edited the movies in Final Cut Pro  an