Clob in where clause

Hi
I'm trying to query simple select where in clause is Clob but it's not working.
set serveroutput on
declare
l_clob clob := '''SYS''';
l_clob2 clob :=null;
vzm varchar2(15);
begin
dbms_output.put_line( to_char(l_clob) );
select username into l_clob2 from dba_users where username = to_char(l_clob);
dbms_output.put_line( to_char(l_clob2) );
end;
so l_clob is returned as string 'SYS'
but l_clob2 show errors :
ORA-01403: no data found
ORA-06512: at line 9
01403. 00000 - "no data found"
#which is not right because there is user SYS in dba_users.
so my question is how to use clob in where clause to query some table? this is just a easiest example ;

ok thanks in one value it's working but how with this example
when I have a list of values to IN() clause so clob like 'SYS','SYSTEM'.etc
set serveroutput on
declare
l_clob clob := '''SYS'',';
l_clob2 clob :=null;
vzm varchar2(15);
begin
vzm:='''SYSTEM''';
dbms_lob.writeappend( l_clob, length(vzm),vzm );
dbms_output.put_line( to_char(l_clob) );
select username into l_clob2 from dba_users where username IN(to_char(l_clob));
dbms_output.put_line( to_char(l_clob2) );
end;
l_clob is 'SYS','SYSTEM' so it should be fit to IN('SYS','SYSTEM') but it not:
l_clob2 ORA-01403: no data found
ORA-06512: at line 9
01403. 00000 - "no data found"
*Cause:   
how to do it when the list of user is really long more then 600 and i have to use IN clause with ' ,' in it?

Similar Messages

  • Using CLOB datatypes in WHERE clause

    Hi All,
    I have a table with two columns as CLOB datatype. I'm using Oracle 8i Enterprise Edition. I can do a query, insert, update and even delete the data in the CLOB field using Oracle's SQL Plus.
    What I want is to do a search on those fields.. that is include that field in a WHERE clause. I'm using this datatype to store large number of data.
    I'd like to see this query working...
    SELECT * FROM MyTable WHERE CLOBFLD LIKE 'Something...';
    Now this query doesn't work. It returns: 'Inconsistent datatype' near the word CLOBFLD.
    Please Help me out.
    Regards,
    Gopi
    null

    I presume you want to query based on the contents of the CLOB, right ? If that is true, then you have to create a text index, using Oracle Context and then use "Contains" in the where clause to query. Hope this helps.

  • Is it possible to use LONG columns in WHERE clause or ORDER BY?

    Is it possible to use LONG columns in WHERE clause or ORDER BY?

    Hi,
    LONG data type is deprecated, maybe could you change your column type to LOB ?
    Nonetheless below is a workaround which may fit your needs if forced to use LONG.
    It uses a function which returns you a CLOB. It allows you to use the converted "LONG" column in a WHERE clause.
    Then if you want to order by you have to convert the CLOB to a VARCHAR using DBMS_LOB.SUBSTR.
    SQL> CREATE TABLE my_table (id NUMBER, description LONG);
    Table created.
    SQL> INSERT INTO my_table VALUES (1, 'FIRST LONG');
    1 row created.
    SQL> INSERT INTO my_table VALUES (2, 'ANOTHER LONG');
    1 row created.
    SQL> COMMIT;
    Commit complete.
    SQL> CREATE TYPE my_type_row AS OBJECT (id INTEGER, description CLOB);
      2  /
    Type created.
    SQL> CREATE TYPE my_type_table AS TABLE OF my_type_row;
      2  /
    Type created.
    SQL> CREATE OR REPLACE FUNCTION get_my_long
      2     RETURN my_type_table
      3     PIPELINED
      4  AS
      5     v_tab   my_type_table := my_type_table ();
      6  BEGIN
      7    FOR cur IN (SELECT id, description FROM my_table)
      8  LOOP
      9        PIPE ROW (my_type_row (cur.id, cur.description));
    10  END LOOP;
    11  RETURN;
    12  END;
    13  /
    Function created.
    SQL> SELECT
      2     id,
      3     description
      4  FROM
      5     TABLE (get_my_long ())
      6  WHERE
      7     description LIKE '%LONG'
      8  ORDER BY
      9     DBMS_LOB.SUBSTR(description);
      ID DESCRIPTION
       2 ANOTHER LONG
       1 FIRST LONG
    SQL> SELECT
      2     id,
      3     description
      4  FROM
      5     TABLE (get_my_long ())
      6  WHERE
      7     description LIKE 'FI%';
      ID DESCRIPTION
       1 FIRST LONG
    SQL>Kind regards,
    Ludovic

  • Dynamic where clause change

    Hi,
    I have code as below
    Scenario1
    FOR i in (Select .................... from table1 Where id in(select id from Sample_table where status='Submit'))
    Loop
    End loop;
    Scenario2
    FOR i in (Select .................... from table1 Where id in(select id from Sample_table where status='Saved'))
    Loop
    End loop;
    Scenario3
    FOR i in (Select .................... from table1 Where id in(select id from Sample_table where status='Inprogress'))
    Loop
    End loop;Query is same here but only chage is where clause
    Total length of this query is exceeding varchar2 length. so i cant use variable to hold this query and append where clause dynamically.
    Do we have any other method to change where clause dynamically?

    >
    We have around 200 columns to select from multiple tables...Here I gave sample code...
    so its exceeding length
    >
    So 200 columns at 30 bytes per column name is only 6000 bytes. That means the rest of the query is using over 26000 bytes: 260 lines of query if each line was 100 bytes long.
    You need to rethink what you are doing. So far your queries are too big, your row-by-row processing is a terrible way to process data and repeating that process multiple times just aggravates the performance even more.
    I can't imagine there is ANY justification for doing things that way.
    Even if you HAD to do things that way you couldn't exceed the CLOB length so why aren't you using a CLOB variable?
    http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/openfor_statement.htm
    >
    OPEN-FOR StatementThe OPEN-FOR statement executes the SELECT statement associated with a cursor variable. It allocates database resources to process the statement, identifies the result set (the rows that meet the conditions), and positions the cursor variable before the first row in the result set.
    With the optional USING clause, the OPEN-FOR statement processes a dynamic SELECT statement that returns multiple rows: it associates a cursor variable with the SELECT statement, executes the statement, identifies the result set, positions the cursor before the first row in the result set, and zeroes the rows-processed count kept by %ROWCOUNT.
    dynamic_string
    A string literal, string variable, or string expression that represents any SQL statement. It must be of type CHAR, VARCHAR2, or CLOB.

  • Derive found flag in SQL with where clause using TABLE(CAST function

    Dear All,
    Stored procedure listEmployees
    ==========================
    CREATE OR REPLACE TYPE STRING_ARRAY AS VARRAY(8000) OF VARCHAR2(15);
    empIdList STRING_ARRAY
    countriesList STRING_ARRAY
    SELECT EMP_ID, EMP_COUNTRY, EMP_NAME, FOUND_FLAG_
    FROM EMPLOYEE WHERE
    EMP_ID IN
    (SELECT * FROM TABLE(CAST(empIdList AS STRING_ARRAY))
    AND EMP_COUNTRY IN
    (SELECT * FROM TABLE(CAST(countriesList AS STRING_ARRAY))
    =================
    I have a stored procedure which lists the employees using above simple query.
    Here I am using table CAST function to find the list of employees in one go
    instead of looping through each and every employee
    Everything fine until requirements forced me to get the FOUND_FLAG as well.
    Now I wanted derive the FOUND_FLAG by using rownum, rowid, decode functions
    but I was not successful
    Can you please suggest if there is any intelligent way to say weather the
    row is found for given parameters in the where clause?
    If not I may have to loop through each set of empIdList, countriesList
    and find the values individually just to set a flag. In this approach I can’t use
    the TABLE CAST function which is efficient I suppose.
    Note that query STRING_ARRAY is an VARRAY. It is very big in size and this procedure
    suppose to handle large sets of data.
    Thanks In advance
    Regards
    Charan
    Edited by: kmcharan on 03-Dec-2009 09:55
    Edited by: kmcharan on 03-Dec-2009 09:55

    If your query returns results, you have found them... so your "FOUND" flag might be a constant,...

  • Index usage in depending on where clause changes.

    Hello Friends,
    I need your help for one issue.
    I have one query , which is using two table Say T1 and T2, where C1 is common column using which both are joined.
    C1 is primary key in T1, but no index available in T2 for C1. T1C2 is the column which we want to select.
    (Note that Either of table can be a Master table)
    Now see the query:
    Select T1C2
    From T1, T2
    where T2.C1 = T1.C1
    Here where clause may have other conditions and From clause may have others tables as per requirements.
    I want to know that, if, I change the query like following to let my query use the available index of T1.C1.
    Select T1C2
    from T1, T2
    where T1.C1 = T2.C1
    Then, Will the query use the available index of T1. and Will i get better performance. Even a little improvement in performance may help me a lot as this kind of query is being used within a where loop (so it is going to be executed multiple times).
    Please advise on this..
    Regards,
    Dipali..

    Hi,
    18:43:17 rel15_real_p>create table t1(c1 number primary key, c2 number);
    Table created.
    18:43:26 rel15_real_p>create table t2(c1 number, c2 number);
    18:45:08 rel15_real_p>
    18:45:09 rel15_real_p>begin
    18:45:09   2  for i in 1..100
    18:45:09   3  loop
    18:45:09   4        insert into t1(c1,c2) values (i,i+100);
    18:45:09   5  end loop;
    18:45:09   6  commit;
    18:45:09   7  end;
    18:45:09   8  /
    PL/SQL procedure successfully completed.
    18:45:09 rel15_real_p>
    18:45:09 rel15_real_p>
    18:45:09 rel15_real_p>begin
    18:45:09   2  for i in 1..100
    18:45:09   3  loop
    18:45:09   4        insert into t2(c1,c2) values (i,i+200);
    18:45:09   5  end loop;
    18:45:09   6  commit;
    18:45:09   7  end;
    18:45:09   8  /
    18:45:23 rel15_real_p>select count(*) from t1;
      COUNT(*)
           100
    18:45:30 rel15_real_p>select count(*) from t2;
      COUNT(*)
           100
    18:45:49 rel15_real_p>select index_name,index_type from user_indexes where table
    _name='T1';
    INDEX_NAME                     INDEX_TYPE
    SYS_C0013059                   NORMAL
    18:48:21 rel15_real_p>set autotrace on
    18:52:25 rel15_real_p>Select T1.C2
    18:52:29   2  From T1, T2
    18:52:29   3  where T2.C1 = T1.C1
    18:52:29   4  /
            C2
           101
           102
           103
           104
           105
            C2
           200
    100 rows selected.
    Execution Plan
       0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=100 Bytes=
              900)
       1    0   HASH JOIN (Cost=7 Card=100 Bytes=3900)
       2    1     TABLE ACCESS (FULL) OF 'T1' (TABLE) (Cost=3 Card=100 By
              es=2600)
       3    1     TABLE ACCESS (FULL) OF 'T2' (TABLE) (Cost=3 Card=100 By
              es=1300)
    Statistics
              0  recursive calls
              0  db block gets
             21  consistent gets
              0  physical reads
              0  redo size
           1393  bytes sent via SQL*Net to client
            562  bytes received via SQL*Net from client
              8  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
            100  rows processed
    18:52:31 rel15_real_p>analyze table t1 compute statistics;
    Table analyzed.
    18:55:35 rel15_real_p>analyze table t2 compute statistics;
    18:55:38 rel15_real_p>set autotrace on
    18:55:42 rel15_real_p>Select T1.C2
    18:55:43   2  From T1, T2
    18:55:45   3  where T2.C1 = T1.C1
    18:55:46   4  /
            C2
           101
           102
           103
           104
           105
            C2
           200
    100 rows selected.
    Execution Plan
       0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=100 Bytes=7
              00)
       1    0   MERGE JOIN (Cost=6 Card=100 Bytes=700)
       2    1     TABLE ACCESS (BY INDEX ROWID) OF 'T1' (TABLE) (Cost=2 Ca
              rd=100 Bytes=500)
       3    2       INDEX (FULL SCAN) OF 'SYS_C0013059' (INDEX (UNIQUE)) (
              Cost=1 Card=100)
       4    1     SORT (JOIN) (Cost=4 Card=100 Bytes=200)
       5    4       TABLE ACCESS (FULL) OF 'T2' (TABLE) (Cost=3 Card=100 B
              ytes=200)
    Statistics
              1  recursive calls
              0  db block gets
             23  consistent gets
              0  physical reads
              0  redo size
           1393  bytes sent via SQL*Net to client
            562  bytes received via SQL*Net from client
              8  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
            100  rows processed
    18:56:56 rel15_real_p>Select T1.C2
    18:56:56   2  From T1, T2
    18:56:56   3  where T1.C1 = T2.C1
    18:56:58   4  /
            C2
           101
           102
           103
           104
           105
            C2
           200
    100 rows selected.
    Execution Plan
       0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=100 Bytes=7
              00)
       1    0   MERGE JOIN (Cost=6 Card=100 Bytes=700)
       2    1     TABLE ACCESS (BY INDEX ROWID) OF 'T1' (TABLE) (Cost=2 Ca
              rd=100 Bytes=500)
       3    2       INDEX (FULL SCAN) OF 'SYS_C0013059' (INDEX (UNIQUE)) (
              Cost=1 Card=100)
       4    1     SORT (JOIN) (Cost=4 Card=100 Bytes=200)
       5    4       TABLE ACCESS (FULL) OF 'T2' (TABLE) (Cost=3 Card=100 B
              ytes=200)
    Statistics
              1  recursive calls
              0  db block gets
             23  consistent gets
              0  physical reads
              0  redo size
           1393  bytes sent via SQL*Net to client
            562  bytes received via SQL*Net from client
              8  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
            100  rows processed- Pavan Kumar N

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

  • Cardinality estimator 2014 is off with OR in where clause

    Here is my test setup on SQL Server 2014.
    -- Create big table
    CREATE TABLE [dbo].[Store](
    Id int IDENTITY(1,1) NOT NULL,
    City int NOT NULL,
    Size int NOT NULL,
    Name varchar(max) NULL,
    CONSTRAINT [PK_Store] PRIMARY KEY CLUSTERED ([Id] ASC)
    GO
    CREATE NONCLUSTERED INDEX [IX_Store] ON [dbo].[Store] (City ASC, Size ASC)
    GO
    -- Fill with 100k rows
    INSERT Store
    SELECT i % 101, i % 11, 'Store ' + CAST(i AS VARCHAR)
    FROM
    (SELECT TOP 100000 ROW_NUMBER() OVER (ORDER BY s1.[object_id]) AS i
    FROM sys.all_objects s1, sys.all_objects s2) numbers
    GO
    -- Create small table
    CREATE TABLE #StoreRequest (City int NOT NULL, Size int NOT NULL)
    GO
    INSERT #StoreRequest values (55, 1)
    INSERT #StoreRequest values (66, 2)
    Now I execute the following query (I force the index to show statistics estimates)
    SELECT s.City
    FROM #StoreRequest AS r
    INNER JOIN Store AS s WITH(INDEX(IX_Store), FORCESEEK)
    ON s.City = r.City AND s.Size = r.Size
    WHERE s.Size <> 1 OR r.City <> 55
    Here are the estimates that I get (I'm not allowed to upload pictures):
    Index Seek IX_Store
    Actual Number of Rows: 90
    Estimated Number of Rows: 50000
    Fixing WHERE clause to use one table not two makes the estimate perfect:
    SELECT s.City
    FROM #StoreRequest AS r
    INNER JOIN Store AS s WITH(INDEX(IX_Store), FORCESEEK)
    ON s.City = r.City AND s.Size = r.Size
    WHERE s.Size <> 1 OR s.City <> 55
    Index Seek IX_Store
    Actual Number of Rows: 90
    Estimated Number of Rows: 89.74
    Switching to 2012 compatibility mode gives estimate of 1 in both cases:
    Index Seek IX_Store
    Actual Number of Rows: 90
    Estimated Number of Rows: 1
    Could anyone explain the first result? I'm a bit worried about it. The fix in this case is trivial, but this problem gave us quite some headache in more complex real life queries with multiple joins.
    Thank you!

    But not full statistics on a field basis, just sometimes some default stats like total row count that some plans will build.  Even your StoreRequest table only has one two-field index that will have a full histogram.
    But I've seen SQL Server make massively bad plans on two-field indexes.
    I've seen SQL Server go wrong one-column indexes, so that is not a very relevant point.
    Temp tables or not, the estimate here is clearly incorrect. SQL Server knows the density of Size and City. It knows the cardinality of the temp table. The density information gives how many rows the the join will produce. The WHERE clause will then remove
    a certain number of rows. With no statistics for the temp table, it does not now how many, but it will apply some standard guess.
    50000 is a completely bogus number, because the join cannot produce that many rows, and SQL Server is able to compute the join with out the WHERE clause decently. (Well, it estimates 90, when the number is 180.) No, this is obviously a case of the cardinality
    estimator giving up completely.
    It is worth noting that both these WHERE clauses gives reasonable estimates:
     WHERE r.Size <> 11 OR r.City <> 550
     WHERE s.Size <> 11 OR s.City <> 550
    Whereas these two gives the spooky 50000:
     WHERE s.Size <> 11 OR r.City <> 550
     WHERE r.Size <> 11 OR s.City <> 550
    Erland Sommarskog, SQL Server MVP, [email protected]

  • Trouble with OR in where clause

    Hello,
    I'm having trouble with execution speed. The problem seems to be with using OR in my where clause.
    Here's the meat of the function where i_pledge_number is an input parm:
    BEGIN
    SELECT /*+ INDEX (pp) */ SUM(pp.prim_pledge_amount)
    INTO return_amount
    FROM
    primary_pledge pp
    WHERE
    -- Get total if multiple allocations
    pp.prim_pledge_number IN
    (SELECT pc.pledge_number
    FROM pledge_codes pc
    WHERE pc.pledge_code_type = 'M'
    AND pc.pledge_code = 'AC'
    AND lpad(pc.pledge_comment,10,'0') = i_pledge_number)
    -- Get total if single allocation
    OR pp.prim_pledge_number = i_pledge_number;
    RETURN return_amount;
    END;
    If I comment out either half of the OR statement (either the subquery or the pp.prim_pledge_number = i_pledge_number half) the function returns a value in .02 seconds. If I leave the OR in, it takes 2.764 seconds to execute?? Can someone please show me a better way (faster) to do this? I tried using nvl() around the subquery but couldn't get it to compile.
    Thanks

    These things are difficult to diagnose remotely, but here is something you can try....
    SELECT */ SUM(pp.prim_pledge_amount)
    INTO return_amount
    FROM   primary_pledge pp
    WHERE  pp.prim_pledge_number IN (SELECT pc.pledge_number
                                     FROM pledge_codes pc
                                     WHERE pc.pledge_code_type = 'M'
                                     AND pc.pledge_code = 'AC'
                                     AND lpad(pc.pledge_comment,10,'0') = i_pledge_number
    UNION ALL
    SELECT i_pledge_number FROM dual)
       RETURN return_amount;
    END;If that doesn't do anything (and it might well not) there are a large number of different ways we can recast this query. To save us further guessing please give us more details: execution plans, database version number, volumetrics.
    Cheers, APC

  • Function-based index with OR in the wher-clause

    We have some problems with functin-based indexes and
    the or-condition in a where-clause.
    --We use Oracle 8i (8.1.7)
    create table TPERSON(ID number(10),NAME varchar2(20),...);
    create index I_NORMAL_TPERSON_NAME on TPERSON(NAME);
    create index I_FUNCTION_TPERSON_NAME on TPERSON(UPPER(NAME));
    The following two statements run very fast on a large table
    and the execution-plan asure the usage of the indexes
    (-while the session is appropriate configured and the table is analyzed):
    1)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%';
    2)     select count(ID) from TPERSON where NAME like 'Mil%' or (3=5);
    In particular we see that a normal index is used while the where-clause contains
    an OR-CONDITION.
    But if we try the similarly select-statement
    3)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%' or (3=5);
    the CBO will not use the function-index I_FUNCTION_TPERSON_NAME and we have a full table scan in the execution-plan.
    (This behavior we only expect with views but not with indexes.)
    We ask for an advice like a hint, which enable the CBO-usage
    of function-based indexes in connection with OR.
    This problem seems to be artificial because it contains this dummy logic:
         or (3=5).
    This steams from an prepared statement, where this kind of boolean
    flag reduce the amount of different select-statements needed for
    covering the hole business-logic, while using bind-variables for the
    concrete query-parameters.
    A more realistic (still boild down) version of our select-statement is:
    select * FROM TPERSON
    where (upper(NAME) like 'MIL%' or (NAME is null))
    and (upper(FIRSTNAME) like 'MICH% or (FIRSTNAME is null))
    and ...;
    thank you for time..
    email: [email protected]

    In the realistic statement you write :
    select * FROM TPERSON
    where (upper(NAME) like 'MIL%' or (NAME is null))
    and (upper(FIRSTNAME) like 'MICH% or (FIRSTNAME is null))
    and ...;
    as far as i know, NULL values are not indexed, "or (NAME is NULL)" have to generate a full table scan.
    HTH
    We have some problems with functin-based indexes and
    the or-condition in a where-clause.
    --We use Oracle 8i (8.1.7)
    create table TPERSON(ID number(10),NAME varchar2(20),...);
    create index I_NORMAL_TPERSON_NAME on TPERSON(NAME);
    create index I_FUNCTION_TPERSON_NAME on TPERSON(UPPER(NAME));
    The following two statements run very fast on a large table
    and the execution-plan asure the usage of the indexes
    (-while the session is appropriate configured and the table is analyzed):
    1)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%';
    2)     select count(ID) from TPERSON where NAME like 'Mil%' or (3=5);
    In particular we see that a normal index is used while the where-clause contains
    an OR-CONDITION.
    But if we try the similarly select-statement
    3)     select count(ID) FROM TPERSON where upper(NAME) like 'MIL%' or (3=5);
    the CBO will not use the function-index I_FUNCTION_TPERSON_NAME and we have a full table scan in the execution-plan.
    (This behavior we only expect with views but not with indexes.)
    We ask for an advice like a hint, which enable the CBO-usage
    of function-based indexes in connection with OR.
    This problem seems to be artificial because it contains this dummy logic:
         or (3=5).
    This steams from an prepared statement, where this kind of boolean
    flag reduce the amount of different select-statements needed for
    covering the hole business-logic, while using bind-variables for the
    concrete query-parameters.
    A more realistic (still boild down) version of our select-statement is:
    select * FROM TPERSON
    where (upper(NAME) like 'MIL%' or (NAME is null))
    and (upper(FIRSTNAME) like 'MICH% or (FIRSTNAME is null))
    and ...;
    thank you for time..
    email: [email protected]

  • Performance - composite index with 'OR' in 'WHERE' clause

    I have a problem with the performance of the following query:
    select /*+ index_asc(omschact oma_index1) */ knr, projnr, actnr from omschact where ((knr = 100 and actnr > 30) or knr > 100)
    and rownum = 1;
    (rownum used only for test purpose)
    index:
    create index on omschact (knr, projnr);
    Execution plan:
    Id Operation
    0 SELECT STATEMENT
    1 COUNT STOPKEY
    2 TABLE ACCESS BY INDEX ROWID
    3 INDEX FULL SCAN
    If I'm correct, the 'OR' in the 'WHERE' clause is responsible for the INDEX FULL SCAN, what makes the query slow.
    A solution would be then to separate the 'WHERE' clause in 2 separate select's (1 with 'knr = 100 and actnr > 30' and 1 with 'knr > 100' and combine the results with a UNION ALL.
    Since it's necessary to have all rows in ascending order (oma_index1) I still have to use an ORDER BY to make sure the order of the rows is correct. This results again in a (too) low performance.
    Another solution that does the trick is to create an index with the 2 fields (knr, projnr) concatenated and to use the same in the 'WHERE' clause:
    create index oma_index2 on omschact (knr || projnr);
    select /*+ index_asc(omschact oma_index2) */ knr, projnr, actnr from omschact where (knr || projnr) > 10030;
    I just can't believe this work-around is the only solution, so I was hoping that someone here knows of a better way to solve this.

    padders,
    I'll give the real data instead of the example. The index I really use consists of 4 fields. In this table the fields are just numbers, but in other tables I need to use char-fields in indexes, so that's why I concatenate instead of using formula's (allthough I would prefer the latter).
    SQL> desc omschact
    Name Null? Type
    KNR NOT NULL NUMBER(8)
    PROJNR NOT NULL NUMBER(8)
    ACTNR NOT NULL NUMBER(8)
    REGELNR NOT NULL NUMBER(3)
    REGEL CHAR(60)
    first methode:
    SQL> create index oma_key_001(knr,projnr,actnr,regelnr);
    Index created.
    SQL> select /*+ index_asc(omschact oma_key_001) */ * from omschact where
    2 (knr > 100 or
    3 (knr = 100 and projnr > 30) or
    4 (knr = 100 and projnr = 30 and actnr > 100000) or
    5 (knr = 100 and projnr = 30 and actnr = 100000 and regelnr >= 0));
    Execution Plan
    Plan hash value: 1117430516
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 11M| 822M| 192K (1)| 00:38:26 |
    | 1 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 11M| 822M| 192K (1)| 00:38:26 |
    |* 2 | INDEX FULL SCAN | OMA_KEY_001 | 11M| | 34030 (1)| 00:06:49 |
    Predicate Information (identified by operation id):
    2 - filter("KNR">100 OR "KNR"=100 AND "PROJNR">30 OR "KNR"=100 AND "PROJNR"=30
    AND "ACTNR">100000 OR "ACTNR"=100000 AND "KNR"=100 AND "PROJNR"=30 AND
    "REGELNR">=0)
    second method (same index):
    SQL> select * from (
    2 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr > 100
    3 union all
    4 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr = 100 and projnr > 30
    5 union all
    6 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr = 100 and projnr = 30 and actnr > 100000
    7 union all
    8 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr = 100 and projnr = 30 and actnr = 100000 and regelnr > 0)
    9 order by knr, projnr, actnr, regelnr;
    Execution Plan
    Plan hash value: 292918786
    | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 11M| 1203M| | 477K (1)| 01:35:31 |
    | 1 | SORT ORDER BY | | 11M| 1203M| 2745M| 477K (1)| 01:35:31 |
    | 2 | VIEW | | 11M| 1203M| | 192K (1)| 00:38:29 |
    | 3 | UNION-ALL | | | | | | |
    | 4 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 11M| 822M| | 192K (1)| 00:38:26 |
    |* 5 | INDEX RANGE SCAN | OMA_KEY_001 | 11M| | | 33966 (1)| 00:06:48 |
    | 6 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 16705 | 1272K| | 294 (1)| 00:00:04 |
    |* 7 | INDEX RANGE SCAN | OMA_KEY_001 | 16705 | | | 54 (0)| 00:00:01 |
    | 8 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 47 | 3666 | | 4 (0)| 00:00:01 |
    |* 9 | INDEX RANGE SCAN | OMA_KEY_001 | 47 | | | 3 (0)| 00:00:01 |
    | 10 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 1 | 78 | | 4 (0)| 00:00:01 |
    |* 11 | INDEX RANGE SCAN | OMA_KEY_001 | 1 | | | 3 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    5 - access("KNR">100)
    7 - access("KNR"=100 AND "PROJNR">30)
    9 - access("KNR"=100 AND "PROJNR"=30 AND "ACTNR">100000)
    11 - access("KNR"=100 AND "PROJNR"=30 AND "ACTNR"=100000 AND "REGELNR">0)
    third method:
    SQL> create index oma_test(to_char(knr,'00000000')||to_char(projnr,'00000000')||to_char(actnr,'00000000')||to_char(regelnr,'000'));
    Index created.
    SQL> select /*+ index_asc(omschact oma_test) */ * from omschact where
    2 (to_char(knr,'00000000')||to_char(projnr,'00000000')||
    3 to_char(actnr,'00000000')||to_char(regelnr,'000')) >=
    4 (to_char(100,'00000000')||to_char(30,'00000000')||
    5* to_char(100000,'00000000')||to_char(0,'000'))
    Execution Plan
    Plan hash value: 424961364
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 553K| 55M| 1712 (1)| 00:00:21 |
    | 1 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 553K| 55M| 1712 (1)| 00:00:21 |
    |* 2 | INDEX RANGE SCAN | OMA_TEST | 99543 | | 605 (1)| 00:00:08 |
    Predicate Information (identified by operation id):
    2 - access(TO_CHAR("KNR",'00000000')||TO_CHAR("PROJNR",'00000000')||TO_CHAR("
    ACTNR",'00000000')||TO_CHAR("REGELNR",'000')>=TO_CHAR(100,'00000000')||TO_CHAR(3
    0,'00000000')||TO_CHAR(100000,'00000000')||TO_CHAR(0,'000'))

  • Can we use where clause in Update on Merge statement?

    Hi All,
    I tried to execute the following Merge Query:
    When this query is executed without ‘Where clause’ in Update statement its working fine. When executed with ‘Where clause’ it throwing the following error:
    ORA-00905: missing keyword.
    Following is the sample query which I tried to execute:
    MERGE INTO TABLE_NAME
    USING (SELECT COLUMN FORM TABLES)
    ON (CONDITION)
    WHEN MATCHED THEN
    UPDATE SET
         COLUMN UPATES
    WHERE CONDITION -- Can we use where clause here?
    WHEN NOT MATCHED THEN
    INSERT
    INSERT VALUES;
    Can some one help on this?
    Thanks in advance.
    Darius

    Yes:
    SQL> drop table emp1;
    Table dropped.
    SQL> create table emp1 as select * from emp where deptno = 30;
    Table created.
    SQL> update emp1 set sal = sal*2;
    6 rows updated.
    SQL> commit;
    Commit complete.
    SQL> select ename,sal from emp1;
    ENAME             SAL
    ALLEN            3200
    WARD             2500
    MARTIN           2500
    BLAKE            5700
    TURNER           3000
    JAMES            1900
    6 rows selected.
    SQL> MERGE INTO emp1
      2  USING(select * from emp) emp
      3  ON (emp1.empno = emp.empno)
      4  WHEN MATCHED THEN
      5  UPDATE SET sal = emp.sal WHERE ename = 'TURNER'
      6  WHEN NOT MATCHED THEN
      7  INSERT(ename,sal) VALUES(emp.ename,emp.sal);
    9 rows merged.
    SQL> select ename,sal from emp1;
    ENAME             SAL
    ALLEN            3200
    WARD             2500
    MARTIN           2500
    BLAKE            5700
    TURNER 1500
    JAMES            1900
    SMITH             800
    JONES            2975
    CLARK            2450
    SCOTT            3000
    KING             5000
    ENAME             SAL
    ADAMS            1100
    FORD             3000
    MILLER           1300
    14 rows selected.
    SQL> SY.

  • Using if logic in the where clause of a select statement

    I have a select clause. And in the select clause there is a variable all_off_trt that can be 'Y' or 'N'.
    In the where clause I want to make it so that if a form variable is checked and all_off_trt is 'Y' then
    exclude it else if the form variable isn't checked then select it no matter what all_off_trt is.
    Is there any way to include either and if statement or a case statement within the where clause to acheive this? If not is there another way of doing it?
    Basically I am looking for a case statement like this
    case
    when all_off_trt = 'Y' and mail_para.code = 'Y' then false
    else true
    end
    Message was edited by:
    Tugnutt7

    Ok, so that really doesn't solve my problem. I have 3 different fields that I need to do that with. Each combining in a select statement to print an email list, as well as other thing limiting the where clause.
    This is currently what I have, tested and working 100%.
    cursor email_cur is
         select unique p.email,s.all_off_trt,s.all_deceased,s.no_enroll
    from participant p, trialcom t, ethics s
    where p.status='A'
    and p.surname=t.surname
    and p.initials=t.initials
    and s.trial_cd = t.tricom
    and s.centre = t.centre
    and p.email is not null
    and (t.centre in (select code from mail_parameters where user_name=user and mail_para='CENTRE')
    or 'XX' in (select code from mail_parameters where user_name=user and mail_para='CENTRE'))
    and (t.tricom in (select code from mail_parameters where user_name=user and mail_para='TRIAL')
    or 'XX' in (select code from mail_parameters where user_name=user and mail_para='TRIAL'))
    and (t.role in (select code from mail_parameters where user_name=user and mail_para='ROLE')
    or 'XX' in (select code from mail_parameters where user_name=user and mail_para='ROLE'))
    and (p.country in (select code from mail_parameters where user_name=user and mail_para='COUNTRY')
    or 'XX' in (select code from mail_parameters where user_name=user and mail_para='COUNTRY'))
    and (t.represent in (select code from mail_parameters where user_name=user and mail_para='REPRESENT')
    or 'XX' in (select code from mail_parameters where user_name=user and mail_para='REPRESENT'));
    This is in a program unit that runs when a button is clicked. At the end of that I need to add on the 3 case statements that help further narrow down the selection of emails to be printed. Then it prints the emails selected from this statement into a file. So it has to be done right in the select statement. The three table variables are the all_off_trt, all_deceased, and no_enroll. The form has 3 checkboxes. One for each, that when checked (giving the variable associated with the checkboxes a value of 'Y') excludes all emails that have a 'Y' in the coresponding table variable.

  • Nested IF Statement in WHERE clause...

    Here is a really abridged sample of my package. I need to ensure that if a salesrep has a status of 'I' (for "inactive") that the next salesrep with a status of 'A' (for "active") will be selected in its place.
    Should I include a nested loop within the WHERE clause? Any tips on how I should go about it? I'm a newbie...thanks for the help..
    SELECT rsa.name rep_name
    ,rsa.attribute7 rep_phone
    ,rsa.arrtibute8 rep_ext
    FROM ra_salesreps_all rsa
    WHERE rsa.status(+) = 'A'

    I'm assuming that this is part of your procedure within a package.....
    You must be writing a CURSOR here....
    Cursors are memory locations that can store retrieved rows and then process them one by one.
    create or replace procedure my_proc
    (<example_var> IN|OUT TYPE)
    IS
    cursor my_cursor IS
    select <the fields I want>
    from <sales type table>
    where <my value> = 'A';
    BEGIN
    <how to process the cursor>
    You can write the cursor process 2 ways:
    1) FOR x in <name_of_cursor> LOOP
    (This does whatever to the data for every record already selected by the cursor)
    2) OPEN....FETCH....CLOSE
    This is only scratching the surface of cursors...you need to read about these for what you are doing.
    Question though...is this something you need to run for a SQL process in Oracle Applications??....if so you don't need to write a package/ procedure. You can write a cursor and load it as type SQL*PLUS, and it will run for you.
    null

  • AND and OR operations in WHERE clause

    Hello, Dear Oracle professionals.
    In WHERE clause when I use AND or OR operations, is there any way of working ORACLE server to select rows?
    For example
    WHERE con1 and con2 and con3 and con4 and con5OR
    WHERE con1 or con2 or con3 or con4 or con5How oracle checks this conditions ? From the begining to the end ? in order ?
    May be I should put some more probable TRUE condition to the end(or to the begin).
    Whant to know how oracle thinks.
    Thanks in advance.

    Hi,
    Khayyam wrote:
    Hello, Dear Oracle professionals.
    In WHERE clause when I use AND or OR operations, is there any way of working ORACLE server to select rows?
    For example
    WHERE con1 and con2 and con3 and con4 and con5OR
    WHERE con1 or con2 or con3 or con4 or con5How oracle checks this conditions ? From the begining to the end ? in order ?It evalauates the one that is likely to make the most difference first. In the case of AND, that means the condition that is least likely to be true (as far as the optimizer can predict).
    May be I should put some more probable TRUE condition to the end(or to the begin).It doesn't matter to the optimizer. Do whatever you find easier to read and debug.
    In ancient times, using the rule-based optimizer, order did matter, but there's no reason to be using the rule-based optimizer now. Oracle 11 doesn't even have the option.
    By the way, be careful not to mix AND and OR without parentheses. That is, never say:
    WHERE  x AND y OR z    -- ***** No!  Wrong!  ******Instead say
    WHERE  (x AND y) OR z   or
    WHERE  x AND (y OR z)   depending on what you want. If you don't use partentheses, then there are rules about how the expresssion is evaluated, but it's a waste of your time to learn them.

Maybe you are looking for

  • Its almost 2012 and no OS X 10.7 in-browser support

    Hello all, According to the Advisory "Adobe Safari 5.1 and Adobe Reader/Acrobat Advisory", a better solution to this whole Safari 5.1 fiasco is to be expected by the end of this year but nothing seems to be in the horizon yet. Its been almost 6 month

  • Making & Burning Slideshow using 'slideshow' at bottom of iPhoto Library?

    Hello. I would appreciate if someone can help me from beginning to finished product of making a slideshow using for example the Snapshot effect and music from iTunes. I will go over in point form to the point where I am unable to proceed any further:

  • Convert video

    Hi. i just want to know if there is an aplication to convert ANY kind of video format to another kind of video format. for example: avi to quicktime, or mpg2 to iphone. etc...etc.... working and converting any video format to any format again. please

  • Change Font to Bold in ALV GRID

    Hi, I want to display only first row in my ALV in Bold font and rest in normal font. Could anyone help me out?

  • I'll be more clear

    I see in the forums where many people have had this problem. I just dont know the solution. The pictures that show up through desktop manager have transferred over to my mac, but I can't get the ones on device memory (memory/home/user/pictures). (I w