Array in Where Clause

Hi,
I am having a function with an IN paramter as an array.
How do i use all the values in this array in the Where clause?
Function ( tArrayOfNos IN tArrType )
open Tstcursor FOR
select     ...
from     ...
where tNo in <all the nos in the array tArrayOfNos >
thanks for your help..

>
If i define the type inside my package and try to use the Member Of in a function, it doesn't work..
>
In the examples above you will need to have a type declared in the database, however you can create a pipelined function... something like this,
SQL> CREATE OR REPLACE Package My_Types Is
  2 
  3     Type enames_tab Is Table Of Varchar2(50);
  4 
  5  End My_Types;
  6  /
Package created
SQL> CREATE OR REPLACE Function lookup_ename Return my_types.enames_tab
  2     Pipelined Is
  3     v_row   my_types.enames_tab;
  4     cur     Sys_Refcursor;
  5     v_ename Varchar2(50);
  6  Begin
  7     v_row := my_types.enames_tab();
  8     Open cur For
  9        SELECT ename
10          FROM emp
11         WHERE ename IN ('SMITH', 'JAMES', 'WARD');
12     Loop
13        Fetch cur
14           INTO v_ename;
15        Exit When cur%Notfound;
16        v_row.Extend;
17        v_row(v_row.Count) := v_ename;
18        Pipe Row(v_row(v_row.Count));
19     End Loop;
20     Return;
21  End;
22  /
Function created
SQL> Set Serveroutput on;
SQL> Declare
  2     v_tab my_types.enames_tab;
  3  Begin
  4     SELECT ename Bulk Collect
  5       INTO v_tab
  6       FROM emp
  7      WHERE ename Member Of lookup_ename;
  8 
  9     For i IN v_tab.First .. v_tab.Last Loop
10        dbms_output.put_line(v_tab(I));
11     End Loop;
12  End;
13  /
SMITH
WARD
JAMES
PL/SQL procedure successfully completed

Similar Messages

  • How to change recordset bahaviour to accept dynamic column names in the where clause

    Hi
    im using php-mysql and i make a recordset and i want to make the column names in the where clause to be dynamic like
    "select id,name from mytable where $tablename-$myvar";
    but when i do this my i break the recordset and it disappear
    and when i use variables from advanced recordset it only dynamic for the value of the column not for the column name
    and when i write the column name to dynamic as above by hand it truns a red exclamation mark on the server behaviour panel
    so i think the only way is to change the recordset behaviour is it? if so How to make it accept dynamic column names?
    thanks in advance.

    As bregent has already explained to you, customizing the recordset code will result in Dreamweaver no longer recognizing the server behavior. This isn't a problem, but it does mean that you need to lay out your dynamic text with the Bindings panel before making any changes. Once you have changed the recordset code, the Bindings panel will no longer recognize the recordset fields.
    Using a variable to choose a column name is quite simple, but you need to take some security measures to ensure that the value passed through the query string isn't attempting SQL injection. An effective way of doing this is to create an array of acceptable column names, and check that the value matches.
    // create array of acceptable values
    $valid = array('column_name1', 'column_name2', 'column_name3');
    // if the query string contains an acceptable column name, use it
    if (isset($_GET['colname']) && in_array($_GET['colname'], $valid)) {
      $col = $GET['colname'];
    } else {
      // set a default value if the submitted one was invalid
      $col = 'column_name1'
    You can then use $col directly in the SQL query.

  • Using a WHERE clause in APEX Tree

    Hi All -
    I have an hierarchical SQL query that I'm displaying as an APEX tree.
    My sample app is here:
    https://apex.oracle.com/pls/apex/f?p=32581:29
    login: guest
    pw: app_1000
    workspace: leppard
    I am trying to add a WHERE clause so that only nodes with the lowest level children are displayed, i.e. something like 'WHERE connect_by_isleaf = 0 OR level = 5'
    The tree query with the where clause works fine in the SQL commands window, but when I add the WHERE clause to my apex tree the page no longer displays anything. Is this an issue with APEX or is there some other way to filter my results?
    Thanks in advance for any suggestions,
    john

    Connect by occurs first, the where clause then is applied to those results, effectively cutting away in the hierarchical structure. Since apex has to build a hierarchical structure from the query it relies on the level pseudocolumn, which is butchered by applying the where clause. It's a miracle you aren't even receiving errors because I'd almost expect an incorrect json array to have been built. With no top level to start from and only level 5 or leaf nodes there is no structure to present: both apex can not put out a correct representation and not jstree either. In your query you will see your "root nodes" but it is not representable.
    I'm not sure why you want to present this in a tree? Both connect_by_is_leaf and level = 5 will simply give you a list of nodes without any hierarchical structure.
    The better thing to do is to use a subquery to first limit your dataset and then use that to base the tree query on, that way you don't break any of those vital columns.
    Eg if you only want leaf nodes and their immediate parent you could go for something like this (quick mockup on some testdata):
    with dataset as (
    select node_id, parent_id
       from treedata
      where connect_by_isleaf = 0
    connect by prior node_id = parent_id
      start with parent_id = 0
    dataset2 as (
    select node_id, parent_id
      from dataset
    union all
    select node_id, null parent_id
      from treedata
    where node_id in (select parent_id from dataset)
    select level, node_id
       from dataset2
    connect by prior node_id = parent_id
      start with parent_id is null

  • Using multiple values in a where clause, for values only known at runtime

    Dear all
    I am creating a PL/SQL program which returns multiple rows of data but only where it meets a set id values that a user has previously chosen. The id values are stored in an associative array and are chosen by a user in the preceding procedure at run time.
    I know all the table and column names in advance. The only things I don't know are the exact number of ids selected from the id column and what their values will be. This will only be known at runtime. When the procedure is run by the user it prints multiple rows of data to a web browser.
    I have been reading the following posting, which I understand to a large extent, Query for multiple value search But I cannot seem to figure out how I would apply it to my work as I am dealing with multiple rows and a cursor.
    The code as I have currently written it is wrong because I get an error not found message in my web browser. I think the var_user_chosen_map_list_ids in the for cursor loop could be the problem. I am using the variable_user_chosen_map_list_ids to store all the id values from my associatative array as a string. Which I modified from the code that vidyadhars posted in the other thread.
    Should I be creating a OPEN FOR ref cursor and if so where would I put my associative array into it? At the moment I take the value, turning it into a string and IN part in the WHERE clause holds the string, allowing the WHERE clause to read all the values from it. I would expect the where clause to read everything in the string as 1 complete string of VARCHAR2 data but this would not be the case if this part of the code at least was correct. The code is as follows:
    --Global variable section contains:
    var_user_chosen_map_list_ids VARCHAR2(32767);
    PROCEDURE PROCMAPSEARCH (par_user_chosen_map_list_ids PKG_ARR_MAPS.ARR_MAP_LIST)
    IS
    CURSOR cur_map_search (par_user_chosen_map_list_ids IN NUMBER)
    IS
    SELECT MI.map_date
           MT.map_title,
    FROM map_info MI,
         map_title MT,
    WHERE MI.map_title_id = MT.map_title_id
    AND MI.map_publication_id IN
    (var_user_chosen_map_list_ids);
    var_map_list_to_compare VARCHAR2(32767) := '';
    var_exe_imm_map VARCHAR2(32767);
    BEGIN
    FOR rec_user_chosen_map_list_ids IN 1 .. par_user_chosen_map_list_ids.count
    LOOP
       var_user_chosen_map_list_ids := var_user_chosen_map_list_ids ||
       '''' ||
       par_user_chosen_map_list_ids(rec_user_chosen_map_list_ids) ||
    END LOOP;
    var_user_chosen_map_list_ids := substr(var_user_chosen_map_list_ids,
                                            1,
                                            length(var_user_chosen_map_list_ids)-1);
    var_exe_imm_map := 'FOR rec_search_entered_details IN cur_map_search
    LOOP
    htp.print('Map date: ' || cur_map_search.map_date || ' Map title: ' || cur_map_search.map_title)
    END LOOP;';
    END PROCMAPSEARCH;EXECUTE IMMEDIATE var_exe_imm_map;
    I would be grateful of any comments or advice.
    Kind regards
    Tim

    I would like to thank everyone for their kind help.
    I have now successfully converted my code for use with dynamic SQL. Part of my problem was getting the concept confused a little, especially as I could get everything work in a static cursor, including variables, as long as they did not contain multiple values. I have learnt that dynamic sql runs the complete select statement at runtime. However even with this I was getting concepts confused. For example I was including variables and the terminator; inside my select string, where as these should be outside it. For example the following is wrong:
         TABLE (sys.dbms_debug_vc2coll(par_user_chosen_map_list_ids))....
    AND MI.map_publication_id = column_value;';Where as the following is correct:
         TABLE (sys.dbms_debug_vc2coll('||par_user_chosen_map_list_ids||'))....
    AND MI.map_publication_id = column_value';PL/SQL is inserting the values and then running the select statement, as opposed to running the select statement with the variables and then accessing the values stored in those variables. Once I resolved that it worked. My revised code is as follows:
    --Global variable section contains:
    var_user_chosen_map_list_ids VARCHAR2(32767);
    var_details VARCHAR(32767);
    PROCEDURE PROCMAPSEARCH (par_user_chosen_map_list_ids PKG_ARR_MAPS.ARR_MAP_LIST)
    IS
    BEGIN
    FOR rec_user_chosen_map_list_ids IN 1 .. par_user_chosen_map_list_ids.count
    LOOP
       var_user_chosen_map_list_ids := var_user_chosen_map_list_ids ||
       '''' ||
       par_user_chosen_map_list_ids(rec_user_chosen_map_list_ids) ||
    END LOOP;
    var_user_chosen_map_list_ids := substr(var_user_chosen_map_list_ids,
                                            1,
                                            length(var_user_chosen_map_list_ids)-1);
    var_details := FUNCMAPDATAFIND (var_user_chosen_map_list_ids);
    htp.print(var_details);
    END PROCMAPSEARCH;
    FUNCTION FUNCMAPDETAILS (par_user_chosen_map_list_ids IN VARCHAR2(32767)
    RETURN VARCHAR2
    AS
    TYPE cur_type_map_search IS REF CURSOR;
    cur_map_search cur_type_map_search;
    var_map_date NUMBER(4);
    var_map_title VARCHAR2(32767);
    begin:
    OPEN cur_map_search FOR
    'SELECT MI.map_date,
           MT.map_title
    FROM map_info MI,
         map_title MT,
         TABLE (sys.dbms_debug_vc2coll(' || par_user_chosen_map_list_ids || '))
    WHERE MI.map_title_id = MT.map_title_id
    AND MI.map_publication_id = column_value';
    LOOP
    FETCH cur_map_compare INTO
    var_map_date,
    var_map_title;
    var_details := var_details || 'Map date: '||
                        var_map_date ||
                        'Map title: ' ||
                        var_map_title;
    EXIT WHEN cur_map_compare%NOTFOUND;
    END LOOP;
    RETURN var_details;
    END FUNCMAPDETAILS;Kind regards
    Tim

  • Using collections in WHERE clause

    Hi friends,
    Please help me to use an associate array in SQL query (WHERE clause). The requirement is similar to the following example:
    ===============================================
    declare
    type rec_emp is record(emp_id integer, emp_name varchar2(100));
    type ty_emp is table of rec_emp index by pls_integer;
    tb_emp ty_emp;
    type ty_emp_history is table of emp_history%rowtype index by pls_integer;
    tb_emp_history ty_emp_history;
    begin
    select emp_id, emp_name
    bulk collect into tb_emp
    from emp
    where dept_id = 10;
    --Now I want to fetch records from emp_history based on the values in tb_emp. So I want a query something like the following.
    --(I know that join can be used to achive this. But it is just an example. I need to achive this in collections.)
    select *
    bulk collect into tb_emp_history
    from emp_history
    where emp_id = tb_emp.emp_id
    and emp_name = tb_emp.emp_name;
    end;
    ===============================================
    Thanks in advance.
    Edited by: Iniyavan on Oct 26, 2012 11:50 AM

    >
    Please help me to use an associate array in SQL query (WHERE clause).
    select *
    bulk collect into some_array
    >
    there is no variable 'some_array' in what you posted.
    If you want help with your code you have to post the code you are really using, not some hacked-up version of it that has errors.
    Here is sample code that shows how to treat a collection as a table using the TABLE operator
    -- type to match emp record
    create or replace type emp_scalar_type as object
      (EMPNO NUMBER(4) ,
       ENAME VARCHAR2(10),
       JOB VARCHAR2(9),
       MGR NUMBER(4),
       HIREDATE DATE,
       SAL NUMBER(7, 2),
       COMM NUMBER(7, 2),
       DEPTNO NUMBER(2)
    -- table of emp records
    create or replace type emp_table_type as table of emp_scalar_type
    declare
    tb emp_table_type;
    deptnoList sys.OdciNumberList;
    BEGIN
    select emp_scalar_type(empno, ename, job, mgr, hiredate, sal, comm, deptno)
    bulk collect into tb from emp;
    SELECT deptno bulk collect
    INTO deptnoList
    FROM dept where deptno not in (select deptno from table(tb));
    for i in 1..deptnoList.count loop
    dbms_output.put_Line(deptnoList(i));
    end loop;
    END;Note that tb is a collection and is useds in the subquery 'select deptno from table(tb)'.

  • How to modify the where clause in this to include other things

    How do I modify the WHERE clause in this code:
    $expected = array(first_name, last_name, level, language, 'city', 'state', 'zip', );
    $query_search = 'SELECT * FROM french;
    $where = false;
    foreach ($expected as $var) {
    if (isset($_GET[$var]) && !empty($_GET[$var])) {
    if ($where) {
    $query_search .= ' AND ';
    } else {
    $query_search .= ' WHERE ';
    $where = true;
    $query_search .= $var . ' = '. GetSQLValueString($_GET[$var], 'text');
    to include things like searching multiple columns and IF NULL:
    SELECT * from MyTable where (MyCol1 = %s or MyCol1 Is Null) AND (MyCol2 = %s or MyCol2 Is Null)
    Where on earth does it go?
    Thanks
    Brian

    My goal is to have a search form and results combination that:
    1) allows the user to ignore any of the page’s existing search fields that
    they don’t need, (to search with empty form fields);
    2) to use whichever search form fields they choose to use even if the
    Registrant for whom they are searching did not insert that information when
    they registered, (they are filled in the search form but empty in the
    database table);
    3) and to permit some of the seach fields to search multiple columns, for
    example the search form field ‘sonsName’ would look for that information in
    three different database table colums, (sonsName1, sonsName2 etc.).
    You’ve given me code that permits 1) above to work beautifully. You’ve also
    sent along code that should let me accomplish the other two, and though I’ve
    been able to recreate below what I want the multiple search column to do, I
    can get neither the multiple column nor the IS NULL sections to work in the
    code you sent most recently.
    How do I take something like this:
    $colname_rsSearch = "-1";
    if (isset($_POST['first_name_now'])) {
      $colname_rsSearch = $_POST['first_name_now'];
    $colname2_rsSearch = "-1";
    if (isset($_POST['last_name_now'])) {
      $colname2_rsSearch = $_POST['last_name_now'];
    $colname3_rsSearch = "-1";
    if (isset($_POST['sonsName'])) {
      $colname3_rsSearch = $_POST['sonsName'];
    mysql_select_db($database_connStr_Milo_db, $connStr_Milo_db);
    $query_rsSearch = sprintf("SELECT milo.first_name_now, milo.last_name_now,
    milo.ws_number, milo.ws_number_3, milo.ws_number_4 FROM milo WHERE
    milo.first_name_now = %s AND milo.last_name_now = %s AND (milo.sonsName1 =
    %s) ||  (milo.sonsName2 = %s) || (milo.sonsName3 = %s)",
    GetSQLValueString($colname_rsSearch,
    "text"),GetSQLValueString($colname2_rsSearch,
    "text"),GetSQLValueString($colname3_rsSearch,
    "text"),GetSQLValueString($colname3_rsSearch,
    "text"),GetSQLValueString($colname3_rsSearch, "text"));
    $rsSearch = mysql_query($query_rsSearch, $connStr_Milo_db) or
    die(mysql_error());
    $row_rsSearch = mysql_fetch_assoc($rsSearch);
    $totalRows_rsSearch = mysql_num_rows($rsSearch);
    ?> (I’ve excluded the IS NULL part from my example, but need it in the final
    version)
    …and make it work using your code below (which permits someone to search
    with empty form fields, but does not yet enlighten me on what to group (with
    parenthesis) to make the code execute the multiple column search and the IS
    NULL parts of the search.
    mysql_select_db($database_connStr_Milo_db, $connStr_Milo_db);
    $expected = array('first_name_now', 'last_name_now', sonsName'
    $query_search = 'SELECT milo.first_name_now, milo.last_name_now,
    milo.ws_number, milo.ws_number_3, milo.ws_number_4  FROM milo';
    $where = false;
    foreach ($expected as $var) {
      if (isset($_POST[$var]) && !empty($_POST[$var])) {
        if ($where) {
          $query_search .= ' AND ';
        } else {
          $query_search .= ' WHERE ';
          $where = true;
      $query_search .= '(' . $var . ' = '. GetSQLValueString($_POST[$var],
    'text') .
      ' OR ' . $var . ' IS NULL)';
    $search = mysql_query($query_search, $connStr_Milo_db) or
    die(mysql_error());
    $row_search = mysql_fetch_assoc($search);
    $totalRows_search = mysql_num_rows($search);
    As always, thank you.

  • View where clause with "IN"

    Hi,
    Is there a nice way to specify the list eg.
    where itemNo IN(:1/?),
    where i can just set the where clause parameter with a array?

    If TABLE_OF_VARCHAR is a table type declared like this:
    CREATE TYPE TABLE_OF_VARCHAR AS TABLE OF VARCHAR2(2000);
    Then you can do this:
    select ...
    from ...
    where column_value in (select *
    from TABLE(CAST(? as TABLE_OF_VARCHAR)))
    this allows you to set an array-valued bind variable and cast its values into a table to select in the IN clause.
    This lets you have a variable number of args in the IN clause in a way that doesn't change the text of the SQL statement each time.
    I've posted a working sample project at:
    http://www.geocities.com/smuench/ArrayOfStringDomain.zip

  • Parsing an input parameter for the where clause or record select value

    In my limited CR experience, I've always used a command database connection so that I can write my own SQL.  However, now I have to parse a  pipe delimited parameter to get my value for the where clause, so I'm selecting several tables and joining them through the Database Expert Links tab.  All works fine, but after doing that and then parsing the parameter with the below formula in the Select Expert, I notice that there is no where clause in the SQL query, and although the report eventually displays the proper values, it runs through thousands of records first.  Here is my Select Expert - Record formula:
    StringVar array Parm1;
    Parm1 := Split({?DATA_AREA}, "|");
    {SO_ORDERS.CASE_ID} = Parm1[2]
    If I change "Parm1[2]" on the last line to a valid Case ID, then there is a where clause in the SQL and the report generates immediately. 
    It seems like the record select formula is applied AFTER all of the records (without a where clause) are searched when I use the parsed parameter value, but when I hard code a valid value, it places that into the where clause BEFORE the sql is executed.  Is there a way to get the parameter parsed first and then use that parsed value in the SQL where clause?
    Thanks.
    Bill

    Yes crystal will run the query first to get 100% data and then applies record selection condition. To increase the performance you need to pass the where condition at the command level instead of report level. So you need to create a report using add command like this
    select * from tablename where field={?Parameter}
    {?Parameter} is a command level parameter.
    Now insert this report as a subreport in another report which has no connection but has a parameter
    {?DATA_AREA} and create a formula like this in the main report
    Split({?DATA_AREA}, "|")[2]
    Now right click on the subreport and go to change subreport links and add this formula from main report and link this to sub report parameter {?Parameter} without linking any database field from the subreport.
    Now your subreport runs with the where clause to get the data.
    Regards,
    Raghavendra

  • Dynamic where clause - hard-parse

    Hi there,
    I landed in the middle of a situation that I'm not seeing any solution possible, so I’m turning to you for help.
    We have a batch script that occurs once a day that handles a lot of information (we're talking about thousands of data).
    In many situations we have to run select's with the where clause dynamically build.
    That is, we have a table with something like: ID - COLUMN_NAME - OPPERATOR - COLUMN_VALUE - DEPENDING_VALUE
    Our database is unique for a large number of clients (we have about 90% of my country City Hall's and then some more...), and DEPENDING_VALUE depends on each client.
    So, for each client, we build the where clause based on that table and then we get the data from another table with something like SELECT ABC FROM XPTO WHERE || WHERE_CLAUSE_BUILD using dynamic sql.
    So far so good, except we can have many different combinations of the where clause causing the select to be hard-parse for each client and we are trying to think of a better way to do this. Unfortunately we haven’t found one yet and I’m not seeing any light in the end of the tunnel…
    This is kind of difficult to explain, so I hope I was clear enough.
    Any help would be greatly appreciated.
    Thank you

    Hi, thank you for your answer.
    We are already using the USING clause and binding.
    The (we think kind of stupid) idea we had was:
    We created an array of 100 positions.
    Then we made a function that get’s the where clause and populates the array making something like:
    ‘where a = :param1 and b = :param2 and c= :param3’ and so on.
    For the remaining positions, we added ‘and 1 = :paramMax+1 and … and 1 = :paramMax+N and …’ and put :paramMax+1.value = 1 and :paramMax+N = 1.
    Then, when using the select with the where clause we opened a cursor using :param1.value, :param2.value, :param3.value, … :param100.value
    But this still is hard-parsing because I can have:
    Select x from y where a = :param1 and b = :param2 and 1 = :param3 …
    And for another client
    Select x from y where a = :param1 and 1 = :param2 and 1 = :param3 …
    The statements are different, that’s why I’m not seeing any solution.
    Thanks

  • Filter Records in WHERE clause iReports using values passed from a prgram

    I have searched for iReports manual and what i can see are docs on sale. I have managed to create jrxml file, execute it in jsp and actually view the report.
    Now i have a big list of customers from various branches and have various categories. I would like to know how to pass the parameters so that i retrieve a small list of items. e.g. WHERE cu.branch=200 AND cu.category=10. That is i would like to pass 20 and 10 to the jrxml query stored.
    In iReports i saw parameters, variables and fields but it seems like these are displayable fields.
    How will i achieve this. Am seeking for assistance.
    null

    >
    Please help me to use an associate array in SQL query (WHERE clause).
    select *
    bulk collect into some_array
    >
    there is no variable 'some_array' in what you posted.
    If you want help with your code you have to post the code you are really using, not some hacked-up version of it that has errors.
    Here is sample code that shows how to treat a collection as a table using the TABLE operator
    -- type to match emp record
    create or replace type emp_scalar_type as object
      (EMPNO NUMBER(4) ,
       ENAME VARCHAR2(10),
       JOB VARCHAR2(9),
       MGR NUMBER(4),
       HIREDATE DATE,
       SAL NUMBER(7, 2),
       COMM NUMBER(7, 2),
       DEPTNO NUMBER(2)
    -- table of emp records
    create or replace type emp_table_type as table of emp_scalar_type
    declare
    tb emp_table_type;
    deptnoList sys.OdciNumberList;
    BEGIN
    select emp_scalar_type(empno, ename, job, mgr, hiredate, sal, comm, deptno)
    bulk collect into tb from emp;
    SELECT deptno bulk collect
    INTO deptnoList
    FROM dept where deptno not in (select deptno from table(tb));
    for i in 1..deptnoList.count loop
    dbms_output.put_Line(deptnoList(i));
    end loop;
    END;Note that tb is a collection and is useds in the subquery 'select deptno from table(tb)'.

  • 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

Maybe you are looking for

  • Display total dmbtr according to mat type and month wise

    hi all, i want to display total dmbtr according to mat type and month wise. like month       mat.type  total_dmbtr jan 2008   fert           xxxxxxxxxx jan 2008   mcfe         yyyyyyyy feb 2008  fert  mmmmm

  • SAPGUI - 'Signature Design', being in different systems, QA, Tst, Prod

    With "Enjoy", I could set my Dev, QA, Tst & Prod to different colors so I can quickly tell what system I am in without looking in lower right corner. I saw a note saying with Signature Design UI, you can't change the color scheme. Is this still true

  • Report Design

    Greetings fellow developers, new and old.  I am a new developer and even newer to CR.  I need help setting up CR XI for my company. Here is my question.  In general, is CR installed on the local developer's machines for report development and then pu

  • CS6 installing trouble on my 2nd tablet PC

    Hi, I bought Cintiq Companion (graphic tablet with window 8). And tring to install CS6 from my disk. Messege "serial number you provided is valid, but a qualifying product could not be found on this computer" apper and I can't complete installation.

  • Client Push on Windows 7 x86 with IE9 open.

    I everyone, I need to validate something. I am currently deploying SCCM 2012 R2 for a client of mine. They are using mainly Windows 7 with SP1 x86 with IE9 installed. When doing  client push from the console or installing any SCCM agent update, we ar