PL/SQL --forall clause

<div class="jive-quote">
CREATE OR REPLACE PROCEDURE IND_MONITOR(P_tab VARCHAR2)
is
type ind_table is table of varchar2(20);
p_ind ind_table;
v_sql varchar2(2000);
begin
select index_name bulk collect into P_Ind from user_indexes where table_name=upper(P_tab);
for i in 1..p_ind.count loop
v_sql :='alter index '||p_ind(i)|| ' monitoring usage'
execute immediate v_sql using p_ind(i);
end loop;
end;
can i use forall instead of 'for loop ..end loop'
</div>

jeneesh wrote:
please refer Re: Two DML operations in one FORALL?; example from Billy..As I stated in reply to Billy, FORALL can be used with EXECUTE IMMEDIATE but it does not have the advantages you get from using FORALL with a single DML statement.
FORALL with a single DML statement reduces context switches between PL/SQL and SQL. EXECUTE IMMEDIATE means more context switches, not fewer.
FORALL with a single DML statement means less work for SQL, since it "executes" the statement once even though it does the work on multiple rows. With EXECUTE IMMEDIATE, there are just as many executions as if you used a simple FOR loop.
Billy's technique may be worthwhile in client-side code, because it reduces the number of network round trips. I don't think it's a good idea in server-side PL/SQL.

Similar Messages

  • Help with SQL MODEL Clause

    I have the privilege of performing a very tedious task.
    We have some home grown regular expressions in our company. I now need to expand these regular expressions.
    Samples:
    a = 0-3
    b = Null, 0, 1
    Expression: Meaning
    1:5: 1,2,3,4,5
    1a: 10, 11, 12, 13
    1b: 1, 10, 11
    1[2,3]ab: 120, 1200, 1201, ....
    It get's even more inetersting because there is a possibility of 1[2,3]a.ab
    I have created two base queries to aid me in my quest. I am using the SQL MODEL clause to solve this problem. I pretty confident that I should be able to convert evrything into a range and the use one of the MODEL clause listed below.
    My only confusion is how do I INCREMENT dynamically. The INCREMENT seems to be a constant in both a FOR and ITERATE statement. I need to figure a way to increment with .01, .1, etc.
    Any help will be greatly appreciated.
    CODE:
    Reference:          http://www.sqlsnippets.com/en/topic-11663.html
    Objective:          Expand a range with ITERATE
    WITH t AS
    (SELECT '2:4' pt
    FROM DUAL
    UNION ALL
    SELECT '6:9' pt
    FROM DUAL)
    SELECT pt AS code_expression
    -- , KEY
    -- , min_key
    -- , max_key
    , m_1 AS code
    FROM t
    MODEL
    PARTITION BY (pt)
    DIMENSION BY ( 0 AS KEY )
    MEASURES (
                        0 AS m_1,
                        TO_NUMBER(SUBSTR(pt, 1, INSTR(pt, ':') - 1)) AS min_key,
                        TO_NUMBER(SUBSTR(pt, INSTR(pt, ':') + 1)) AS max_key               
    RULES
    -- UPSERT
    ITERATE (100000) UNTIL ( ITERATION_NUMBER = max_key[0] - min_key[0] )
    m_1[ITERATION_NUMBER] = min_key[0] + ITERATION_NUMBER
    ORDER BY pt, m_1
    Explanation:
    Line numbers are based on the assupmtion that "WITH t AS" starts at line 5.
    If you need detailed information regarding the MODEL clause please refer to
    the Refrence site stated above or read some documentation.
    Partition-
    Line 18:     PARTITION BY (pt)
                   This will make sure that each "KEY" will start at 0 for each value of pt.
    Dimension-
    Line 19:     DIMENSION BY ( 0 AS KEY )     
                   This is necessary for the refrences max_key[0], and min_key[0] to work.
    Measures-
    Line 21:      0 AS m_1
                   A space holder for new values.
    Line 22:     TO_NUMBER(SUBSTR(pt, 1, INSTR(pt, ':') - 1)) AS min_key
                   The result is '1' for '1:5'.
    Line 23:     TO_NUMBER(SUBSTR(pt, INSTR(pt, ':') + 1)) AS max_key                                        
                   The result is '5' for '1:5'.
    Rules-
    Line 26:     UPSERT
                   This makes it possible for new rows to be created.
    Line 27:     ITERATE (100000) UNTIL ( ITERATION_NUMBER = max_key[0] - min_key[0] )
                   This reads ITERATE 100000 times or UNTIL the ITERATION_NUMBER = max_key[0] - min_key[0]
                   which would be 4 for '1:5', but since the ITERATION_NUMBER starts at 0, whatever follows
                   is repaeted 5 times.
    Line 29:     m_1[ITERATION_NUMBER] = min_key[0] + ITERATION_NUMBER
                   m_1[ITERATION_NUMBER] means m_1[Value of Dimension KEY].
                   Thus for each row of KEY the m_1 is min_key[0] + ITERATION_NUMBER.
    Reference:          http://www.sqlsnippets.com/en/topic-11663.html
    Objective:          Expand a range using FOR
    WITH t AS
    (SELECT '2:4' pt
    FROM DUAL
    UNION ALL
    SELECT '6:9' pt
    FROM DUAL)
    , base AS
    SELECT pt AS code_expression
    , KEY AS code
    , min_key
    , max_key
         , my_increment
    , m_1
    FROM t
    MODEL
    PARTITION BY (pt)
    DIMENSION BY ( CAST(0 AS NUMBER) AS KEY )
    MEASURES (
                        CAST(NULL AS CHAR) AS m_1,
                        TO_NUMBER(SUBSTR(pt, 1, INSTR(pt, ':') - 1)) AS min_key,
                        TO_NUMBER(SUBSTR(pt, INSTR(pt, ':') + 1)) AS max_key,     
                        .1 AS my_increment     
    RULES
    -- UPSERT
              m_1[FOR KEY FROM min_key[0] TO max_key[0] INCREMENT 1] = 'Y'
    ORDER BY pt, KEY, m_1
    SELECT code_expression, code
    FROM base
    WHERE m_1 = 'Y'
    Explanation:
    Line numbers are based on the assupmtion that "WITH t AS" starts at line 5.
    If you need detailed information regarding the MODEL clause please refer to
    the Refrence site stated above or read some documentation.
    Partition-
    Line 21:     PARTITION BY (pt)
                   This will make sure that each "KEY" will start at 0 for each value of pt.
    Dimension-
    Line 22:     DIMENSION BY ( 0 AS KEY )     
                   This is necessary for the refrences max_key[0], and min_key[0] to work.
    Measures-
    Line 24:      CAST(NULL AS CHAR) AS m_1
                   A space holder for results.
    Line 25:     TO_NUMBER(SUBSTR(pt, 1, INSTR(pt, ':') - 1)) AS min_key
                   The result is '1' for '1:5'.
    Line 26:     TO_NUMBER(SUBSTR(pt, INSTR(pt, ':') + 1)) AS max_key                                        
                   The result is '5' for '1:5'.
    Line 27:     .1 AS my_increment     
                   The INCREMENT I would like to use.
    Rules-
    Line 30:     UPSERT
                   This makes it possible for new rows to be created.
                   However seems like it is not necessary.
    Line 32:     m_1[FOR KEY FROM min_key[0] TO max_key[0] INCREMENT 1] = 'Y'
                   Where the KE value is between min_key[0] and max_key[0] set the value of m_1 to 'Y'
    */

    Of course, you can accomplish the same thing without MODEL using an Integer Series Generator like this.
    create table t ( min_val number, max_val number, increment_size number );
    insert into t values ( 2, 3, 0.1 );
    insert into t values ( 1.02, 1.08, 0.02 );
    commit;
    create table integer_table as
      select rownum - 1 as n from all_objects where rownum <= 100 ;
    select
      min_val ,
      increment_size ,
      min_val + (increment_size * n) as val
    from t, integer_table
    where
      n between 0 and ((max_val - min_val)/increment_size)
    order by 3
       MIN_VAL INCREMENT_SIZE        VAL
          1.02            .02       1.02
          1.02            .02       1.04
          1.02            .02       1.06
          1.02            .02       1.08
             2             .1          2
             2             .1        2.1
             2             .1        2.2
             2             .1        2.3
             2             .1        2.4
             2             .1        2.5
             2             .1        2.6
             2             .1        2.7
             2             .1        2.8
             2             .1        2.9
             2             .1          3
    15 rows selected.--
    Joe Fuda
    http://www.sqlsnippets.com/

  • How can I set a variable number of values in a SQL IN clause?

    Hi,
    How can I set a variable number of values in a SQL IN clause without having to change the text of the SQL statement each time?
    I read the link http://radio.weblogs.com/0118231/2003/06/18.html. as steve wrote.
    SELECT *
    FROM EMP
    WHERE ENAME IN (?)
    But we need the steps not to create type in the system and would there be any other solution if we would like to use variable number of values in a SQL IN clause ?
    We are using JDeveloper 10.1.3.2 with Oracle Database 10.1.3.2
    Thanks
    Raj

    Hi,
    can you please explain why the solution from steve is not the right solution for you.
    regards
    Peter

  • Generate a SQL "IN" clause using ALDSP

    Problem Summary
    ALDSP: Generate a SQL "IN" clause
    Problem Description
    I would like to know if there is a possibility of generating an SQL "IN" clause using ALDSP.
    I would need the XQuery construct to create an SQLsomething like-
    select * from emp where dept_no in ('101', '201', '301');
    The values for dept_no would be passed at runtime.
    (Or)
    Will be I able to create a physical data service using the SQL - select * from emp where dept_no in ?
    If yes, how do I map the parameter to "?"
    Thanks.

    Mike,
    Thanks for the response. The section that you are taking about is to push joins to DB. Joining tables is not the problem that I am facing.
    I will rephrase the problem.
    I would like to know if there is a possibility of creating a ALDSP physical data service (.ds file) with the SQL as select * from employee where emp_id in ?
    and I should be able to pass multiple employee ids to the "?" parameter. select * from emp where emp_id in ('101', '201', '301');
    There is no fixed number of ids that a user can pass.
    Thanks.

  • SQL IN clause with a Tool variable

     

    We are using using Forte 3.M.2 (just upgraded from 3.G, finally).
    Platform is AIX 4.3. Database is DB2 (UDB) (version 5.2 i think).
    True, I haven't tried my code on any other platform. I think it should work on NT, because one of our other teams members has set up an NT laptop for portable demos. And it has DB2 (NT version i guess) loaded on it.
    Dynamic sql is not really that bad, if you have to go that route to build your list.
    Let me know how it goes.
    Steven Barnes
    Daniel Gonz&aacute;lez de Lucas <danieleam.es> 07/28/00 04:06AM >>>We are getinng some trouble, the DB Manager seems to try to convert
    :OfficeList to a unique integer lets say:
    :OfficeList value is 3,4,7
    so the IN clause
    trying with Oracle 8.1.5 converts 3,4,7 in a unique integer (a extrange
    value because doesn't match with 3,4 nor 7).
    trying with SQL Server 6.5 gives an error converting 3,4,7 to a unique
    tinyint.
    The idea is that with your sintax the DB Manager must split the TextData
    into 3 integer values. I think that it works fine in some DB Managers and
    not in others.
    Which release and vendor of DB Manager you use?
    Which Fort&eacute; release?
    Thank you very much in advance.
    Daniel.
    ----- Original Message -----
    From: "Steve Barnes" <DHS9126dhs.state.il.us>
    To: <danieleam.es>; <kamranaminyahoo.com>
    Sent: Thursday, July 27, 2000 1:55 PM
    Subject: Re: (forte-users) SQL IN clause with a Tool variable
    I needed to have an "IN" clause for some numbers. Here's how I did it:
    GetOffices():TextData method...
    Offices : TextData = new ;
    for (x : integer) in sql select MyIntegerColumn
    from MY_TABLE
    where whatever condition
    on session MyDBSession do
    Offices.Concat(x) ;
    Offices.Concat(',') ;
    end for ;
    return (Offices.CopyRange(0,Offices.ActualSize -1)) ; // get rid of lastcomma
    in actual sql.....
    OfficeList : TextData ;
    OfficeList = GetOffices() ;
    sql select * from MyTable where MyField in (:OfficeList)
    on session MyDBSession ;
    Works very well.
    Steven Barnes
    Daniel Gonz&aacute;lez de Lucas <danieleam.es> 07/27/00 05:32AM >>>Hello,
    To do a select we have two options:
    select * from MyTable
    where MyField in ('a','b','c')
    we would like to do the same but using a fort&eacute; variable in the IN clause.
    select * from MyTable
    where MyField in (:ToolVar)
    What should we do and what kind of variable or array of variables shouldwe use in ToolVar to do the same than in first option?
    >
    Has anybody done this without a dynamic query?
    Best regards
    Daniel
    For the archives, go to: http://lists.xpedior.com/forte-users and use
    the login: forte and the password: archive. To unsubscribe, send in a new
    email the word: 'Unsubscribe' to: forte-users-requestlists.xpedior.com

  • SQL IN clause with Bind parameter?

    Hi
    I have a simple task that hasn't been so simple to figure out. I want to allow a user to search for one or more comma-separated values in a simple JClient ADF app. Is there a way to use a SQL IN clause with a single bind variable? e.g. SELECT TITLE FROM CITATION WHERE ID IN (:0)
    When I pass a single value it works fine but a comma separated list doesn't.
    Thanks
    John

    Update: I wanted to combine the techniques found in two of Steve Muench's articles -
    1) Providing Default Values for View Object Bind Variables (so I could display an ADF-bound JPanel with defaults)
    http://radio.weblogs.com/0118231/stories/2004/10/07/providingDefaultValuesForViewObjectBindVariables.html
    2) Array of String Domain Example (so a user could enter one or more comma-separated values into a text box for DB searches)
    http://radio.weblogs.com/0118231/stories/2004/09/23/notYetDocumentedAdfSampleApplications.html
    I learned some helpful stuff about the framework but spent lots of time banging my head against the wall because the two examples wouldn't work when directly combined. To best understand this, be sure to study Steve's examples above.
    In example 1 Steve passes an array of objects (Object[] DEFAULT_VALUES) to the ViewObject's where clause using the setWhereClauseParams(Object[] values). However, in example 2 he creates an Oracle Array which contains an Oracle ArrayDescriptor, Connection, and array of values to pass to the "IN" bind variable. Also, example 1 allows for multiple bind vars to be included whereas example 2 allows for an array of data to be passed to a single bind var. Even though my code provides an array to a single bind var (per ex. 2) it should still allow for the passage of multiple bind vars with minimal code modification.
    Code from Steve's example 1 was copied into my EmpView ViewObject but certain modifications were necessary:
    1) Change the ViewObject's DEFAULT_VALUES from Object[] to String[].
    2) Modify the executeQueryForCollection() method in the ViewObject to call a function which will set the bind variables as Oracle Arrays (effectively converting the "params" data type from that of String[] to Oracle Array[])
    3) Create a setManagerID(String[]) method in the EmpView object and expose it to the client.
    (there are a number of others so it's best for you to go through the code and compare)
    I finally got it working so I'm attaching the code, however beware - I'm new to this so there may be other, better ways to go about it. Also, there are no framework bind vars so that section of code is never executed...it compiles but may fail at run time.
    In order for this to work I suggest you use JDev to re-create the EmpView and Panel1 objects. This will ensure that the necessary ADF framework components are generated. Once complete, then copy in the code provided.
    *File: EmpViewImpl.java
    *Created as Read-Only access view object with the
    *query:
    *select manager_id, last_name from hr.employees
    *where manager_id IN
    *(select * from TABLE(CAST(:0 as TABLE_OF_VARCHAR)))
    *order by manager_id
    package model;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import oracle.jbo.domain.Array;
    import oracle.jbo.server.ViewObjectImpl;
    import oracle.sql.ArrayDescriptor;
    // --- File generated by Oracle ADF Business Components Design Time.
    // --- Custom code may be added to this class.
    // --- Warning: Do not modify method signatures of generated methods.
    public class EmpViewImpl extends ViewObjectImpl implements model.common.EmpView
    private ArrayDescriptor descriptor;
    private final static String[] DEFAULT_VALUES_STRING = new String[]{"100"};
    private final static int NUM_DEFAULT_VALUES = DEFAULT_VALUES_STRING.length;
    * This is the default constructor (do not remove)
    public EmpViewImpl()
    protected void executeQueryForCollection (Object qc, Object[] params, int numUserParams)
    Object pars[] = null;
    // Bind default variables only if none have been provided by the user
    if (numUserParams == 0)
    numUserParams = NUM_DEFAULT_VALUES;
    int numFwkSuppliedBindVals = (params != null) ? params.length : 0;
    if (numFwkSuppliedBindVals > 0)
    // Allocate a new Object[] array with enough room for both user- and framework-supplied vars
    Object[] newBinds = new Object[numFwkSuppliedBindVals + numUserParams];
    // Copy the framework-supplied bind variables into a new Object[] array
    // leaving enough slots at the beginning for the user-supplied vars
    System.arraycopy(params, 0, newBinds, numUserParams, numFwkSuppliedBindVals);
    // Now copy in the user-supplied vars to the beginning of the array
    System.arraycopy(DEFAULT_VALUES_STRING, 0, newBinds, 0, numUserParams);
    params = newBinds;
    } else
    params = DEFAULT_VALUES_STRING;
    // We have to call this method to convert the default values into the proper Oracle Array expected by the query.
    // If you set a debugger breakpoint at this line you can see that the "params" data type changes from String[] to Object[]
    setWhereClauseParamsToDefaultValues();
    // Now retrieve the params of the new data type
    params = this.getWhereClauseParams();
    super.executeQueryForCollection(qc, params, numUserParams);
    private void setWhereClauseParamsToDefaultValues()
    this.setManagerID(DEFAULT_VALUES_STRING);
    private Connection getCurrentConnection() throws SQLException
    // Create a bogus statement so that we can access our current connection
    // JBD note - Does this get run each time??
    PreparedStatement st = getDBTransaction().createPreparedStatement("commit", 1);
    Connection conn = st.getConnection();
    st.close();
    return conn;
    private synchronized void setupDescriptor(Connection conn) throws SQLException
    descriptor = new ArrayDescriptor("TABLE_OF_VARCHAR", conn);
    * setManagerID
    * Exposed to client to accept an array of values (presumably passed in by user-entry into text box
    * @param aryMan
    public void setManagerID(String[] aryMan)
    Array arr = null;
    try
    // Find the connection
    Connection conn = getCurrentConnection();
    //Create the ArrayDescriptor by looking for our custom data type in our connected DB
    if(descriptor == null)
    setupDescriptor(conn);
    // Create the Oracle Array by passing in the descriptor, connection, and object array of data
    arr = new Array(descriptor, conn, aryMan);
    } catch (SQLException se)
    System.out.println("SQL Exception: " + se.getMessage());
    // Now we can set the WHERE clause parameter bind variable (index = 0) to the Oracle Array
    if (arr != null) setWhereClauseParam(0, arr);
    * FILE: Panel1.java
    * Created as an empty panel. Then a JTextField, a
    * JButton, and an EmpView1 table were dragged on.
    * A custom actionPerformed method was created for the
    * JButton which grabs the data from the text box.
    * The user can enter either a single manager id or
    * multiple, comma-separated ids.
    * All code in this class was created by JDev except
    * for the Jbutton action
    package view;
    import java.awt.*;
    import javax.swing.*;
    import model.common.*;
    import oracle.jbo.ApplicationModule;
    import oracle.jbo.SQLStmtException;
    import oracle.jbo.uicli.jui.*;
    import oracle.jbo.uicli.controls.*;
    import oracle.jbo.uicli.binding.*;
    import oracle.jdeveloper.layout.*;
    import oracle.adf.model.*;
    import oracle.adf.model.binding.*;
    import java.util.ArrayList;
    import oracle.jdeveloper.layout.VerticalFlowLayout;
    import javax.swing.JTextField;
    import javax.swing.JButton;
    import javax.swing.JTable;
    import javax.swing.table.TableModel;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    public class Panel1 extends JPanel implements JUPanel
    * NOTE: You need to have previous created the Oracle8 type named
    * ==== TABLE_OF_VARCHAR by doing the following at the SQL*Plus
    * command prompt:
    * create type table_of_varchar as table of varchar2(20)
    // Panel binding definition used by design time
    private JUPanelBinding panelBinding = new JUPanelBinding("Panel1UIModel");
    private VerticalFlowLayout verticalFlowLayout1 = new VerticalFlowLayout();
    private JTextField jTextField1 = new JTextField();
    private JButton jButton1 = new JButton();
    private JTable jTable1 = new JTable();
    * The default constructor for panel
    public Panel1()
    * the JbInit method
    public void jbInit() throws Exception
    this.setLayout(verticalFlowLayout1);
    jTextField1.setText("jTextField1");
    jButton1.setText("jButton1");
    jButton1.addActionListener(new ActionListener()
    public void actionPerformed(ActionEvent e)
    jButton1_actionPerformed(e);
    this.add(jTextField1, null);
    this.add(jButton1, null);
    this.add(jTable1, null);
    jTable1.setModel((TableModel)panelBinding.bindUIControl("EmpView1", jTable1));
    public static void main(String [] args)
    try
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    catch(Exception exemp)
    exemp.printStackTrace();
    Panel1 panel = new Panel1();
    panel.setBindingContext(JUTestFrame.startTestFrame("DataBindings.cpx", "null", panel, panel.getPanelBinding(), new Dimension(400, 300)));
    panel.revalidate();
    * JUPanel implementation
    public JUPanelBinding getPanelBinding()
    return panelBinding;
    private void unRegisterProjectGlobalVariables(BindingContext bindCtx)
    JUUtil.unRegisterNavigationBarInterface(panelBinding, bindCtx);
    private void registerProjectGlobalVariables(BindingContext bindCtx)
    JUUtil.registerNavigationBarInterface(panelBinding, bindCtx);
    public void setBindingContext(BindingContext bindCtx)
    if (panelBinding.getPanel() == null)
    panelBinding = panelBinding.setup(bindCtx, this);
    registerProjectGlobalVariables(bindCtx);
    panelBinding.refreshControl();
    try
    jbInit();
    panelBinding.refreshControl();
    catch(Exception ex)
    panelBinding.reportException(ex);
    private void jButton1_actionPerformed(ActionEvent e)
    // Get the user-supplied values
    String txt = jTextField1.getText();
    String[] mIds = txt.split(",");
    // Now trim
    for (int i=0; i<mIds.length; i++)
    mIds[i] = mIds.trim();
    ApplicationModule am = (ApplicationModule)panelBinding.getDataControl().getDataProvider();
    EmpView vo = (EmpView)am.findViewObject("EmpView1");
    vo.setManagerID(mIds);
    try
    vo.executeQuery();
    } catch (SQLStmtException s)
    System.out.println("Query failed: " + s.getMessage());

  • Can a SQL WITH Clause be used in Materialized View

    Hello,
    Can we use SQL WITH clause in Materialized View.
    Thanks

    Hello,
    Here is an example
    CREATE MATERIALIZED VIEW MV_TEST
    BUILD IMMEDIATE
    REFRESH FORCE ON DEMAND
    AS
    WITH t AS (SELECT owner, object_type, COUNT ( * )
               FROM my_objects
               GROUP BY object_type, owner)
    SELECT *
    FROM t
    WHERE owner IN ('SYS', 'SYSTEM');Regards

  • PL/SQL forall operator speeds 30x faster for table inserts

    Hi!
    I find this quotes from one internet website. According to this site - "Loading an Oracle table from a PL/SQL array involves expensive context switches, and the PL/SQL FORALL operator speed is amazing. " But, i knew something opposite - that normal SQL insertion always faster than this one. There may be some exception - but not always. Pls go through the link --
    [url http://www.dba-oracle.com/oracle_news/news_plsql_forall_performance_insert.htm]PL/SQL FORALL operator speed is amazing In Oracle .
    Anyone who have knowledge regarding this - pls share their views or opinion here to clear my doubt. I'll be waiting for the reply. Thanks in advance.
    Regards.
    Satyaki De.

    Hi Satyaki,
    The forall bulk processing is always faster than the row by row processing as shown in this test.
    It is faster because you have much less executions of the insert statement and therefore less context switches.
    I must mention that bulk fetching 100,000 records at a time isn't always a great idea for production code because
    you'll use a large amount of PGA memory.
    I guess you are confused with the "insert into products select * from products" variant. This pure SQL will beat the
    forall variant.
    From slow to fast:
    1. row by row dynamic SQL without using bind variables (execute immediate insert ...)
    2. row by row dynamic SQL with the use of bind variables (execute immediate insert ... using ...)
    3. row by row static SQL (for r in c loop insert ... values ... end loop;)
    4. bulk processing (forall ... insert ...)
    5. single SQL (insert ... select)
    Hope this helps.
    Regards,
    Rob.
    Message was edited by:
    Rob van Wijk
    Way too late ...

  • Exclude duplicate values on SQL where clause statement

    Hi!
    Are some posibilities to exclude duplicate values do not using sql aggregate functions in main select statement?
    Priview SQL statement
    SELECT * FROM
    select id,hin_id,name,code,valid_date_from,valid_date_to
    from diaries
    QRSLT
    WHERE (hin_id = (SELECT NVL(historic_id,id)FROM tutions where id=/*???*/ 59615))
    AND NVL(valid_date_to,to_date('22.12.2999','dd.mm.yyyy')) <= (SELECT NVL(valid_date_to,to_date('22.12.2999','dd.mm.yyyy'))FROM tutions where id= /*???*/ 59615)
    AND trunc(valid_date_from) >=(SELECT trunc(valid_date_from)FROM tutions where id= /*???*/ 59615)
    The result
    ID                  HIN_ID    NAME      CODE    VALID_DATE FROM                 VALID_DATE_TO    
    50512
    59564
    RE TU
    01
    07.06.2013 16:32:15
    07.06.2013 16:33:28
    50513
    59564
    TT2 
    02
    07.06.2013 16:33:23
    07.06.2013 16:33:28
    50515
    59564
    TT2 
    02
    07.06.2013 16:33:28
    07.06.2013 16:34:42
    50516
    59564
    ROD 
    03
    07.06.2013 16:34:37
    07.06.2013 16:34:42
    VALID_DATE_TO & AND VALID_DATE_FROM tutions
    07.06.2013 16:34:42
    15.07.2013 10:33:23
    In this case i got duplicate of entry TT2 id 50513  In main select statement cant use agregate functions are even posible to exclude this value from result modifying only the QLRST WHERE clause (TRUNC need to be here)
    THANKS FOR ANY TIP !
    ID.

    Hi, Ok this is working in this case
    SELECT * FROM
    select id,hin_id,name,code,valid_date_from,valid_date_to
    from diaries ahs
    QRSLT
    WHERE (hin_id = (SELECT NVL(historic_id,id)FROM aip_healthcare_tutions where id=/*???*/ 59615))
    AND NVL(valid_date_to,to_date('22.12.2999','dd.mm.yyyy')) <= (SELECT NVL(valid_date_to,to_date('22.12.2999','dd.mm.yyyy'))FROM tutions where id= /*???*/ 59615)
    AND trunc(valid_date_from) >=(SELECT trunc(valid_date_from)FROM tutions where id= /*???*/ 59615)
    AND NOT  EXISTS
    (SELECT null FROM diaries ahs WHERE  ahs.valid_date_from < QRSLT.valid_date_from
        AND QRSLT.hin_id=ahs.hin_id
        AND QRSLT.code=ahs.code);
    Result
    50512
    59564
    RE TU
    01
    07.06.2013 16:32:15
    07.06.2013 16:33:28
    50513
    59564
    TT2 
    02
    07.06.2013 16:33:23
    07.06.2013 16:33:28
    50516
    59564
    ROD 
    03
    07.06.2013 16:34:37
    07.06.2013 16:34:42
    But if the Data in tutions row  are theese(valid_date_to-null)  then NO ROWS are returning and its logical because in full result list Valid_date_from column are logical incorect
    valid_date_from                                 valid_date_to
    15.07.2013 10:33:23
    NULL
    ID                  HIN_ID    NAME      CODE    VALID_DATE FROM                 VALID_DATE_TO 
    50510
    59564
    RE TU
    01
    07.06.2013 16:33:28
    50511
    59564
    TT2 
    02
    07.06.2013 16:34:41
    50514
    59564
    ROD 
    03
    07.06.2013 16:34:41
    50520
    59564
    Params
    04
    03.07.2013 21:01:30
    50512
    59564
    RE TU
    01
    07.06.2013 16:32:15
    07.06.2013 16:33:28
    50513
    59564
    TT2 
    02
    07.06.2013 16:33:23
    07.06.2013 16:33:28
    50515
    59564
    TT2 
    02
    07.06.2013 16:33:28
    07.06.2013 16:34:42
    50516
    59564
    ROD 
    03
    07.06.2013 16:34:37
    07.06.2013 16:34:42
    Are that posible modifying where statement  if the valid_date_to in tutions are null then theese records where in diary valid_date_to is null is correct to, but need to stay previos logic
    D                  HIN_ID    NAME      CODE    VALID_DATE FROM                 VALID_DATE_TO 
    50510
    59564
    RE TU
    01
    07.06.2013 16:33:28
    null
    50511
    59564
    TT2 
    02
    07.06.2013 16:34:41
    null
    50514
    59564
    ROD 
    03
    07.06.2013 16:34:41
    null
    50520
    59564
    Params
    04
    03.07.2013 21:01:30
    null
    Thanks !
    ID.

  • Prepared Statement with SQL 'IN' Clause

    Hi,
    I am trying to write a JDBC SQL call to a database using a prepared statement, the call looks something like:
    select *
    from table
    where field in (?, ? ,?)
    this thing is that i don't know how many 'IN' parameters are needed until runtime (they come from a List), so is there an easy way of dealing with this, I haven't been able to find any information on this problem anywhere?

    >
    Hmmm...more expensive than say doing a query on on 2 billion rows with no index?
    More expensive than doing a cross server join?
    More expensive than doing a restore?
    I knew that someone would point this out. :)
    I just tried to exaggerate the importance of cursor sharing. This is one of the most important topic in DBMS world, but quite often ignored by JAVA world. I hope that you understand my good intention.
    >
    2. Insert data corresponding to bind variable to "T". Interesting idea. Please provide the algorithm for that. The only ones I can come up with
    1. Involved creating a "dynamic" SQL for the insert
    2. Doing multiple cross network inserts.
    The first of course is exactly what you said your solution prevented. The second will be more expensive than sending a single dynamically created select.Hopefully, this is not just an "interesting" idea, but very common technique in DBMS. Actually one of the common techniques. There are couple of ways to handle this kind(variable number of bind variables in "IN" clause) of problem.
    What i commented was that the simplest one. It's like this:
    (based on Oracle)
    SQL> create global temporary table bind_temp(value int);
    PreparedStatement stmt = con.prepareStatement("INSERT INTO bid_temp VALUES(?)");
    for(...) {
         stmt.setInt(1, aValue)
         stmt.addBatch();
    stmt.executeBatch();
    Statement stmt2 = con.executeQuery("SELECT * FROM target_table WHERE id IN (bind_temp)");
    ...Doesn't it look pretty? Pretty for both Java developers and DBAs.
    By virtue of the mechanism of batch processing, the total DBMS call is just twice and you need just 2 completely sharable SQL statements.
    (Hopefully you might understand that Oracle global temporary table is just session scope and we don't need them to be stored permanently)
    Above pattern is quite beneficial than these pattern of queries.
    SELECT * FROM target_table WHERE id IN (?)
    SELECT * FROM target_table WHERE id IN (?,?)
    SELECT * FROM target_table WHERE id IN (?,?,?)
    SELECT * FROM target_table WHERE id IN (?,?,?,?,.......,?)
    If you have large quantity of above patterns of queries, you should note that there are another bunch of better techniques. I noted just one of them.
    Hope this clairfies my point.

  • XSQL Using bind params with sql LIKE clause

    I am unable to use a bind-param with the LIKE clause in a SELECT statement.
    eg call .../temp.xsql?name=N
    XSQL query is this:
    <xsql:query max-rows="-1" bind-params="name">
    SELECT last_name
    FROM emp
    WHERE last_name LIKE '?%'
    </xsql:query>
    I have tried a few combinations so far with no success eg:
    WHERE last_name LIKE '{@name}%'
    WHERE last_name LIKE ?||%
    Any ideas?

    I highly recommend using XSQL's real bind variable feature wherever you can. You can read about it in the XSQL Online Documentation (Search for the "Using Bind Variables" section).
    Using this feature is more performant and more secure than using textual substitution variables.
    Here's what your page looks like using textual substitution:
    <page connection="UTD4" xmlns:xsql="urn:oracle-xsql">
      <xsql:query null-indicator="yes" >
        SELECT * FROM TC_HL7_SEG WHERE SEGMENT_CODE LIKE '{@code}%'
      </xsql:query>
    </page> .
    And here's what it would look like using real bind variables:
    <page connection="UTD4" xmlns:xsql="urn:oracle-xsql">
      <xsql:query null-indicator="yes" bind-params="code">
        SELECT * FROM TC_HL7_SEG WHERE SEGMENT_CODE LIKE ?||'%'
      </xsql:query>
    </page> .
    Using real bind variables allows the database to avoid reparsing the SQL statement everytime, which improves performance.
    Steve Muench
    JDeveloper/BC4J Development Team
    Author, Building Oracle XML Applications

  • Dynamically generated SQL IN clause

    have a CURSOR in a procedure that takes in parameters. Three of the five parameters are part of the WHERE clause where each column will be compared to via the IN keyword as opposed to the "=" because there could be more than one value passed in.
    Or better question...can this be done dynamically? If so, how?
    For example:
    SELECT *
    FROM my_table
    WHERE col_1 IN (list_1_string)
    AND col_2 IN (list_2_string)
    AND col_3 IN (list_3_string)
    How do I create the list with the approriate quotes so that the query returns the correct data if I were to manually execute it in a SQL+ session.
    Thanks,
    Gio
    Giovanni Jaramillo
    Oracle Developer Contractor
    AMGEN Inc. - Sales & Marketing Information Systems
    Thousand Oaks, CA 91320-1799
    [email protected]

    You could still put it in one select without creating additional objects if performance is not an issue:
    SELECT *
      FROM my_table
    WHERE INSTR(list_1_string, '*' || col_1 || '*', 1) > 0
       AND INSTR(list_2_string, '*' || col_2 || '*', 1) > 0
       AND INSTR(list_3_string, '*' || col_3 || '*', 1) > 0In this case values in your list_1_string, list_2_string, list_3_string should be separated with *, like *1*15*343* or any other separator, make sure this separator doesn't appear as actual data in the columns.

  • SQL 'IN' clause parsing

    I've written a program that parses SQL to identify all 'IN' and 'NOT IN' clauses like the one here:
    "SELECT x FROM tableA WHERE tableA.y IN (1,2,3,4,5)"
    I had to research all the possible keywords that can appear immediately before the left operand of the IN/NOT IN clause (i.e. before 'tableA.y' in the above example). In this case it's 'WHERE'. I also encountered 'HAVING', 'AND', 'OR' and 'NOT' (not to be confused with the 'NOT' in 'NOT IN').
    But I just discovered that 'WHEN' can precede the clause also, if the clause is within a CASE statement... as in:
    "SELECT CASE WHEN y IN (4,5,6) THEN 1 ELSE 2 END FROM tableB"
    So my question is: Are there any other keywords I have to worry about that can appear immediately before the left operand of the 'IN' clause in valid SQL? I'm trying to avoid more surprises. Thanks.
    - Jack Cochrane

    Frank, good points and good questions.
    The entire purpose of the parser is to refactor "IN" conditions within existing SQL statements into multiple IN conditions such that no single IN has more than 1000 elements, which is an Oracle limitation. So:
    SELECT x FROM tab WHERE tab.z IN (1,2,3,4,5...,3000)
    becomes:
    SELECT X FROM tab WHERE (tab.z IN (1,2,3,4,5...,1000) OR tab.z IN (1001,..2000) OR tab.z IN (2001,...3000))
    The parser must find the "IN" token, identify its operands, count the operands, and then if there are more than 1000 operands, parse backwards from the IN keyword until it finds the beginning of the IN condition, and finally refactor the condition. Conditions using "NOT IN" is handled in similar fashion. If this process has any limitations, I need to document and/or fix them.
    As for your questions:
    When the parser looks for each occurrence of "IN", it actually searches tokens separated by certain delimiters including blanks. So it won't match "HAVING".
    The parser identifies quoted strings by keeping and updating state as it parses. If it encounters a quote, it continues until it reaches the matching quote (treating escaped quotes appropriately). It knows not to parse anything between the quotes for keywords, etc.
    Parentheses are matched using state also.
    When parsing backwards to find the start of the IN condition, if the parser finds an unmatched left paren (meaning it's reached the beginning of the parenthetical block containing "IN") it stops and declares the condition as starting there (after the parenthesis). If it encounters a right paren instead, it treats everything from there back to its matching left paren as a black box whose contents are ignored for purposes of finding the beginning of the IN condition. If parsing backwards encounters "WHERE", "HAVING", "AND", "OR", or "NOT" (not counting the "NOT" in "NOT IN") it stops and declares the condition as starting after the keyword. That's why I need to know all the possible keywords that can precede an IN clause.
    Parsing forward to find operands operates in similar fashion but looks for commas, etc.
    Multiple IN occurrences are handled in a cludgy but very simple way... The parser searches left to right for the "IN" token, and once the first IN occurrence is dealt with, then it or its newly created "IN" keywords, are changed to a unique dummy string like "ZZ". Then the SQL string is searched again from the beginning for the first "IN" remaining. When all IN's are gone the dummy tokens are converted back to "IN". This handles IN's in subqueries nicely.
    I will look at how to how to refactor this:
    "...JOIN scott.emp ON e.job IN ('ANALYST', 'CLERK')... "
    However I doubt such a thing would have more than 1000 elements in our application. Thanks for all the other possibilities -- CHECK, etc.
    Thanks!
    - Jack

  • PL/SQL: how to use in parameter in select sql where clause

    Hi
    in a procedure, I need to apply 'in parameter' in 'where clause' along with other table fields. Purpose is to create dynamic select querry with multiple conditions.
    select count(*) from table xx
    where y_code=2008 and v_type in ('SI', 'TI', 'DI') ;
    my requirement is replace 'and v_type in ('SI', 'TI', 'DI')' with in parameter. pls note in paramter may contain null value.
    Regards

    ... e.g. why on earth do you want to pass in a string to be appended to the WHERE clause of an SQL.I second that and I strongly advice NOT to do it. If you really want to do it, then come back and show us, how you would prevent SQL injection. This approach is too dangerous (and too complex) IMHO.
    Do it straight forward as in the article of Tom Kyte (link in the post of BluShadow above)

  • SQL between clause & index question

    I currently have the below CTAS that uses between clause to identify the date range from the parameter table and then query a history table on a different database. The history table has index in the acct_date column. The below SQL is slow and takes a long time.
    create table temp1 as
    select acct_date,cust_ord_1,fin_fclty_2,cust_ord_ship_3,
    cust_ship_4,fin_item_5,sls_q,sls_tran_a
    from pgt.pg_orders@jtu where acct_date between
    (select value from pgm_parameters where parameter='wk_minday') and
    (select value from pgm_parameters where parameter='wk_maxday');
    Please advise of any changes that I can do to tune the script and make it execute faster. Thanks in advance.

    See:
    [url http://forums.oracle.com/forums/thread.jspa?threadID=863295] How to post a SQL tuning request
    [url http://forums.oracle.com/forums/thread.jspa?messageID=1812597] When your query takes too long
    But you might want also want to read this:
    http://jonathanlewis.wordpress.com/2008/12/05/distributed-dml/

Maybe you are looking for

  • After upgrade to Maverick Mail does not connect to server to download emails

    Since I have had my system upgraded to Maverick I can no longer download emails from my server/provider. Mail asks for the password for the user (me) and when I type it in nothing happens. There is no problem connecting to my server/provider online,

  • PR to PO with deletion indicator problem

    Hello, I need to one e.g. in conversion process. I have 3 line items and created PR with that. Now after creation of PR marked deletion indicator on second line item and save the PR. Now after release when i convert this from PR to PO i am not gettin

  • Update JTable from String[][]

    Hello everyone, I have a JTable with a slightly customized DefaultTableModel shown below: DefaultTableModel tableModel = new DefaultTableModel(rowData, columnNames){      private static final long serialVersionUID = 8655602888381735851L;      @Overri

  • Per my last post - potentially fatal mistake

    I think my software guy gave me the wrong software, I told him I need Server 2003 so I can run CF Standard. I seem to have Small Business Version, but I just checked, and I never realized Adobe recommends the Web edition. I can't get anything to hook

  • My mac has reset itself

    All of my preferences have been set to the default settings. My contacts do not show up in Address book, there are no calendars or entries in iCal, my bank data is missing from Quicken, I have no stored bookmarks in Safari, my music will not show up