Associative Array to Nested Table: Anything faster?

(First Post! Some ASP.NET references, but I think this really is a PL/SQL question)
I work on a team that runs an Oracle instance for data warehousing and reporting along with an ASP.NET based website for display.
Sometimes, I may want to have many parameters come in and only show records that match those parameters. For example, I may want to show all employees who are Managers or Developers and not show employees who are Accountants or Scientists. Typically, I send a parameter into my PL/SQL stored procedures as an associative array (as declared in my package specification). Once in the procedure, I convert that associative array into another associative array (as a user created SQL type) and then I'm able to use it like a nested table to join on.
My question is: in your experience, is there any way to get around this type conversion or another faster way?
For example:
-- Create the sql type
CREATE OR REPLACE TYPE DIM.sql_string_table AS TABLE OF VARCHAR2(255);
--pretend that this works and it's in a package body
declare
type string_table is table of varchar2(255) index by binary_integer;
l_job_types string_table; -- Keep in mind I'd normally be sending this via ASP.NET
l_job_types_nested sql_string_table := sql_string_table();
begin
-- Add some data
l_job_types(0) := 'Manager';
l_job_types(1) := 'Developer';
-- Do the conversion
for i in l_job_types.first .. l_job_types.last
loop
l_job_types_nested.extend;
l_job_types_nested(l_job_types_nested.count) := l_job_types(i);
end loop;
-- get some data out (we're pretending)
open fake_ref_cursor for
Select e.*
from employees e,
the(select cast(l_job_types_nested as sql_string_table) from dual) jobs_types_wanted
where e.type = value(jobs_types_wanted);
end;
The result would be all employees whose have a type that was input into the l_job_types associatve array.
See: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:110612348061
for additional reference

> I convert that associative array into another associative array (as a user created SQL type)
Just so we're clear, Oracle use the term 'associative array' to refer to the exclusively PL/SQL sparse collection type ("table of x index by pls_integer" etc) as distinct from the common nested table collection type.
Also I could be wrong but I think
SELECT ..
FROM   the(select cast(l_job_types_nested as sql_string_table) from dual) jobs_types_wantedis generally the same as
SELECT ..
FROM   TABLE(l_job_types_nested) jobs_types_wantedthough "SELECT *" and implicitly collection casting don't always mix. The "THE()" syntax is deprecated.

Similar Messages

  • Inserting a associative array into a table

    Hi,
    I am working on a process where I want to store the temporary results in an associative array. At the end of the process I plan to write the contents of the array into a table that has the same structure. (the array is defined as a %rowtype of the table)
    Is it possible to execute ONE sql statement that transfers the array into the table? I am on 10g (10.2.0.4.0)
    Here's what I have now:
    declare
      type t_emp is table of emp%rowtype index by pls_integer;
      v_emp t_emp;
    begin
      -- a process that fills v_emp with lots of data
      for i in v_emp.first .. v_emp.last
      loop
        insert into emp values v_emp(i);
      end loop;  
    end;But it would be better if the loop could be replaced by sql one statement that inserts all of v_emp into emp. Is that possible?
    Thanks!
    PS: I'm not sure whether it's a good idea to use this approach... building a table in memory and inserting it into the database at the end of the process. Maybe it's better to insert every record directly into the table... but in any case I'm curious to see if it is possible in theory :)
    Edited: Added version info

    True, SQL cannot access the PL/SQL type.
    So you can not do something like this:
    insert into emp
    select * from table(v_emp)That is not possible.
    But FORALL is possible:
    FORALL i in v_emp.first .. v_emp.last
        insert into emp values v_emp(i);FORALL makes just one "round trip" to SQL bulk binding the entire contents of the array.
    It is much more efficient than the normal FOR loop, though it is mostly a PL/SQL optimization - even the FORALL actually inserts the rows "one at the time", it just hands the entire array to the SQL engine in one go.
    If the logic has to be done procedurally, FORALL is efficient.
    If the logic can be changed so arrays can be avoided completely and everything done in a single "insert into ... select ..." statement, that is the most efficient.

  • How to  insert  300 data from associative array to backend table in PL/SQL

    HI ALL,
    I'm posting my code here:
    Creating back end table:
    Create table orlando
    ( id number(20),
    calltype number(12),
         gateway_name varchar2(25),
         accounting_id varchar2(18),
         start_time_system_ticks number(11),
         node_time_zone      varchar2(25),
         start_date varchar2(10),     
         start_time varchar2(10),
         softswitch_response number(11),
         alerting number(11)     
    Creating package:
    CREATE OR REPLACE PACKAGE r IS
    type apollo_rec is record(
    id number(20),
    calltype number(12),
         gateway_name varchar2(25),
         accounting_id varchar2(18),
         start_time_system_ticks number(11),
         node_time_zone      varchar2(25),
         start_date varchar2(10),     
         start_time varchar2(10),
         softswitch_response number(11),
         alerting number(11)
    TYPE bin_array IS TABLE OF apollo_rec INDEX BY BINARY_INTEGER;
    PROCEDURE rr (state_array bin_array);
    END ;
    SET SERVEROUT ON
    CREATE OR REPLACE PACKAGE BODY r IS
    PROCEDURE rr (state_array bin_array) IS
    BEGIN
    FOR i IN 1 .. state_array.COUNT LOOP
    INSERT INTO orlando(id,calltype,gateway_name,accounting_id,start_time_system_ticks)VALUES(state_array(i).id,state_array(i).calltype,state_array(i).gateway_name,
    state_array(i).accounting_id,state_array(i).start_time_system_ticks);
    COMMIT;
    END LOOP;
    END ;
    END ;
    I've run this code in i*SQL PLUS.But when I run this code for 5 entries there is no error but when I modify the insert statement for 300 entries(300 identifiers in the insert statement)
    it gives me error:
    Warning: Package Body created with compilation errors.
    Errors for PACKAGE BODY R:
    LINE/COL      ERROR
    7/2      PL/SQL: SQL Statement ignored
    7/14      PL/SQL: ORA-00913: too many values
    Is there any feature in PL/SQL to decrease the entries in insert statement and make the insert statement along with the program small and increase the program performance.
    Edited by: 983040 on Jan 20, 2013 11:11 PM

    Basic example (ran on 11.2.0.3):
    SQL> create table testtab( id number, day date, val varchar2(30) );
    Table created.
    SQL>
    SQL> create or replace package TestTabLib as
      2 
      3          type TTestTab is table of testtab%rowtype;
      4 
      5          procedure InsertRows( rowArray TTestTab );
      6 
      7  end;
      8  /
    Package created.
    SQL>
    SQL> create or replace package body TestTabLib as
      2 
      3          procedure InsertRows( rowArray TTestTab ) is
      4          begin
      5                  forall i in 1..rowArray.Count
      6                          insert into testtab values rowArray(i);
      7          end;
      8 
      9  end;
    10  /
    Package body created.
    SQL>
    SQL> declare
      2          rowArray        TestTabLib.TTestTab;
      3  begin
      4          --// populating the array - using a bulk fetch as
      5          --// an example
      6          select
      7                  object_id, created, object_name
      8                          bulk collect into
      9                  rowArray
    10          from    all_objects
    11          where   rownum < 11;
    12 
    13          --// bulk insert array
    14          TestTabLib.InsertRows( rowArray );
    15  end;
    16  /
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select * from testtab;
            ID DAY                 VAL
           100 2011/12/05 09:16:03 ORA$BASE
           116 2011/12/05 09:16:04 DUAL
           117 2011/12/05 09:16:04 DUAL
           280 2011/12/05 09:19:09 MAP_OBJECT
           365 2011/12/05 09:19:10 SYSTEM_PRIVILEGE_MAP
           367 2011/12/05 09:19:10 SYSTEM_PRIVILEGE_MAP
           368 2011/12/05 09:19:10 TABLE_PRIVILEGE_MAP
           370 2011/12/05 09:19:11 TABLE_PRIVILEGE_MAP
           371 2011/12/05 09:19:11 STMT_AUDIT_OPTION_MAP
           373 2011/12/05 09:19:11 STMT_AUDIT_OPTION_MAP
    10 rows selected.
    SQL>
    SQL> declare
      2          rowArray        TestTabLib.TTestTab;
      3  begin
      4          --// populating the array - using a custom build
      5          --// loop example such as a Java front-end will
      6          --// use reading data from user input form
      7          rowArray := new TestTabLib.TTestTab();
      8          rowArray.Extend(2);     --// user entered 2 values
      9          for i in 1..rowArray.Count loop
    10                  rowArray(i).id := i;
    11                  rowArray(i).day := trunc(sysdate);
    12                  rowArray(i).val := 'value '||to_char(i,'000');
    13          end loop;
    14 
    15          --// bulk insert array
    16          TestTabLib.InsertRows( rowArray );
    17  end;
    18  /
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select * from testtab where val like 'value%';
            ID DAY                 VAL
             1 2013/01/21 00:00:00 value  001
             2 2013/01/21 00:00:00 value  002
    SQL>

  • Require help on Array of Nested tables and Oracle Object type

    Hi All,
    I have a scenario where I have some millions of records received from a flat file and the record is stored in Table as below:
    Tablename: FILE_RECORD
    Rows:
    FILE_REG_ID = 1
    RECORD_NBR = 1     
    PROCESSED_IND = U
    RECORD= 00120130326006A
    FILE_REG_ID = 1
    RECORD_NBR = 2     
    PROCESSED_IND = U
    RECORD= 00120130326003
    1) I have to read these records at once and
    a) Split the RECORD column to get various other data Eg: Fld1=001, Fld2=20130326, Fld3 = 003
    b) send as an Array to Java.
    2) Java will format this into XML and sent to other application.
    3) The other application returns a response as Successful or Failure to Java in XML
    4) Java will send RECORD_NBR and the corresponding response as Success or Failure back to PLSQL
    5) PLSQL should match the RECORD_NBR and update the PROCESSED_IND = P.
    I 'm able to achieve this using SQL Table type by creating a TYPE for Each of the fields (Flds) however the problem is Java cannot Access the parameters as the TYPE are of COLUMN Types
    Eg: For RECORD_NBR
    SUBTYPE t_record_nbr IS FILE_RECORD.T010_RECORD_NBR%TYPE;
    Can you please let me know how I can achieve this to support Java, I know one way that is by creating an OBJECT TYPE and a TABLE of the OBJECT TYPE.
    Eg: T_FILE_RECORD_REC IS OBJECT
    FILE_REG_ID number(8), RECORD_NBR number (10), PROCESSED_IND varchar2(1), RECORD varchar(20)
    Create type T_FILE_RECORD_TAB IS TABLE OF T_FILE_RECORD_REC
    However I'm facing a problem to populate an Array of records, I know I'm missing something important. Hence please help.
    It would be helpful to provide some guidelines and suggestions or Pseudo or a Code to achieve this. Rest all I can take up further.
    Thanks in advance,

    I know once way that is creating a OBJECT TYPE and a TABLE of OBJECT TYPE, howeve I feel I'm missing something to achieve this.You're right, you need SQL object types created at the database level. Java doesn't know about locally defined PL/SQL types
    However you can do without all this by creating the XML directly in PL/SQL (steps 1+2) and passing the document to Java as XMLType or CLOB.
    Are you processing the records one at a time?

  • Associative Arrays, Indexes vs. Full Table Scans

    Hello,
    I just started using ODP.Net to connect my .Net Web Service to our Oracle Database. The reason why I switched to ODP.Net is support for arrays. If I wanted to pass in arrays to the procedure I had to pass it in through a varchar2 in a CSV formatted string.
    ex. "123,456,789"
    So now I'm using ODP.net, passing in PL/SQL Associative Arrays then converting those arrays to nested tables to use within queries.
    ex.
    OPEN OUT_CURSOR FOR
    SELECT COLUMN1, COLUMN2
    WHERE COLUMN_ID IN (SELECT ID FROM TABLE(CAST(ASSOC_ARR_TO_NESTED(IN_ASSOC_ARR) AS NESTED_TBL_TYPE)))
    It uses the array successfully however what it doesn't do is use the index on the table. Running the same query without arrays uses the index.
    My colleague who works more on the Oracle side has posted this issue in the database general section (link below). I'm posting here because it does seem that it is tied to ODP.Net.
    performance - index not used when call from service
    Has anyone ever experienced this before?

    You have to use a cardinality hint to force Oracle to use the index:
    /*+ cardinality(tab 10) */See How to use OracleParameter whith the IN Operator of select statement

  • Return Nested Table  Using Out Parameter

    Hi Friends,
    I wrote a function in which i'm using a return type as NUMBER and OUT parameter as TABLE but i'm not able to call the function in PL/SQL because of TABLE ,Can anyone plz tell me how to call the function in PL/sql using TABLE as OUT parameter. The calling function is mentioned below..
    FUNCTION get_label_to_folder (
    i_folder_id IN NUMBER,
    i_label_id IN NUMBER,
    i_new_path IN VARCHAR2,
    i_src_path IN VARCHAR2 DEFAULT NULL,
    --i_output_loc_type   IN       VARCHAR2,
    o_vdoc_table OUT vdocs_table
    RETURN NUMBER;
    I tried to call that function in this manner but it won't work--
    DECLARE
    TYPE vdocs_table IS TABLE OF VARCHAR2 (50);
    vdoc vdocs_array := vdocs_array ();
    vret VARCHAR2 (20);
    BEGIN
    vret :=
    sce_label_util.get_label_to_folder (32272,
    324073,
    '/test-aaaa/a1/',
    NULL,
    vdoc
    FOR i IN vdoc.FIRST .. vdoc.LAST
    LOOP
    DBMS_OUTPUT.put_line (vret || ' ,' || vdoc (i));
    END LOOP;
    END;
    Kindly check it and plz resolve the problem.
    Regards,
    Anand

    It is not the correct approach to do this (passing a collection using an OUT parameter) using a function.
    Does not matter whether you dislike it. It is still wrong.
    It should be a procedure. It should likely define the OUT parameter as being passed by reference and not value in order to decrease the call overheads and increase performance.
    Also note that is it not called a table. The correct terminology is a collection or an associative array. A table is something you get inside the database engine. The structure you define in the PL engine is nothing like a database table and everything like an array.
    PS. And how do you expect us to determine the error? How do you expect us to test anything if we do not know what Oracle version you are using? Please.. FULL details, including Oracle version number and the full Oracle error message!

  • Unable to retrieve data from a Associative Array (?)

    Hi!!!! :)))
    i've a problem!!!
    this is the oracle's code:
    Package GEST_REPORT
    IS
    type rec_url is record(
    TIBCDCON TBISD_30.TIBCDCON%TYPE,
    etc...
    SETDEL VARCHAR2(10)
    type tab2 is table of rec_url index by binary_integer;
    FUNCTION MAIN_SELECT
    ( CPLAS IN VARCHAR2)
    RETURN tab2;
    END;
    ...and a java code:
    String storedProcedure = "{? = call GEST_REPORT.MAIN_SELECT(?)}";
    String result = "";
    try{
    if (connection != null) {
    CallableStatement callableStatement = null;
    callableStatement = preprepareCall(storedProcedure);
    // preparo parametri di input.
    callableStatement.setString(2, "OM");
    callableStatement.registerOutParameter(1, oracle.jdbc.driver.OracleTypes.ARRAY, "tab2");
    and so on...
    In the last line of code throws an 'invalid name pattern'
    or
    "ORA-21700: object does not exist or is marked for delete"
    if registerOutParameter(1, oracle.jdbc.driver.OracleTypes.ARRAY, "ISDSV.GEST_REPORT").
    Where TAB2: IS THE MY ARRAY (OR NESTED TABLE?);
    GEST_REPORT: THE NAME OF PACKAGE;
    ISDSV: THE USER.
    do u have suggestion for retrieve data from TAB2 in JAVA??
    THKS!!!!!!

    Hi
    Use fully qualified type name: schema_name.type_name. For your case that would be "ISDSV.tab2"
    Cherrs :))

  • REF CURSOR to Associative Array

    I have a procedure that builds up a collection (associative array / index-by table). Is there any way to hand the collection over to ODP.NET without putting the contents into a temporary table? REF CURSOR seems to fit, but I cannot find the syntax to OPEN a REF CURSOR for the collection.
    I am trying to turn the GetResourceGroup() a_Resources parameter into a ref cursor in the example below (which, as I understand it, would also hold the collection in memory until the cursor is closed).
    Alternatively, is there a direct method? I.e. is it possible to get the collection directly into a DataTable or similar?
    Any advice gratefully received,
    Peter
    TYPE RsrcRow IS RECORD
    ResourceId Resource.ResourceId%TYPE,
    ResourceName Resource.ResourceName%TYPE
    TYPE Resources IS TABLE OF RsrcRow INDEX BY VARCHAR2(80);
    PROCEDURE GetResourceGroup(
    a_ResourceType IN VARCHAR2,
    a_Resources OUT Resources
    IS
    l_LocalCollection Resources;
    BEGIN
    GetResourcesByType(a_ResourceType, l_LocalCollection);
    -- Return resource set (need to port this to ODP.NET).
    a_Resources := l_LocalCollection;
    RETURN;
    END GetResourceGroup;

    odp.net does not have collection support right now.
    PL/SQL Associative Array should be available in next release (see other forum threads)
    1. Support for Varchar2 indexes is unlikely (since OCI does not provide such functionality). Which means you can only return an C style "array" like structure at best.
    2. Your 'GetResourceGroup' need to return REF CURSOR (or other primitive type like VARCHAR2), until Associative Array become available.
    FB

  • How do u create a datatable from PLSQL Associative Arrays returned from SP

    Using C# 4.0 ODP.NET 11g, vs2010 on Windows XP.
    Have a procedure that takes two input values and returns 35 PL\SQL Associative Arrays (pl/sql tables). I am currently able to call the proc and have it returned the values. i end up with 35 arrays each 35 elements in length.
    I want to create a datatable from them but am at a lost on how to do so.
    This what i have
    Oracle.DataAccess.Client.OracleCommand oCommand = new Oracle.DataAccess.Client.OracleCommand();
    oCommand.CommandText = ProcName;
    oCommand.CommandType = CommandType.StoredProcedure;
    //Input Parameters
    OracleParameter param1 = oCommand.Parameters.Add("p_orderid",OracleDbType.Int32);
    param1.Direction = ParameterDirection.Input;
    param1.Value = OrderID;
    OracleParameter param2 = oCommand.Parameters.Add("p_testinstanceid", OracleDbType.Int32);
    param2.Direction = ParameterDirection.Input;
    param2.Value = TestInstanceID;
    //Output Parameters
    OracleParameter param3 = oCommand.Parameters.Add("program_id", OracleDbType.Int32);
    param3.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    param3.Direction = ParameterDirection.Output;
    param3.Size = 50;
    OracleParameter param4 = oCommand.Parameters.Add("normyear", OracleDbType.Varchar2);
    param4.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    param4.Direction = ParameterDirection.Output;
    param4.Size = 50;
    param4.ArrayBindSize = new int[50];
    // set the bind size value for each element
    for (int i = 0; i < 50; i++)
    param4.ArrayBindSize[i] = 10;
    ...33 more output parameters all PLSQLAssociativeArray type
    oCommand.ExecuteNonQuery();
    OracleDataAdapter da = new OracleDataAdapter(oCommand);
    //Fill the DataTable
    da.Fill(dt);
    The datatable is empty. What am i doing wrong? Or this there a better way to get the output values to end up in a datatable. Note that when i examine the parameters in oCommand i see that they all the the right out values.

    I have multiple where conditions which needs the same subqueryThat is where the Subquery Factoring Clause comes in handy, because then
    »Oracle Database optimizes the query by treating the query name as either an inline view or as a temporary table«
    with temp as (
    subquery
    select 1
      from table1
    where col1 in (select * from temp)
       and col2 in (select * from temp)
       and col3 in (select * from temp)

  • Decide between Temoporary tables, Nested tables and Arrays

    Hello everyone.
    I need to convert T-SQL function to PL-SQL.
    I have this line in T-SQL:
    DECLARE @FTAP TABLE ([Value] [int] PRIMARY KEY NONCLUSTERED NOT NULL, UNIQUE ([Value]ASC )); As I see that, there are several equivalents in PL-SQL:
    1. Global temporary table.
    2. Nested table.
    3. Array.
    The table is declared in the function for reusing in the same function.
    When the function finished the table should delete.
    Also, the table should have index (or primary key...).
    What is the best choice?

    be careful in directly translating SQL server code to Oracle. they are fundamentally different in terminology and in the way they work.
    you can use associated arrays with record types:
    SQL> declare
      2     type rec_demo is record (id number, txt varchar2(100));
      3     type tab_demo is table of rec_demo index by binary_integer;
      4     v_tab_demo tab_demo;
      5  begin
      6
      7    v_tab_demo(1).id := 23;
      8    v_tab_demo(1).txt := 'demo';
      9    v_tab_demo(2).id := 54;
    10    v_tab_demo(2).txt := 'demo2';
    11
    12    for i in 1..v_tab_demo.count loop
    13       dbms_output.put_line(v_tab_demo(i).txt);
    14    end loop;
    15
    16
    17  end;
    18  /
    demo
    demo2you can also use collections in other ways. Most people would advise against using global temporary tables unless there's no other way and even then they'd recommend materialised views etc.
    can you elaborate a bit more about how you're using it? if we know what purpose it's being used for we may be able to assist a bit more efficiently.

  • Object tables/associative arrays are using lots of memory what is alternate

    I'm using mostly object tables/associative arrays in my package and it is using lots of server memorey so i want to use a different technicque to save momorey .
    like using create global temporary table or nested Table Store as or creating table run time at the start and droping it in the end .
    do have any suggestion for this ?
    for this package i'm retriving data from different table into object tables and do calculation in memorey before i send data to front end for reporting using reference cursor .
    give me your suggetion or if you know any example code for this type of process using different technique please let us know .
    thank you very much
    regards
    shailen Patel

    You can create a global temporary table like this:
    CREATE GLOBAL TEMPORARY TABLE AR_TRIAL_RCPT(
      LOC_ACCT_ID NUMBER(12),  
      ACCT_ID NUMBER(12),  
      CURRENCY_ID NUMBER(12),  
      AMT NUMBER(13,   4),  
      AMT_PRIMARY NUMBER(13,   4)
    [ON COMMIT PRESERVE ROWS]
    ;If you want the table truncated on COMMITs leave out the part in brackets other wise leave off the brackets and the table won't be truncated until your session terminates or you explicitly truncate the table.
    You can also define indexes, primary keys, foreign keys, check constraints, etc. on your temporary table if need be to improve processing.
    Now when it comes to inserting into your newly minted global temporary table, you should be able to use one of insert statements from the following anonymous PL/SQL block:
    CREATE GLOBAL TEMPORARY TABLE AR_TRIAL_RCPT(
      LOC_ACCT_ID NUMBER(12),  
      ACCT_ID NUMBER(12),  
      CURRENCY_ID NUMBER(12),  
      AMT NUMBER(13,   4),  
      AMT_PRIMARY NUMBER(13,   4)
    --[ON COMMIT PRESERVE ROWS]
    CREATE GLOBAL succeeded.
    declare
    l_open_receipt_select_1 varchar2(4000) :=
        'select 1, 1, 1, 12.05, 12.05 from dual';
    l_open_receipt_select_2 varchar2(4000) :=
        'select 2, 2, 1, 17.05, 17.05 from dual';
    l_open_receipt_select_3 varchar2(4000) :=
        'select 3 loc_acct_id,
      1 currency_id,
      27.05 amt,
      3 acct_id,
      27.05 amt_primary
      from dual';
    l_open_receipt_select_4 varchar2(4000) :=
        'select 4 loc_acct_id,
      1 currency_id,
      24.35 amt,
      4 acct_id,
      24.35 amt_primary
      from dual';
    l_ins_stmt varchar2(4000);
    begin
      -- If the column order is known ahead of time and is consistent
      -- You can use this form:
      l_ins_stmt :=
        'insert into ar_trial_rcpt (
      loc_acct_id, acct_id, currency_id, amt, amt_primary
      ) '||l_open_receipt_select_1||
      ' union all '||
      l_open_receipt_select_2;
      execute immediate l_ins_stmt;
      -- If the column order is NOT known ahead of time or is INconsistent
      -- You can use this form:
      l_ins_stmt :=
        'insert into ar_trial_rcpt (
      loc_acct_id, acct_id, currency_id, amt, amt_primary
      select loc_acct_id
      , acct_id
      , currency_id
      , amt
      , amt_primary
      from ('||l_open_receipt_select_3||')
      union all
      select loc_acct_id
      , acct_id
      , currency_id
      , amt
      , amt_primary
      from ('||l_open_receipt_select_4||')';
      execute immediate l_ins_stmt;
    end;
    anonymous block completed
    select * from ar_trial_rcpt
    LOC_ACCT_ID ACCT_ID  CURRENCY_ID AMT    AMT_PRIMARY
    1           1        1           12.05  12.05      
    2           2        1           17.05  17.05      
    3           3        1           27.05  27.05      
    4           4        1           24.35  24.35      
    4 rows selected

  • Associative Array vs Table Scan

    Still new to PL/SQL, but very keen to learn. I wondered if somebody could advise me whether I should use a collection (such as an associative array) instead of repeating a table scan within a loop for the example below. I need to read from an input table of experiment data and if the EXPERIMENT_ID does not already exist in my EXPERIMENTS table, then add it. Here is the code I have so far. My instinct is that it my code is inefficient. Would it be more efficient to scan the EXPERIMENTS table only once and store the list of IDs in a collection, then scan the collection within the loop?
    -- Create any new Experiment IDs if needed
    open CurExperiments;
    loop
    -- Fetch the explicit cursor
    fetch CurExperiments
    into vExpId, dExpDate;
    exit when CurExperiments%notfound;
    -- Check to see if already exists
    select count(id)
    into iCheckExpExists
    from experiments
    where id = vExpId;
    if iCheckExpExists = 0 then
    -- Experiment ID is not already in table so add a row
    insert into experiments
    (id, experiment_date)
    values(vExpId, dExpDate);
    end if;
    end loop;

    Except that rownum is assigned after the result set
    is computed, so the whole table will have to be
    scanned.really?
    SQL> explain plan for select * from i;
    Explained.
    SQL> select * from table( dbms_xplan.display );
    PLAN_TABLE_OUTPUT
    Plan hash value: 1766854993
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |      |   910K|  4443K|   630   (3)| 00:00:08 |
    |   1 |  TABLE ACCESS FULL| I    |   910K|  4443K|   630   (3)| 00:00:08 |
    8 rows selected.
    SQL> explain plan for select * from i where rownum=1;
    Explained.
    SQL> select * from table( dbms_xplan.display );
    PLAN_TABLE_OUTPUT
    Plan hash value: 2766403234
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |      |     1 |     5 |     2   (0)| 00:00:01 |
    |*  1 |  COUNT STOPKEY     |      |       |       |            |          |
    |   2 |   TABLE ACCESS FULL| I    |     1 |     5 |     2   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter(ROWNUM=1)
    14 rows selected.

  • Associative array type for each blob column in the table

    i am using the code in given link
    http://www.oracle.com/technology/oramag/oracle/07-jan/o17odp.html
    i chnages that code like this
    CREATE TABLE JOBS
    JOB_ID VARCHAR2(10 BYTE),
    JOB_TITLE VARCHAR2(35 BYTE),
    MIN_SALARY NUMBER(6),
    MAX_SALARY NUMBER(6),
    JOBPIC BLOB
    CREATE OR REPLACE PACKAGE associative_array
    AS
    -- define an associative array type for each column in the jobs table
    TYPE t_job_id IS TABLE OF jobs.job_id%TYPE
    INDEX BY PLS_INTEGER;
    TYPE t_job_title IS TABLE OF jobs.job_title%TYPE
    INDEX BY PLS_INTEGER;
    TYPE t_min_salary IS TABLE OF jobs.min_salary%TYPE
    INDEX BY PLS_INTEGER;
    TYPE t_max_salary IS TABLE OF jobs.max_salary%TYPE
    INDEX BY PLS_INTEGER;
    TYPE t_jobpic IS TABLE OF jobs.jobpic%TYPE
    INDEX BY PLS_INTEGER;
    -- define the procedure that will perform the array insert
    PROCEDURE array_insert (
    p_job_id IN t_job_id,
    p_job_title IN t_job_title,
    p_min_salary IN t_min_salary,
    p_max_salary IN t_max_salary,
    p_jobpic IN t_jobpic
    END associative_array;
    CREATE OR REPLACE package body SHC_OLD.associative_array as
    -- implement the procedure that will perform the array insert
    procedure array_insert (p_job_id in t_job_id,
    p_job_title in t_job_title,
    p_min_salary in t_min_salary,
    p_max_salary in t_max_salary,
    P_JOBPIC IN T_JOBPIC
    ) is
    begin
    forall i in p_job_id.first..p_job_id.last
    insert into jobs (job_id,
    job_title,
    min_salary,
    max_salary,
    JOBPIC
    values (p_job_id(i),
    p_job_title(i),
    p_min_salary(i),
    p_max_salary(i),
    P_JOBPIC(i)
    end array_insert;
    end associative_array;
    this procedure is called from .net. from .net sending blob is posiible or not.if yes how

    Ok, that won't work...you need to generate an image tag and provide the contents of the blob column as the src for the image tag.
    If you look at my blog entry -
    http://jes.blogs.shellprompt.net/2007/05/18/apex-delivering-pages-in-3-seconds-or-less/
    and download that Whitepaper that I talk about you will find an example of how to do what you want to do. Note the majority of that whitepaper is discussing other (quite advanced) topics, but there is a small part of it that shows how to display an image stored as a blob in a table.

  • Associative array two variable comparison :update table error

    Hi,
    i am using associative array to update the version number of table
    -i declare two associative array to compare the column from two table (temp,main tables)values in loop
    -if id's of both variable(for temp and main table) are equal and column of either of table not matching then it should update the version no of temp table
    -if id's not equal i.e record only exists temp table then update null version number annd increment it by 1
    -following is the structure and procedure --it shows the matching and non matching records but for the update statement it not giving expected output i.e it updates all records irrespective of the condition provided
    -i tried to put condition in update as well as in the  if statement but it updates all record
    ....suggestion and help highly appreciate. thankx in advance !!!
    /*--table structure and data--*/
    CREATE TABLE "TEMP_TABLE"
       ( "ID" NUMBER NOT NULL ENABLE,
      "COL1" VARCHAR2(20 BYTE),
      "COL2" VARCHAR2(20 BYTE),
      "VERSION" NUMBER
       INSERT INTO TEMP_TABLE VALUES (101,'A','B',NULL);
       INSERT INTO TEMP_TABLE VALUES (102,'x','y',NULL);
       INSERT INTO TEMP_TABLE VALUES (103,'r','t',NULL);
       CREATE TABLE "MAIN_TABLE"
       ( "ID" NUMBER NOT NULL ENABLE,
      "COL1" VARCHAR2(20 BYTE),
      "COL2" VARCHAR2(20 BYTE),
      "VERSION" NUMBER
       INSERT INTO MAIN_TABLE VALUES (101,'A','B',1);
    /*------update version procedure----------*/
    DECLARE
      TYPE T_tmp_table IS TABLE OF tmp_table %ROWTYPE INDEX BY PLS_INTEGER;
      TYPE T_main_table IS TABLE OF main_table%ROWTYPE INDEX BY PLS_INTEGER;
      l_tmp_table T_tmp_table;
      l_main_table T_main_table;
      BEGIN
        SELECT * BULK COLLECT INTO l_tmp_table FROM tmp_table;
        SELECT * BULK COLLECT INTO l_main_table FROM main_table;
        FOR i IN 1 .. l_tmp_table.count
        LOOP
          FOR j IN 1 .. l_main_table.count
         LOOP
      if(l_tmp_table(i).ID = l_main_table(j).ID AND l_tmp_table(i).VERSION IS NULL) then     
      ---this first if loop updates temp table version irrespective of l_tmp_table.ID=l_main_table.ID orl_tmp_table. ID<>l_main_table.ID  .it display proper matching and non-matching records.
       dbms_output.put_line('matching ids from tmp and main are :'||l_tmp_table(i).ID||'  '||l_main_table(j).ID);
       UPDATE tmp_table SET VERSION = l_tmp_table(i).version +1;
       --where l_tmp_table(i).ID = l_main_table(j).ID     --
       end if;
      if (l_tmp_table(i).ID <> l_main_table(j).ID) then
       dbms_output.put_line('non matching ids from tmp and main are :'||l_tmp_table(i).ID||'  '||l_main_table(j).ID);
       UPDATE tmp_table SET VERSION = l_tmp_table(i).version +1;
       --where l_tmp_table(i).ID <> l_main_table(j).ID    
        end if;
              END LOOP;
              END LOOP;
        EXCEPTION
        WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('OTHER');
    END;

    Hello user8937641
    I think there is a problem with the logic of your SQL-Code.
    But maybe in this formatted structure you can see where your problem is. -> I can not say it because I do not know what is the requirement.
    I hope it helps...
    /*------update version procedure----------*/
    DECLARE
      TYPE T_tmp_table IS TABLE OF tmp_table %ROWTYPE INDEX BY PLS_INTEGER;
      TYPE T_main_table IS TABLE OF main_table%ROWTYPE INDEX BY PLS_INTEGER;
      l_tmp_table T_tmp_table;
      l_main_table T_main_table;
      BEGIN
        SELECT * BULK COLLECT INTO l_tmp_table FROM tmp_table;
        SELECT * BULK COLLECT INTO l_main_table FROM main_table;
        FOR i IN 1 .. l_tmp_table.count
        LOOP
          FOR j IN 1 .. l_main_table.count
          LOOP
            IF     l_tmp_table(i).ID = l_main_table(j).ID
               AND l_tmp_table(i).VERSION IS NULL
             THEN
                 ---this first if loop updates temp table version irrespective of l_tmp_table.ID=l_main_table.ID orl_tmp_table. ID<>l_main_table.ID  .it display proper matching and non-matching records.
                 dbms_output.put_line('matching ids from tmp and main are :'||l_tmp_table(i).ID||'  '||l_main_table(j).ID);
                 UPDATE tmp_table
                    SET version = l_tmp_table(i).version +1;
                  WHERE id = l_tmp_table(i).ID
            END IF;
            IF l_tmp_table(i).ID <> l_main_table(j).ID
             THEN
               dbms_output.put_line('non matching ids from tmp and main are :'||l_tmp_table(i).ID||'  '||l_main_table(j).ID);
               -- Maybe you do not need this update:
               UPDATE tmp_table
                  SET version = l_tmp_table(i).version +1;
                WHERE id =  l_tmp_table(i).ID
            END IF;
            COMMIT;
           END LOOP;
        END LOOP;
      EXCEPTION WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Error at Executing the PLSQL-Block - ' || SQLERRM);
    END;

  • How to insert array of records in Storage table and  Nested table same time??

    Hi,
    I am using ProC++ ( Oracle 8i) . I want to insert a host array
    in a table. That table has a nested table in it. So for every
    record in my host array, there are muliple records to be
    inserted in Nested table. How is this possible using pro*C??
    Pls help.
    Thanks
    Nivedita

    Have a look at the Oracle 9i PL/SQL manual, which has an example.

Maybe you are looking for

  • How do I delete HP_Tools partition & turn of beep on my DV7-6153ea?

    Hi Everyone, I recently updated my bios with a HP update and a fourth partion called 'HP_Tools' has appeared on my new DV7-6153ea Windows 7 (sp1) laptop. My question is this... I don't want a fourth partition on my harddrive especially for 99mb. I'd

  • Driver wont download

    I have been having issues with my ipod not being recognized by iTunes or any PC. I spent hours going over support topics trying different and all things I could find. I did just get a new USB cord for it. Now the PC will show that it is a malfunction

  • Iphotos and apple TV

    I am struggling getting my iphotos off of my iMAC to my Apple TV.  I understand that you need to go through Itunes...and I believe the problem may be in the name of the accounts.  We have one User ID for our Apple TV/iMac and another user id for Itun

  • 2012 mini with 2 thunderbolt + hdmi

    I haven't been able to get a solid answer either way on this, so I'll ask specifically here and hopefully someone has tried. The new mini says on the features page: "You can daisy-chain as many as six Thunderbolt devices - including two Apple Thunder

  • Aperture not showing ISO Metadata for the Canon SD800

    I normally use Aperture with my Nikon D200, but someone gave me a Canon SD800 for Xmas, which is a great little point and shoot camera for times when my D200 is overkill. I notice, however, that the ISO field in Aperture is always blank for imported