PL/SQL Evaluation problem of where clause in case of  NUMBER column type

I found the following problem in Oracle® Database 2 Day Developer's Guide 11g Release 1 (11.1) B28843-04:
The sole parameter of function eval_frequency is employee_id IN employees.employee_id%TYPE.
An ORA-01422 exception occurs when the execution reaches the following select command
SELECT e.hire_date
INTO hire_date
FROM employees e
WHERE employee_id= e.employee_id;
A possible cause of the error is that the type of employee_id is NUMBER while the employees.employee_id is NUMBER(6,0) . The result of the selection is the same as there were no WHERE clause at all.
Everything worked fine, when I declared a temporary variable of NUMBER(6,0) for storing the actual parameter of function and used this variable in the where clause, but I consider this "solution" as being no solution.
It is pointless to use %TYPE parameter of a function for flexibility if I must degrade this flexibility by a fixed declaration of a temporary variable of the same type as the column in question.
What is wrong?
The Developer'Guide I used, the Oracle Sql Developer I used or the PL/SQL version ?

Hi,
Welcome to the forum!
user8949829 wrote:
A possible cause of the error is that the type of employee_id is NUMBER while the employees.employee_id is NUMBER(6,0) . The result of the selection is the same as there I don't think so. The variable employee_id is defined as having the exact same type as the eponymous column. Even if it didn't, I believe Oracle will always implicity convert between datatypes when possible, rounding if necessary. That may cause errors, but it isn't causing this error.
No, the error has nothing to do with the data type. It has to do with the ambiguity of employee_id: is it a column, or is it a variable?
The default is that it means the column name, so
WHERE   employee_id = e.employee_idis equivalent to saying
WHERE   e.employee_id = e.employee_idwhich isn't quite the same thing as not having a WHERE clause; rows with NULL employee_id would still be excluded, if there were any.
I think it's best not to use variable names that are the same as column names. You could call the variable v_employee_id, or, since it's an IN-argument, in_employee_id.
If you must use a variable that can be mistaken for a column, then qulaify it with the name of the procedure, like this:
WHERE   eval_frequency.employee_id = e.employee_id
Everything worked fine, when I declared a temporary variable of NUMBER(6,0) for storing the actual parameter of function That makes sens. You probably gave that variable a name that couldn't be mistaken for a column in the table.
Edited by: Frank Kulash on Jan 12, 2011 8:27 PM

Similar Messages

  • 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))

  • Improve the performance in stored procedure using sql server 2008 - esp where clause in very big table - Urgent

    Hi,
    I am looking for inputs in tuning stored procedure using sql server 2008. l am new to performance tuning in sql,plsql and oracle. currently facing issue in stored procedure - need to increase the performance by code optmization/filtering the records using where clause in larger table., the requirement is Stored procedure generate Audit Report which is accessed by approx. 10 Admin Users typically 2-3 times a day by each Admin users.
    It has got CTE ( common table expression ) which is referred 2  time within SP. This CTE is very big and fetches records from several tables without where clause. This causes several records to be fetched from DB and then needed processing. This stored procedure is running in pre prod server which has 6gb of memory and built on virtual server and the same proc ran good in prod server which has 64gb of ram with physical server (40sec). and the execution time in pre prod is 1min 9seconds which needs to be reduced upto 10secs or so will be the solution. and also the exec time differs from time to time. sometimes it is 50sec and sometimes 1min 9seconds..
    Pl provide what is the best option/practise to use where clause to filter the records and tool to be used to tune the procedure like execution plan, sql profiler?? I am using toad for sqlserver 5.7. Here I see execution plan tab available while running the SP. but when i run it throws an error. Pl help and provide inputs.
    Thanks,
    Viji

    You've asked a SQL Server question in an Oracle forum.  I'm expecting that this will get locked momentarily when a moderator drops by.
    Microsoft has its own forums for SQL Server, you'll have more luck over there.  When you do go there, however, you'll almost certainly get more help if you can pare down the problem (or at least better explain what your code is doing).  Very few people want to read hundreds of lines of code, guess what's it's supposed to do, guess what is slow, and then guess at how to improve things.  Posting query plans, the results of profiling, cutting out any code that is unnecessary to the performance problem, etc. will get you much better answers.
    Justin

  • Problems with WHERE CLAUSE in selects executed by BAPIs

    Dear Experts,
    I'm trying to make a SAP Java Connector. My problem is that, when they are called by Java, BAPI functions don't run in the same manner as in SAP testing mode .
    I tested two BAPI functions called through my connector and I saw with the debbuger that BAPI functions don't execute the select and loop at with a WHERE clause when they are called by Java, therefore they throw errors. But in the SAP testing mode functions work just fine.
    I'm  new to SAP and I don't know why this happens. Would you like to explain to me how to fix this problem?
    Thank you very much.
    Kind regards,
    Maricica

    979380 wrote:
    Yeah,i m sorry.I m a forum newbie.All right,we ve been given an oracle account for the purpose of this project,an we have connect to the oracle database either via linux terminal with sqlplus,or via oracle client and plsql.So i have to create some tables,then fill these tables with tuples(we ve been given fixed .sql files to do that),and we re suggested to do that from the linux terminal.I did that successfully.Then we have to run some queries either in terminal or plsql.I chose plsql.I connect,i can see the tables that i have created but when i run(in both sql and terminal window) for example the query "select * from table_1",i take 0 rows as a result.I tested to run the query from terminal(with sqlplus) to see if the tables are really empty,but i recieve the results as i should.
    I am sorry for my chaotic writing but i cant even explain the problem to myself better and i m not a native.
    (im using oracle version 11.2.0.1, this is the first time i m using oracle databases and i m a rookie in databases in general)
    Edited by: 979380 on 1 Ιαν 2013 10:33 πμ
    [oracle@localhost ~]$ sqlplus user1/user1
    SQL*Plus: Release 11.2.0.2.0 Production on Tue Jan 1 11:19:29 2013
    Copyright (c) 1982, 2010, Oracle.  All rights reserved.
    Connected to:
    Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    SQL> create table table_1 (id number);
    Table created.
    SQL> select * from table_1;
    no rows selected
    SQL> insert into table_1 values(1);
    1 row created.
    SQL> select * from table_1;
            ID
             1
    SQL> in order to SELECT any rows from any table, first you must INSERT data into the table!
    is COPY & PASTE broken for you?

  • Query SQL datastore with XML where clause source

    Hope I am in the right place.  New to Bus Obj Data Services Designer....I have cerated xml schemas, added it to the page as an xml source in.  Mapped a test xml file and all is well there.  I have added a query that grabs the xml.
    I need to then query the MS SQL datastore ans use  the data form the xml query as the where clause.  How is this done?  Or do I put a query on the datastore for all the data in a table then do anotehr query filtering one with the other?  seems like that would be rather heavy and low performance.  The results will then be sent back out as xml (schema and test file already set up as an xml out)
    Thanks!

    Thanks for the tips.
    I'm trying to implement this option, using your ViewDefHelper.
    I´m running into a problem though. After I create my dynamic View Object using a ViewDef, I need to create some view links.
    So I get the AttributeDefs of the columns (source, and destination) from the method findAttributeDef (which is the whole purpose of performance in my post). This method is returning the correct Attribute Def, but when I create the view Link with the method createViewLinkBetweenViewObjects(java.lang.String vlName,
    java.lang.String accessorName,
    ViewObject master,
    AttributeDef[] srcAttrs,
    ViewObject detail,
    AttributeDef[] destAttrs,
    java.lang.String assocClause)
    My destination query is generating the where clause as:
    null = ?
    Any Ideas what I'm doing wrong ?
    Thanks again.
    John.

  • PreparedStatement.setDate(int, Date) problem in WHERE clause

    Hello all,
    First and foremost, thanks for the help. It is really appreciated.
    I am having the toughest time tracking down a problem with how I am handling date setting with my PreparedStatement. The kicker is that I am only having problems with the where clause date sets.
    The date is pulled out of the database, put into a string, modified, put back into a date, and then used to query via SQL.
    Data selected this way:
    "SELECT * FROM table_name"
    Data updated this way:
    "UPDATE table_name SET name = ? WHERE pk_id = ? AND pk_date = ?"
    The java.sql.Date object I use to PreparedStatement.setDate(int, Date) is exact to seconds. It works great if it is not in the where clause (eg Inserts work, Updates work without where clause) which leads me to believe there is truncation of data somewhere between setDate(int, Date) and the native SQL in Oracle 9i.
    Is that a correct assumption? How do I solve this?
    Thanks,
    John

    My assumption was correct. If a java.sql.DATE is pulled from a Oracle 9i database it may have more data in it than is allowed for in java.sql.Date. java.sql.Timestamp, on the other hand, does retain all data in the field.
    The correct code looks something like this
    prepStmt.setTimestamp(Timestamp.valueOf(timeString));
    cheers,
    John

  • Problem in case of or condition in  where clause in case of leftouter joi.

    hi
    i am encountering a wierd problem.
    in a select query if i have a left outer join and a or condition in where clause the order of condition in or matters and if i use a to_char problem is solved.
    see query below
    select * from custsupp left outer join Salesperson s on custsupp.sales_rep = s.id ,state a where (CS_FLAG='C' or CS_flag ='B') and custsupp.state = a.id
    i have a single record in table custsupp with CS_FLAG ='B' the above does not return result. but if i move CS_FLAG='B' on left of or i.e
    select * from custsupp left outer join Salesperson s on custsupp.sales_rep = s.id ,state a where (CS_FLAG='B' or CS_flag ='C') and custsupp.state = a.id
    i get the rsult.
    also if i remove left outer join and keep order of condition as it is i get result i.e
    select * from custsupp ,state a where (CS_FLAG='C' or CS_flag ='B') and custsupp.state = a.id
    also if i add a to_char to co,umns CS_FLAG i get the result.
    select * from custsupp left outer join Salesperson s on custsupp.sales_rep = s.id ,state a where (to_char(CS_FLAG)='C' or to_char(CS_flag ='B')) and custsupp.state = a.id
    why it is so?
    CS_flag is of type nchar
    Shreyas
    Edited by: shreyasd on Jun 9, 2010 11:07 PM

    First if you don't want to take credit of the free sample then follow the below procedure:
    1. Do the GRN for all the three item and for the free item in the excise tab at the item level select the material as non cenvatable. Just remember to add base value of the item
    2.  If you want to capture the Part1 entry then just do the normal transaction and while posting the excise with J1IEX just remove the excise duties for the free item.
    3. For paying the vendor the excise amount, just do subsequent debit in the MIRO and in the details tab add in the unplanned delivery cost the amount that you want to pay for the excise duties
    Second case if you want to take credit of the duties:
    1. Do the Normal GRN process, add the base value and excise values for the free item.
    2. Post the Excise duites with J1iEX.
    3. The with the account entry you can settle the excise payment
    Hope this will help you
    Enjoyyyyyyyyyyy
    Akshit

  • How to define SQL that contains "in" where clause in VO?

    I don't want to define "in" caluse in a programatical way in VO like below. I want to use a declariable way to define in clause using varaible bindings.
    Can it be implemented?
        private String getInClauseWithParamNames(List termCodes) {
               //logic to form the in clause with multiple bind variables
               StringBuffer inClause = new StringBuffer();
               if(termCodes !=null){
                   for (int i = 1; i < termCodes.size() + 1; i++) {
                       inClause.append(":termC" + (i));
                       if (i < termCodes.size()) {
                          inClause.append(",");
               return inClause.toString();
        public Row[] getYardFixedSlots(List termCodes) {
            if(termCodes != null && !termCodes.isEmpty()){
                String inClause = getInClauseWithParamNames(termCodes);
                //setting the where cluase to use the generated in clause
                this.setWhereClause("YardFixedSlot.TERMINAL_C in (" + inClause + ")");
                ////clearing all existing where clause params if any
                this.setWhereClauseParams(null);
                if(getVariableManager() !=null){
                   this.getVariableManager().clearVariables();
                //setting values for all bind variables one by one in the in clause
                for (int i = 0; i < termCodes.size(); i++) {
                    //defining the named bind variables programatically
                    this.defineNamedWhereClauseParam("termC" + (i + 1), null, null);
                    //setting the value for each named bind variable
                    this.setNamedWhereClauseParam("termC" + (i + 1), termCodes.get(i));
                this.setRangeSize(-1);
                //executing the query
                this.executeQuery();
            //returning the rows from query result
            return this.getAllRowsInRange();

    I test it using model tester.
    I try to write a test program to test it. when run it in jdeveoper, why it always run model tester instead of run my test program?
    package com.psa.citos.ypc.model.views.shift;
    import oracle.jbo.ApplicationModule;
    import oracle.jbo.Row;
    import oracle.jbo.RowSet;
    import oracle.jbo.ViewObject;
    import oracle.jbo.client.Configuration;
    public class TestClient {
        public static void main(String[] args) {
            TestClient testClient = new TestClient();
            String        amDef = "com.psa.citos.ypc.model.services.AppModule";
            String        config = "AppModuleLocal";
            ApplicationModule am = Configuration.createRootApplicationModule(amDef,config);
            // Work with your appmodule and view object here
            // 1. Find the vessel view object instance.
            FindVesselListByVVCodesImpl vesselList = (FindVesselListByVVCodesImpl)am.findViewObject("FindVesselListByVVCode1");
            vesselList.setvv_csv_list("23981,23818,23132");
            // 2. Execute the query
              vesselList.executeQuery();
              // 3. Iterate over the resulting rows
              while (vesselList.hasNext()) {
                  Row customer = vesselList.next();
                  // 4. Print the person's email
                  System.out.println("AbbrVesselM: " + customer.getAttribute("AbbrVesselM"));
            Configuration.releaseRootApplicationModule(am, true);

  • Performance Tuning on a table where WHERE clause is having only PK columns

    Hi folks!!
    Here is the gotcha!!!!
    I am having a table, named X, with primary key columns A and B.
    I running a packaged procedure in which there is a SELECT statment to get the record from the table X with WHERE condition on A and B columns. Now the problem is, the package is taking too much amount of time to get executed.
    Eventually, I used TKPROF utility on the trace file of that package execution.
    The trace file is showing that huge amount of time is spent on the SELECT statement of table X, as I said above.
    I am baffled why it is taking that much of time eventhough the columns in the WHERE clause are Primary Key columns only and that too there are in the sequential order as that of in primary key contituent sequence.
    I would be very grateful to you guyz... plz help me out of this one....
    Cheers...........PCZ

    Also can you use preformatting as requested above, so
    that we can read it?
    [pre]Your preformatted
    text[/pre]
    Hi William,
    Plz find the requested:
    SELECT *
    FROM
    STTMS_CUST_ACCOUNT WHERE BRANCH_CODE=:B2 AND CUST_AC_NO=:B1
    call     count       cpu    elapsed       disk      query    current        rows
    Parse      180      0.00       0.04          0          0          0           0
    Execute  56538      0.96       4.02          0          0         26           0
    Fetch    56512   5581.98   19547.83         12 1134505869          6       56512
    total   113230   5582.94   19551.89         12 1134505869         32       56512
    Misses in library cache during parse: 0
    Optimizer mode: ALL_ROWS
    Parsing user id: 42  (FLEXMIG)   (recursive depth: 1)
    Rows     Row Source Operation
        325  TABLE ACCESS BY INDEX ROWID STTM_CUST_ACCOUNT (cr=6427406 pr=1 pw=0 time=327599336 us)
    10064925   INDEX RANGE SCAN IND_DORMANCY (cr=46475 pr=0 pw=0 time=15740976 us)(object id 512984)
    Rows     Execution Plan
          0  SELECT STATEMENT   MODE: ALL_ROWS
        325   TABLE ACCESS   MODE: ANALYZED (BY INDEX ROWID) OF
                  'STTM_CUST_ACCOUNT' (TABLE)
    10064925    INDEX   MODE: ANALYZED (RANGE SCAN) OF 'IND_DORMANCY' (INDEX)
    ********************************************************************************This is what I can do. I apologize if it still does not come out in proper format. This is the first time I am trying it. :)
    Cheers.......PCZ

  • Problem of blak padding while comparison on nchar column types

    hi
    i have database oracle 9i with fields of type nchar in tables. in where clause i need to use rtrim(column) = value.
    if there are spaces they are not trimmed.
    i am using generic_baseletter and ansi for case insensitive search.
    see below
    SELECT * FROM V$VERSION;
    BANNER
    Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
    PL/SQL Release 9.2.0.1.0 - Production
    CORE 9.2.0.1.0 Production
    TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
    NLSRTL Version 9.2.0.1.0 - Production
    SQL> SHOW PARAMETER NLS_COMP
    nls_comp string ANSI
    SQL> SHOW PARAMETER NLS_SORT
    nls_sort string GENERIC_BASELETTER
    SQL> SELECT * FROM AREA WHERE CODE = 'bom';
    no rows selected.
    SQL> SELECT * FROM AREA WHERE rtrim(CODE) = 'bom';
    ID CODE DESCRIPTION
    CREATED_BY
    CREATED_DT
    MODIFIED_BY
    MODIFIED_DT BATCH_ID
    15 bom bom
    onkars
    26-APR-10 11.59.51.633000 AM
    20-APR-10 12.05.43.155000 PM
    1 row selected.

    i have database oracle 9i with fields of type nchar in tablesthen you should use the N'text' notation (for national character literals):
    SQL> SELECT * FROM AREA WHERE rtrim(CODE) = N'bom';

  • Problem in where clause in Union

    Hi,
    This is my query
    select activity_source,
    cust_acct_no,
    trx_no,
    order_no,
    dollar_amount,
    deduction_number,
    dispute_status,
    dispute_dt,
    case when count(*) over (partition by cust_acct_no,trx_no order by cust_acct_no,trx_no)=1 then activity_source else trx_no end as order2,
    case when count(*) over (partition by cust_acct_no,trx_no,order_no order by cust_acct_no,trx_no,order_no)=1 then activity_source else order_no end as order3
    From
    (select
    'QFAL' activity_source
    , ded.customer_account cust_acct_no
    , ded.invoice_nbr trx_no
    , ded.sales_order_prime order_no
    , ded.deduction_amount dollar_amount
    , ded.deduction_nbr deduction_number
    , NULL dispute_status
    , NULL dispute_dt
    from
    DW_AP_FAL_DEDUCTION ded
    Where/*_*/
    ded.follow_date = '9-SEP-9999'
    UNION
    select
    'PS' activity_source
    , item.CUST_ID cust_acct_no
    , item.ITEM trx_no
    , item.ORDER_NO order_no
    , item.BAL_AMT dollar_amount
    , NULL deduction_number
    , item.DISPUTE_STATUS dispute_status
    , item.DISPUTE_DT dispute_date
    from
    otr_item_ps item
    Where/*_*/
    item.DISPUTE_STATUS IN ('MUL','RDC','PA','CCR')
    and item.BUSINESS_UNIT IN ('ARNAM','ARCAN','ARUSC')
    and item.ITEM_STATUS = 'O')
    order by
    order2 desc,
    order3 desc,
    cust_acct_no
    I wanted to implement a criteria where ded.deduction_amount dollar_amount in the first part of the query should not be equal to item.BAL_AMT
    i.e; ded.deduction_amount<>item.BAL_AMT
    how do i do this in the query?

    Select name, lodging, age
    From longtime
    Union
    Select name address, 0 -- when you do not have the same column in the table.
    From prospect
    /* Order by age; -- you cannot use column name in the order by clause. */
    order by 3 ; you should use the column number instead.

  • Expert mode query in View objects and appended where clause

    My company is Oracle Member Partner and we are developing enterprise web applications using Oracle database and BC4J.
    I have the following problem...
    When I enable EXPERT MODE option in View Object I have trouble appending to query statement in my client code.
    I need expert mode because I must use "SELECT DISTINCT" insted of "SELECT" in my query.
    It looks something like this:
    viewObject.setWhereClause("CLA_ID = " + claId);
    viewObject.executeQuery();
    SQL query from View Object becomes sub-query and fails to execute:
    select * from (original view object query) where (... appended where clause)
    Order by part of the query causes sql errors because original query is now sub-query.
    Is there any way around this?

    I tried creating an expert mode SQL query:
    SELECT DISTINCT EMPNO, ENAME FROM EMP.
    Then at runtime I do:
    vo.setWhereClause("ENAME LIKE '%'||?||'%');
    vo.setWhereClauseParam(0,'A');.
    and this works fine. The trick is that since expert-mode view objects get wrapped as inline views (to allow runtime appending of WHERE clause, actually), you need to select any column in the select statement to which you want to later refer in a dynamically-appended where clause.
    If you want to prevent the inline-view wrapping, you can write the following code in your view object's ViewObjectImpl subclass to force the VO to NOT be treated as an expert-mode SQL VO.
      // Goes in your view object impl subclass
      public void create() {
         // Force this VO to NOT be treated as an expert-mode SQL, so that
         // its query does not get wrapped as an inline view.
         getViewDef().setFullSql(false);
      }I used this trick above to create an expert mode query like:
    SELECT DISTINCT deptno FROM empand then at runtime I add a dynamic where clause that refers to a column
    in EMP that is not in the select list like this:
        ViewObject vo = am.findViewObject("View1");
        vo.setWhereClause("ename like '%A%'");
        vo.executeQuery();
        System.out.println(vo.first().getAttribute(0));and this causes the query to come out as:
    SELECT DISTINCT deptno FROM emp WHERE ename like '%A%'.
    instead of:
    SELECT * FROM (SELECT DISTINCT deptno FROM emp) QRSLT WHERE ename like '%A%'which would cause an error due to the fact that ename is not in the select list of the original (wrapped, inline) query.

  • Slow split table export (R3load and WHERE clause)

    For our split table exports, we used custom coded WHERE clauses. (Basically adding additional columns to the R3ta default column to take advantage of existing indexes).
    The results have been good so far. Full tablescans have been eliminated and export times have gone down, in some cases, tables export times have improved by 50%.
    However, our biggest table, CE1OC01 (120 GB), continues to be a bottleneck. Initially, after using the new WHERE clause, it looked like performance gains were dramatic, with export times for the first 5 packages dropping from 25-30 hours down to 1 1/2 hours.
    However, after 2 hours, the remaining CE1OC01 split packages have shown no improvement. This is very odd because we are trying to determine why part of the table exports very fast, but other parts are running very slow.
    Before the custom WHERE clauses, the export server had run into issues with SORTHEAP being exhausted, so we thought that might be the culprit. But that does not seem to be an issue now, since the improved WHERE clauses have reduced or eliminated excessive sorting.
    I checked the access path of all the CE1OC01 packages, through EXPLAIN, and they all access the same index to return results. The execution time in EXPLAIN returns similar times for each of the packages:
    CE1OC01-11: select * from CE1OC01  WHERE MANDT='212'
    AND ("BELNR" > '0124727994') AND ("BELNR" <= '0131810250')
    CE1OC01-19: select * from CE1OC01 WHERE MANDT='212'
    AND ("BELNR" > '0181387534') AND ("BELNR" <= '0188469413')
          0 SELECT STATEMENT ( Estimated Costs =  8.448E+06 [timerons] )
      |
      ---      1 RETURN
          |
          ---      2 FETCH CE1OC01
              |
              ------   3 IXSCAN CE1OC01~4 #key columns:  2
    query execution time [millisec]            |       333
    uow elapsed time [microsec]                |   429,907
    total user CPU time [microsec]             |         0
    total system cpu time [microsec]           |         0
    Both queries utilize an index that has fields MANDT and BELNR. However, during R3load, CE1OC01-19 finishes in an hour and a half, whereas CE1OC01-11 can take 25-30 hours.
    I am wondering if there is anything else to check on the DB2 access path side of things or if I need to start digging deeper into other aggregate load/infrastructure issues. Other tables don't seem to exhibit this behavior. There is some discrepancy between other tables' run times (for example, 2-4 hours), but those are not as dramatic as this particular table.
    Another idea to test is to try and export only 5 parts of the table at a time, perhaps there is a throughput or logical limitation when all 20 of the exports are running at the same time. Or create a single column index on BELNR (default R3ta column) and see if that shows any improvement.
    Anyone have any ideas on why some of the table moves fast but the rest of it moves slow?
    We also notice that the "fast" parts of the table are at the very end of the table. We are wondering if perhaps the index is less fragmented in that range, a REORG or recreation of the index may do this table some good. We were hoping to squeeze as many improvements out of our export process as possible before running a full REORG on the database. This particular index (there are 5 indexes on this table) has a Cluster Ratio of 54%, so, perhaps for purposes of the export, it may make sense to REORG the table and cluster it around this particular index. By contrast, the primary key index has a Cluster Ratio of 86%.
    Here is the output from our current run. The "slow" parts of the table have not completed, but they average a throughput of 0.18 MB/min, versus the "fast" parts, which average 5 MB/min, a pretty dramatic difference.
    package     time      start date        end date          size MB  MB/min
    CE1OC01-16  10:20:37  2008-11-25 20:47  2008-11-26 07:08   417.62    0.67
    CE1OC01-18   1:26:58  2008-11-25 20:47  2008-11-25 22:14   429.41    4.94
    CE1OC01-17   1:26:04  2008-11-25 20:47  2008-11-25 22:13   416.38    4.84
    CE1OC01-19   1:24:46  2008-11-25 20:47  2008-11-25 22:12   437.98    5.17
    CE1OC01-20   1:20:51  2008-11-25 20:48  2008-11-25 22:09   435.87    5.39
    CE1OC01-1    0:00:00  2008-11-25 20:48                       0.00
    CE1OC01-10   0:00:00  2008-11-25 20:48                     152.25
    CE1OC01-11   0:00:00  2008-11-25 20:48                     143.55
    CE1OC01-12   0:00:00  2008-11-25 20:48                     145.11
    CE1OC01-13   0:00:00  2008-11-25 20:48                     146.92
    CE1OC01-14   0:00:00  2008-11-25 20:48                     140.00
    CE1OC01-15   0:00:00  2008-11-25 20:48                     145.52
    CE1OC01-2    0:00:00  2008-11-25 20:48                     184.33
    CE1OC01-3    0:00:00  2008-11-25 20:48                     183.34
    CE1OC01-4    0:00:00  2008-11-25 20:48                     158.62
    CE1OC01-5    0:00:00  2008-11-25 20:48                     157.09
    CE1OC01-6    0:00:00  2008-11-25 20:48                     150.41
    CE1OC01-7    0:00:00  2008-11-25 20:48                     175.29
    CE1OC01-8    0:00:00  2008-11-25 20:48                     150.55
    CE1OC01-9    0:00:00  2008-11-25 20:48                     154.84

    Hi all, thanks for the quick and extremely helpful answers.
    Beck,
    Thanks for the health check. We are exporting the entire table in parallel, so all the exports begin at the same time. Regarding the SORTHEAP, we initially thought that might be our problem, because we were running out of SORTHEAP on the source database server. Looks like for this run, and the previous run, SORTHEAP has remained available and has not overrun. That's what was so confusing, because this looked like a buffer overrun.
    Ralph,
    The WHERE technique you provided worked perfectly. Our export times have improved dramatically by switching to the forced full tablescan. Being always trained to eliminate full tablescans, it seems counterintuitive at first, but, given the nature of the export query, combined with the unsorted export, it now makes total sense why the tablescan works so much better.
    Looks like you were right, in this case, the index adds too much additional overhead, and especially since our Cluster Ratio was terrible (in the 50% range), so the index was definitely working against us, by bouncing all over the place to pull the data out.
    We're going to look at some of our other long running tables and see if this technique improves runtimes on them as well.
    Thanks so much, that helped us out tremendously. We will verify the data from source to target matches up 1 for 1 by running a consistency check.
    Look at the throughput difference between the previous run and the current run:
    package     time       start date        end date          size MB  MB/min
    CE1OC01-11   40:14:47  2008-11-20 19:43  2008-11-22 11:58   437.27    0.18
    CE1OC01-14   39:59:51  2008-11-20 19:43  2008-11-22 11:43   427.60    0.18
    CE1OC01-12   39:58:37  2008-11-20 19:43  2008-11-22 11:42   430.66    0.18
    CE1OC01-13   39:51:27  2008-11-20 19:43  2008-11-22 11:35   421.09    0.18
    CE1OC01-15   39:49:50  2008-11-20 19:43  2008-11-22 11:33   426.54    0.18
    CE1OC01-10   39:33:57  2008-11-20 19:43  2008-11-22 11:17   429.44    0.18
    CE1OC01-8    39:27:58  2008-11-20 19:43  2008-11-22 11:11   417.62    0.18
    CE1OC01-6    39:02:18  2008-11-20 19:43  2008-11-22 10:45   416.35    0.18
    CE1OC01-5    38:53:09  2008-11-20 19:43  2008-11-22 10:36   413.29    0.18
    CE1OC01-4    38:52:34  2008-11-20 19:43  2008-11-22 10:36   424.06    0.18
    CE1OC01-9    38:48:09  2008-11-20 19:43  2008-11-22 10:31   416.89    0.18
    CE1OC01-3    38:21:51  2008-11-20 19:43  2008-11-22 10:05   428.16    0.19
    CE1OC01-2    36:02:27  2008-11-20 19:43  2008-11-22 07:46   409.05    0.19
    CE1OC01-7    33:35:42  2008-11-20 19:43  2008-11-22 05:19   414.24    0.21
    CE1OC01-16    9:33:14  2008-11-20 19:43  2008-11-21 05:16   417.62    0.73
    CE1OC01-17    1:20:01  2008-11-20 19:43  2008-11-20 21:03   416.38    5.20
    CE1OC01-18    1:19:29  2008-11-20 19:43  2008-11-20 21:03   429.41    5.40
    CE1OC01-19    1:16:13  2008-11-20 19:44  2008-11-20 21:00   437.98    5.75
    CE1OC01-20    1:14:06  2008-11-20 19:49  2008-11-20 21:03   435.87    5.88
    PLPO          0:52:14  2008-11-20 19:43  2008-11-20 20:35    92.70    1.77
    BCST_SR       0:05:12  2008-11-20 19:43  2008-11-20 19:48    29.39    5.65
    CE1OC01-1     0:00:00  2008-11-20 19:43                       0.00
                558:13:06  2008-11-20 19:43  2008-11-22 11:58  8171.62
    package     time      start date        end date          size MB   MB/min
    CE1OC01-9    9:11:58  2008-12-01 20:14  2008-12-02 05:26   1172.12    2.12
    CE1OC01-5    9:11:48  2008-12-01 20:14  2008-12-02 05:25   1174.64    2.13
    CE1OC01-4    9:11:32  2008-12-01 20:14  2008-12-02 05:25   1174.51    2.13
    CE1OC01-8    9:09:24  2008-12-01 20:14  2008-12-02 05:23   1172.49    2.13
    CE1OC01-1    9:05:55  2008-12-01 20:14  2008-12-02 05:20   1188.43    2.18
    CE1OC01-2    9:00:47  2008-12-01 20:14  2008-12-02 05:14   1184.52    2.19
    CE1OC01-7    8:54:06  2008-12-01 20:14  2008-12-02 05:08   1173.23    2.20
    CE1OC01-3    8:52:22  2008-12-01 20:14  2008-12-02 05:06   1179.91    2.22
    CE1OC01-10   8:45:09  2008-12-01 20:14  2008-12-02 04:59   1171.90    2.23
    CE1OC01-6    8:28:10  2008-12-01 20:14  2008-12-02 04:42   1172.46    2.31
    PLPO         0:25:16  2008-12-01 20:14  2008-12-01 20:39     92.70    3.67
                90:16:27  2008-12-01 20:14  2008-12-02 05:26  11856.91

  • Case statement in where clause ??

    Hello gurus,
    Can we use case statements in where clause ?? Any example will be great!
    And also i would like to know, besides CASE and DECODE statements, Is there any way we can use IF ELSE statements in SELECT clause or in WHERE clause ?
    Thank you!!

    Hi,
    user642297 wrote:
    Hoek,
    Thanks for the reply
    Whatever you return from 'then' should match your criteria.I didnt get this part...can you elaborate this part ?? Thank you!!Remember what a CASE expression does: it returns a single value in one of the SQL data types (or NULL).
    You're probably familiar with conditions such as
    WHERE   col = 1Inthe example above, col could be replaced by any kind of expression: a function call, and operation (such as "d * 24") or a CASE expression, which is exactly what Hoek posted:
    where  case
             when col = 6 then 1
             when col = 9 then 1
           end = 1;I think what Hoek meant about mnatching was this: since the CASE expression is being compared to a NUMBER, then every THEN clause (as well as the ELSE, if there is one) should return the same data type. You can't have one THEN clause return a NUMBER, and another one in the same CASE expression return a DATE, like this:
    where  case
             when col = 6 then 1
             when col = 9 then SYSDATE     -- WRONG! Raises ORA-00932: inconsistent datatypes
           end = 1; 
    By the way, it's rare when a CASE expression really helps in a WHERE clause. CASE is great for doing conitional stuff in places where you otherwise can't (in the ORDER BY clause, for example), but the WHERE clause was designed for conditions.
    Hoek was just trying to give a simple example. If you really wanted those results, it would be simpler to say:
    where  col = 6
    or     col = 9and simpler still to say
    where  col  IN (6, 9)

  • Select sdo_nn with where-clause on large table

    Hi spatial-experts,
    I've following problem. I use a table with more than 2.500.000 dataset. Every dataset represents one point (SDO_GEOMETRY, SDO_POINT_TYPE) and have further (text) information. (PI (point of interest) table from TeleAtlas mn_pi)
    Following Select works fine:
    SELECT /*+ ORDERED NO_INDEX(pi IX_PI_FEATTYP) */
    sdo_nn_distance(1) distance,
    id, feattyp, arnamelc, name, stname, stnamelc, hsnum, postcode
    FROM multinet.mn_pi pi
    WHERE
    pi.feattyp IN ( 9373,9374)
    AND
    SDO_NN(
    pi.geom,
    SDO_GEOMETRY( 2001, 8307, SDO_POINT_TYPE(613.86865234375/60, 3002.94677734375/60, NULL), NULL, NULL),
    'sdo_batch_size=0', 1) = 'TRUE'
    AND rownum = 1
    ORDER BY distance
    (P.S. IX_PI_FEATTYP is an index on column feattyp, here not used. When I'm using it the select do not work (it last very long...))
    When I now modify the where clause to an pi which feat type that does not exists (no entry in table) the select lasts very long (I canceled the select after 5 minutes).
    for example: pi.feattyp = 9756
    Otherwise I add a further where clause like
    AND arnamelc = 'ITA'
    the select also works very long. The point are now in italy. refrence point is in germany and is more than 500km away.
    Are there some solutions to solve this problems
    (should I use for every feat type a own table)?
    Why is the select so slow?
    Thanks for all helpfully answers,
    Matthias

    Hi Matthias,
    When you use nearest neighbor, Oracle will use the spatial index to find the nearest neighbor that meets the query criteria. It probes into the index, calculates distances, and returns data in distance order.
    Using SDO_BATCH_SIZE, it keeps going back to the database, returning more and more records in distance order until the other predicates are satisfied (in your case, pi.feattyp IN ( 9373,9374).
    When you specified pi.feattyp = 9756 (which doesn't exist), you told Oracle to keep going and calculating distances for each of the more than 2.500.000 records in the the data set (you killed it after 5 minutes).
    I don't know why adding: AND arnamelc = 'ITA' caused Oracle to take extra time. Sometimes I will do a: set autotrace trace exp
    then compare plans for something that runs quickly vs. something that runs slowly. If you want to post the plans for the fast and slow versions it might be interesting to look at.
    My guess is you may want to look at a solution that incorporates various possibilities. For instance, if there are only a few of some feattyp values, you may want to select those using the non-spatial index then use sdo_geom.sdo_distance to find the closest point rather than risk having to look through a few million values for a match.
    I'm sure other people have thoughts as well...
    Kind regards,
    Dan

Maybe you are looking for