To bulk table the PL/SQL collection

Hi all

version 10g 10.2.0.1

Can what I do to accomplish the following.

I need to build a collection based on the result of two SQL statements in a loop.

Example:

IS FUNCTION (get_info)

RETURN retrieval_pkg_public_ty
PIPELINED

TYPE ret_tab IS TABLE OF THE ret_rec;

BECAUSE me in 1... 2
LOOP

SELECT...
BULK COLLECT into ret_tbl
FROM (SELECT...
FROM (SELECT...

Quite a big SQL statement...

WHERE
x = parameter_value, - I'm from the changes of parameters to values
y = parameter_value,-I'm from the changes of parameters to values

END LOOP;


BECAUSE me IN ret_tbl. FIRST... ret_tbl. LAST
LOOP
COURSE OF ACTION...

END LOOP;

I can use a global temporary table to store the results of each loop and select TWG, but I prefer to use a table function.

Thank you
Mark

user1602736 wrote:
Currently I have a procedure that is called in a package that returns a SYS_REFCURSOR.

Course code of procedure is

I'm in 1.2
LOOP
INSERt INTO TWG

END LOOP;

Why not just fill the TWG using a TWG INSERT INTO SELECT... Source FROM WHERE... ?

I wanted to avoid creating a TWG to accomplish above.

Why? You do the problems with this approach TWG think there?

The cursor returns only about 50 records. The record includes data fields about 20

Don't forget that if you store it as a collection of PL/SQL (there is no such thing as PL "+ table + '), this collection resides in expensive private process memory (PGA). Is there are 100 sessions by using this code, then it will have a 100 copies of this collection.

On the other hand, a TWG does not lie in the expensive private memory. And it adapts to a 1000 lines in the future, without affecting performance (do not forget that the TWG can be indexed - not collections). For a collection, you will need to pay an excessive price in memory to keep this 1000 lines in the PGA.

TWG is not a bad thing. The collections are not a bad thing. They are tools to solve specific problems. Your task is to select the right tool for the job. Cached data line SQL in a PL/SQL collection is almost never the right tool for the job, because it requires private process memory and uses a very simplistic data structure (does not support the index and so on).

Tags: Database

Similar Questions

  • Query on the PL/SQL Collections

    Hi all

    Please help me with the code below.

    I wrote this package, now I want to see the result by calling this package.

    Please take a look at the below scenario. It is just a POC that I tried on the EMPLOYEE table, once it is a success I will apply this original code.

    How to call this package and how to capture the values will be stored in the OUTPUT parameters, please help me with this.

    -Package Spec

    create or replace PACKAGE emp_dtls_pkg
    AS
    Dept_rec_type RECORD TYPE IS
    (DEPARTMENT_NAME HR.departments.DEPARTMENT_NAME%TYPE
    Location_id HR.departments.LOCATION_ID%TYPE);
    Emp_rec_type RECORD TYPE IS
    (Employe_id HR.employees.EMPLOYEE_ID%TYPE
    HR.employees.FIRST_NAME%TYPE name
    LAST_NAME HR.employees.LAST_NAME%TYPE
    E-MAIL HR.employees.EMAIL%TYPE
    PHONE_NUMBER HR.employees.PHONE_NUMBER%TYPE
    HR.employees.HIRE_DATE%TYPE HIRE_DATE
    HR.employees.JOB_ID%TYPE JOB_ID
    HR.employees.SALARY%TYPE SALARY
    HR.employees.COMMISSION_PCT%TYPE COMMISSION_PCT);

    TYPE emp_tbl_type IS TABLE OF THE emp_rec_type;

    PROCEDURE get_emp_dtls
    (p_dept_number number
    p_dept_rec ON emp_dtls_pkg.dept_rec_type
    p_emp_rec ON emp_dtls_pkg.emp_tbl_type
    );
    END emp_dtls_pkg;

    -Package body

    CREATE or REPLACE PACKAGE BODY emp_dtls_pkg AS
    PROCEDURE get_emp_dtls
    (p_dept_number number
    p_dept_rec ON emp_dtls_pkg.dept_rec_type
    p_emp_rec ON emp_dtls_pkg.emp_tbl_type
    )
    IS
    cursor emp_cur is
    Select EMPLOYEE_ID
    FIRST NAME
    LAST_NAME
    E-mail
    PHONE_NUMBER
    HIRE_DATE
    JOB_ID
    SALARY
    COMMISSION_PCT HR.employees
    where department_id = p_dept_number;

    l_emp_tbl emp_dtls_pkg.emp_tbl_type: = emp_dtls_pkg.emp_tbl_type ();
    l_dname HR.departments.DEPARTMENT_NAME%TYPE;
    l_loc HR.departments.LOCATION_ID%TYPE;

    BEGIN
    Select DEPARTMENT_NAME, location_id
    in l_dname, l_loc
    of HR.departments
    where department_id = p_dept_number;

    IF l_loc is not null THEN
    p_dept_rec. DEPARTMENT_NAME: = l_dname;
    p_dept_rec. location_id: = l_loc;

    FOR SheikYerbouti in emp_cur
    LOOP
    I'm in l_emp_tbl.first... l_emp_tbl. Last
    LOOP

    l_emp_tbl (l_emp_tbl. LAST YEAR). Employe_id: = SheikYerbouti. EMPLOYEE_ID;
    l_emp_tbl (l_emp_tbl. LAST YEAR). First name: = SheikYerbouti. FIRST_NAME;
    l_emp_tbl (l_emp_tbl. LAST YEAR). Name: = SheikYerbouti. LAST_NAME;
    l_emp_tbl (l_emp_tbl. LAST YEAR). E-MAIL: = SheikYerbouti. E-MAIL ADDRESS;
    l_emp_tbl (l_emp_tbl. LAST YEAR). PHONE_NUMBER: = SheikYerbouti. PHONE_NUMBER;
    l_emp_tbl (l_emp_tbl. LAST YEAR). HIRE_DATE: = SheikYerbouti. HIRE_DATE;
    l_emp_tbl (l_emp_tbl. LAST YEAR). Job_id: = SheikYerbouti. JOB_ID;
    l_emp_tbl (l_emp_tbl. LAST YEAR). SALARY: = SheikYerbouti. SALARY;
    l_emp_tbl (l_emp_tbl. LAST YEAR). COMMISSION_PCT: = emp_rec.COMMISSION_PCT;
    END LOOP;
    END LOOP;
    END IF;
    p_emp_rec: = l_emp_tbl;
    EXCEPTION
    WHILE OTHERS THEN
    DBMS_OUTPUT. PUT_LINE (' ERROR: ' |) SQLERRM);
    END get_emp_dtls;
    END emp_dtls_pkg;
    /

    Thanks and greetings
    Srinivas

    Hi Srinivas,

    I hope code below will be useful for you...

    -- Package Specification
    
    create or replace PACKAGE emp_dtls_pkg AS
      TYPE dept_rec_type IS RECORD(
        DEPARTMENT_NAME HR.departments.DEPARTMENT_NAME%TYPE,
        LOCATION_ID     HR.departments.LOCATION_ID%TYPE);
      TYPE emp_rec_type IS RECORD(
        EMPLOYEE_ID    HR.employees.EMPLOYEE_ID%TYPE,
        FIRST_NAME     HR.employees.FIRST_NAME%TYPE,
        LAST_NAME      HR.employees.LAST_NAME%TYPE,
        EMAIL          HR.employees.EMAIL%TYPE,
        PHONE_NUMBER   HR.employees.PHONE_NUMBER%TYPE,
        HIRE_DATE      HR.employees.HIRE_DATE%TYPE,
        JOB_ID         HR.employees.JOB_ID%TYPE,
        SALARY         HR.employees.SALARY%TYPE,
        COMMISSION_PCT HR.employees.COMMISSION_PCT%TYPE);
    
      TYPE emp_tbl_type IS TABLE OF emp_rec_type;
    
      PROCEDURE get_emp_dtls(p_dept_number IN number,
                             p_dept_rec    OUT emp_dtls_pkg.dept_rec_type,
                             p_emp_rec     OUT emp_dtls_pkg.emp_tbl_type);
    END emp_dtls_pkg;
    
    -- Package Body
    
    create or replace PACKAGE body emp_dtls_pkg IS
    
      PROCEDURE get_emp_dtls(p_dept_number IN number,
                             p_dept_rec    OUT emp_dtls_pkg.dept_rec_type,
                             p_emp_rec     OUT emp_dtls_pkg.emp_tbl_type) is
    
      begin
    
        SELECT DEPARTMENT_NAME, LOCATION_ID
          INTO p_dept_rec
          FROM departments d
         WHERE d.department_id = p_dept_number;
    
        SELECT EMPLOYEE_ID,
               FIRST_NAME,
               LAST_NAME,
               EMAIL,
               PHONE_NUMBER,
               HIRE_DATE,
               JOB_ID,
               SALARY,
               COMMISSION_PCT BULK COLLECT
          INTO p_emp_rec
          FROM employees e
         WHERE e.department_id = p_dept_number;
    
      end get_emp_dtls;
    
    end emp_dtls_pkg;
    
    -- Invokeing the Package
    
    DECLARE
    
      l_deptrec     emp_dtls_pkg.dept_rec_type;
      l_emptab      emp_dtls_pkg.emp_tbl_type;
      p_dept_number number(5) := 20;
    
    BEGIN
    
      emp_dtls_pkg.get_emp_dtls(p_dept_number, l_deptrec, l_emptab);
    
      dbms_output.put_line(l_deptrec.DEPARTMENT_NAME);
    
      for i in l_emptab.first .. l_emptab.last loop
        dbms_output.put_line(l_emptab(i).FIRST_NAME);
      end loop;
    
    END emp_dtls_pkg;
    
  • The exception of collection management in bulk

    Hello guys,.

    Please help me with a code to retrieve the data from the table with the wrong data type...

    I have a table with data

    Col1 (VARCHAR2 (10))

    --------------------

    1001

    1002

    1003

    1004

    1006

    1007

    A

    1009

    1010

    I need to write a PL/SQL code to bulk collect the data in the table above in a variable (number v_num) except that "a." Please let me know how to handle the exception invalid number in this case. I use oracle 10G

    But I need to know how to handle the exception in Collect(while collecting the data, there is an error) in bulk

    Hmm, good to know how it works, you can try to SAVE the exceptions (as below). But remember what said Paul Horth and keep in mind. That is why I didn't post earlier.

    -Create a table to store

    SQL > create table tab_num (col1 NUMBER);

    DECLARE

    type tt is the table of a % rowtype;

    v_num tt;

    v_errnum NUMBER;

    CURSOR c1

    IS

    SELECT col1 from a;

    BEGIN

    OPEN c1;

    LOOP

    FETCH c1 COLLECT LOOSE v_num LIMIT 1;  -The limit that you can modify according to the requirement

    -DBMS_OUTPUT. Put_line('v_num. COMTE-'|| v_num. COUNT);

    WHEN v_num EXIT. COUNT = 0;

    FORALL idx IN 1.v_num. COUNT SAVE EXCEPTIONS

    INSERT INTO tab_num VALUES v_num (idx);

    COMMIT;

    END LOOP;

    CLOSE c1;

    EXCEPTION

    WHILE OTHERS THEN

    DBMS_OUTPUT. Put_line ('Others - Err' |) SQLERRM);

    v_errnum: = SQL % BULK_EXCEPTIONS. COUNTY;

    BECAUSE me IN 1.v_errnum

    LOOP

    DBMS_OUTPUT. Put_line ('Err' |) SQL % BULK_EXCEPTIONS (i) .error_index | "Message - ' | SQLERRM (0 - SQL %BULK_EXCEPTIONS(i).error_code));)

    END LOOP;

    END;

  • Dynamic SQL with in bulk in the record type

    Oracle 10.2 g

    I received this Tom

    [http://asktom.oracle.com/pls/apex/f?p=100:11:0:NO:]

    I'm able to do this without dynamic SQL, but my requirement is to do it in dynamic SQL
     create table t1 ( x int, y int );
    
     insert into t1 select rownum, rownum+1 from all_users where rownum <= 5;
    
     create table t2 ( x int, y int, z int );
    
     declare
                type array is table of t1%rowtype;
                l_data array;
        begin
                select * bulk collect into l_data from t1;
      
                forall i in 1 .. l_data.count
                
                       execute immediate 'insert into (select x, y from t2) values :x' using l_data(i);
        end;
     
    Error at line 1
    ORA-06550: line 9, column 90:
    PLS-00457: expressions have to be of SQL types
    ORA-06550: line 9, column 20:
    PL/SQL: Statement ignored
    There is a work around in 11g, but can we do something in 10g?



    Thank you
    HESH.

    HESH wrote:

    but following does not.

    declare
    type array is table of t1%rowtype;
    l_data array;
    begin
    select * bulk collect into l_data from t1;
    
    forall i in 1 .. l_data.count
    
    execute immediate 'insert into (select x, y from t2) values :x' using l_data(i);
    end;
    

    I want just a dynamic SQL code for the insert with FORALL statement would adopt as well as collections.

    Doesn't make much sense.

    Extract you the data from the SQL engine in the table of the record type. If the output data that cursor SQL must be read in the SQL engine and copied into the memory of PL/SQL engine.

    Then, you send that VERY SAME DATA back to the SQL engine to be used by a SQL insert cursor.

    Where is the logic behind the extraction of data from SQL in a PL/SQL table structure and then push this same structure table on the SQL engine database? What is the purpose to send data on a detour of underperforming and non-scalale through the PL/SQL engine?

    You have any justification (technical or functional wise) to back up this absurd approach?

    Why this can be achieved using a single SQL cursor that does both the choice (extraction) and (in bulk) insertion - using the plain old INSERT... SELECT structure?

    And if the insert is variable, then what? Create a dynamic INSERT... SELECT cursor and execute it (using bind values). This simple... Right?

  • Insert rows in the PL/SQl table

    Hello
    I have a PL/SQl table that I filled through bulk collect and now I'm trying to loop through the table (actually quite a few nested loops)... Now in one of my curls, I might need to insert a new row by splitting the field in the existing row in the table. Can I insert the line in the pl/sql table in the loop without affecting the "FOR i IN tab.first... Tab.Last' loop?
    Also, what would be the index of such a line inserted into the table. Can I access it with tab.last + 1 (doesn't look like it can be done if I insert into various levels of loops).
    OR
    If I insert the lines insde loops nested, then I can access the new lines as soon as I close all the loops and open a new loop? The new lines will be at the last table.

    Any help will be appreciated...

    The expression v_arr. LAST gives the index of the last entry, so you can refer to this element as

    v_arr(v_arr.LAST)
    

    Then the attributes of this element will be

    v_arr(v_arr.LAST).attr
    

    for example

    DECLARE
        TYPE table_defs_tt IS TABLE OF user_tables%ROWTYPE INDEX BY PLS_INTEGER;
        v_mytables table_defs_tt;
    BEGIN
        SELECT * BULK COLLECT INTO v_mytables
        FROM   user_tables
        WHERE  ROWNUM <= 100;
    
        DBMS_OUTPUT.PUT_LINE(v_mytables(v_mytables.LAST).table_name);
    END;
    
  • generate the math table in a SQL

    How can I get math tables in a SQL query.

    for taking the table of 2 to 5, you can use

    Select 2 * rownum "table 2", 3 * rownum "table 3", 4 * rownum 'table 4', 5 * rownum 'table 5' from dual connect by rownum<>

  • Cannot see the table in the p/sql procedure but can in normal sql

    Hello

    using 11.2.0.3

    that sql format

    Select schema_owner. < table > - it works in good sql and pl/sql get message table or view does not exist.

    Other fine tables.

    Y at - it a permission to have reference to the table in the pl/sql procedure rather than sql?

    Thank you

    Hello

    I'm glad you solved the problem!

    Don't forget to mark it as "answered".  It will help others with a similar problem, and it will save time for people answering questions on this forum.

  • Question: insertion of several lines in the MS Sql Server table using the DB adapter

    Hi all

    I managed to insert a single row in a table of MS SQL Server via the adapter DB to my process BPEL, but when I tried to insert in mutiple lines in the same table of MS SQL server, I encounter the error below.

    I use a DB SQL XA connection to connect to the server.

    Kindly help me to solve the problem. Thanks in advance.

    Error:

    " < bpelFault > < faultType > 0 < / faultType > < remoteFault xmlns =" http://schemas.Oracle.com/BPEL/extension "> < a name ="summary"part > < summary > exemption is is produced when the binding was used." Exception occurred during invocation of the JCA binding: "JCA binding run 'merge' reference operations have to: DBWriteInteractionSpec Execute Failed Exception." the merger failed. The descriptor name: [LoadCmpAggSpendStage.SapTable]. Caused by com.microsoft.sqlserver.jdbc.SQLServerException: incorrect syntax near ')'... Check the logs for the record output full DBAdapter before this exception. This exception is considered as reproducible, probably due to a communication failure. To be classified as not reproducible rather add property nonRetriableErrorCodes with the '102' value in the deployment descriptor (i.e. weblogic - RA.Xml). Auto retry a reproducible fault set composite.xml for this invoke these properties: jca.retry.interval, jca.retry.count and jca.retry.backoff. All properties are integers. ". The called JCA adapter threw an exception of resource. Please examine the error message above carefully to determine a resolution. < /Summary. (> < / piece > < part name = "detail" > < detail syntax > incorrect near ')'. < / details > < / piece > < part name = "code" > < code > 102 < / code > < / piece > < / remoteFault > < / bpelFault >

    Kind regards

    Balaji Rahmani

    It seems that in this case is called merge operation. If existing records (check primary key) are not there then it will be inserted on the other update. Check the syntax of the query that is created. It looks like she may have a supplement "). If you want to only insert then call insert operation and not merge.

  • Need to know the current table whose stats are collected

    All,
    I ran DBMS_STATS.gather_schema_stats on my DB for a schema with a degree = > 32. I want to know for which table the package is currently gathering statistics.
    I tried to see the columns num_rows & last_analyzed from user_tables & user_tab_partitions for this information, but without success.

    Regds,
    Malika

    In session of v$ get hash_value then ask in V$ sql with this hash_value in sql_hash_value...

    Select sql_text from v$session, V$sql where hash_value = sql_hash_value and sid = 
    
  • Load the data from a text file into a table using pl/sql

    Hi Experts,

    I want to load the data from a text file (sample1.txt) to a table using pl/sql

    I used the pl/sql code below

    ***********************************
    declare
    f utl_file.file_type;
    s varchar2 (200);
    c number: = 0;
    Start
    f: = utl_file.fopen('TRY','sample1.txt','R');
    loop
    UTL_FILE.get_line (f, s);
    insert into sampletable (a, b, c) values (s, s, s);
    c: = c + 1;
    end loop;
    exception
    When NO_DATA_FOUND then
    UTL_FILE.fclose (f);
    dbms_output.put_line('No. deles de lignes insérées: ' || c);
    end;

    ***************************************

    and my sample1.txt file looks like

    ***************************************
    1
    2
    3
    ***************************************

    Gets the data inserted, with way below

    Select * from sampletable;

    A, B AND C

    1-1-1
    2-2-2
    3 3 3

    I want that data to get inserted as

    A, B AND C

    1 2 3

    The text file I have is to have three lines, and the first value of each line should go to each column

    Help, please...

    Thank you
    declare
    f utl_file.file_type;
    s1 varchar2(200);
    s2 varchar2(200);
    s3 varchar2(200);
    c number := 0;
    begin
    f := utl_file.fopen('TRY','sample1.txt','R');
    utl_file.get_line(f,s1);
    utl_file.get_line(f,s2);
    utl_file.get_line(f,s3);
    insert into sampletable (a,b,c) values (s1,s2,s3);
    c := c + 1;
    utl_file.fclose(f);
    exception
    when NO_DATA_FOUND then
    if utl_file.is_open(f) then utl_file.fclose(f); ens if;
    dbms_output.put_line('No. of rows inserted : ' || c);
    end;
    

    SY.

  • How to remove duplicates from the PL - SQL table?

    Hi gurus,

    I have a PL - SQL table with the following structure
    Authors (SR_NO, Auth_Code, Change_Date, cost)

    This table is filled using a slider. However, this table can have a few lines in double (for column (Auth_Code)
    for example
    SR_NO      Auth_Code       Change_Date                       Cost
    1               A1             14-FEB-09 08.18.47 AM          11.00
    2               A2             14-FEB-09 08.18.56 AM       2839.00
    3               A1             15-FEB-09 08.00.02 AM      1299.00
    4               A1             15-FEB-09 07.00.00 AM        789.00
    5               A3             14-FEB-09 08.18.56 AM        312.00
    6               A4             14-FEB-09 08.19.02 AM        233.00
    I need to get the above result set select the separate lines of Auth_Code including the Change_Date is maximum (and store in another PL - SQL table for treatment later or even the removal of this table will be also!)

    of the data A1 is duplicated and a maximum Change_Date above = 15 February 09 08.00.02 AM.
    Where my PL - SQL Table that results must have given below
    SR_NO      Auth_Code       Change_Date                       Cost
    2               A2             14-FEB-09 08.18.56 AM       2839.00
    3               A1             15-FEB-09 08.00.02 AM      1299.00
    5               A3             14-FEB-09 08.18.56 AM        312.00
    6               A4             14-FEB-09 08.19.02 AM        233.00
    I'm not very aware of the PL - SQL tables and there is no chance to change the existing cursor that fills the data in this table PL - SQL.
    I guess that I need to compare each record of PL - SQL table with others, but do not know how to do this.

    Could you please help?

    Hello

    Like this?:

    Connected to Oracle Database 10g Express Edition Release 10.2.0.1.0
    Connected as hr
    
    SQL>
    SQL> with data as(
      2  select 1 as SR_NO, 'A1' as Auth_Code, to_date('14-FEB-09 08.18.47', 'dd-mon-yy hh24:mi:ss') as change_date,    11.00 as cost from dual union all
      3  select 2 as SR_NO, 'A2' as Auth_Code, to_date('14-FEB-09 08.18.56', 'dd-mon-yy hh24:mi:ss') as change_date,  2839.00 as cost from dual union all
      4  select 3 as SR_NO, 'A1' as Auth_Code, to_date('15-FEB-09 08.00.02', 'dd-mon-yy hh24:mi:ss') as change_date,  1299.00 as cost from dual union all
      5  select 4 as SR_NO, 'A1' as Auth_Code, to_date('15-FEB-09 07.00.00', 'dd-mon-yy hh24:mi:ss') as change_date,   789.00 as cost from dual union all
      6  select 5 as SR_NO, 'A3' as Auth_Code, to_date('14-FEB-09 08.18.56', 'dd-mon-yy hh24:mi:ss') as change_date,   312.00 as cost from dual union all
      7  select 6 as SR_NO, 'A4' as Auth_Code, to_date('14-FEB-09 08.19.02', 'dd-mon-yy hh24:mi:ss') as change_date,   233.00 as cost from dual)
      8  select * from data d where change_date = (select max(change_date) from data d2 where d.auth_code = d2.auth_code);
    
         SR_NO AUTH_CODE CHANGE_DATE       COST
    ---------- --------- ----------- ----------
             2 A2        14/02/2009        2839
             3 A1        15/02/2009        1299
             5 A3        14/02/2009         312
             6 A4        14/02/2009         233
    
    SQL>
    

    Kind regards

  • Use of PL/SQL collections

    Hi gurus,

    I have a new collection and just wanted to know about little things.

    I would like to declare the associative array for emp % rowtype and I want to load the entire table in the pl/sql table, and then I want to display on the screen.

    I wrote the following code but impossible to load the entire table and display it.

    Could you please guide me in the loading and display of the entire record of the table emp also please share some links that will give me examples of collections on the emp table.

    Literature Informatics very difficult to understand concepts.

    declare
    type emplist is table of emp%rowtype index by binary_integer;
    etab emplist;
    
    
    
    
    begin
    if etab is null then
    dbms_output.put_line('etab empty');
    else
    dbms_output.put_line('etab not empty');
    end if;
    dbms_output.put_line(etab.count);
    --null;
    
    
    
    
    end;
    

    Thank you...

    Oracle offers 3 types of PL/SQL collection type.

    1. associative array

    2. nested table

    3. Varray

    You must first determine what type of suites collection your goal. To show how what you try, I used the nested Table collection type.

    SQL > select * from version $ v where rownum = 1;

    BANNER
    ----------------------------------------------------------------
    Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi

    SQL > declare
    2 tbl type is table of the emp % rowtype;
    tbl 3 v;
    4 start
    5 Select * bulk collect into emp v.;
    6
    7 because I loop 1.v.count
    8 dbms_output.put_line (v (i) .empno |) '/' || v (i) .ename);
    9 end of the loop;
    10 end;
    11.
    7369/SMITH
    7499/ALLEN
    7521/WARD
    7566/JONES
    7654/MARTIN
    7698/BLAKE
    7782/CLARK
    7788/SCOTT
    7839/KING
    7844/TURNER
    7876/ADAMS

    PL/SQL procedure successfully completed.

    A common myth about the treatment in bulk, it's that it improves performance. Grouping of PL/SQL variable uses an area of PGA memory. PGA is a private memory area. For example, if a process requires 1 MB of storage for a variable grouping in PGA and 25 users ask the same process, then 25 MB is allocated in PGA for this collection. It's a very expensive.

    It must be so always remember, the best and the only way to process the data in Oracle using SQL. PL/SQL is not a recommended tool to process the data. Therefore, always try to make the processing of your data by using simple SQL. Never treat the data in a loop using the explicit cursor or collection of PL/SQL.

  • run immediately with bind sql collection

    Hi, I'm working on an implementation immediate execution where to use a binding that is to an SQL array type. The type of table is produced by be transmitted from an array of Java.

    So it looks like:

    execute immediate mystatement using myarray;

    "mystatement" contains a forall command. I thought that it wouldn't work, because of limitations in the use of tables to link with dynamic sql, but it does. Also, I see in the Oracle documentation that allows dynamic sql to binds to SQL collection types. Am I so I read the documentation correctly, please, that this is a correct use of the immediate execution with a SQL collection?

    I tested on 10.2 and 11 g

    Thank you

    David

    979394 wrote:
    Hi, I'm working on an implementation immediate execution where to use a binding that is to an SQL array type. The type of table is produced by be transmitted from an array of Java.

    So it looks like:

    execute immediate mystatement using myarray;

    "mystatement" contains a forall command. I thought that it wouldn't work, because of limitations in the use of tables to link with dynamic sql, but it does. Also, I see in the Oracle documentation that allows dynamic sql to binds to SQL collection types. Am I so I read the documentation correctly, please, that this is a correct use of the immediate execution with a SQL collection?

    I tested on 10.2 and 11 g

    Thank you

    David

    Welcome to the Forum!
    Here is a small demonstration to what Solomon said: (not the best of examples I would say, but should provide an indication)

    drop table depts;
    drop table emps;
    drop type type_depts;
    
    create table depts (dept_no   number, dept_name varchar2(25), loc varchar2(10));
    
    create table emps (empno  number, name varchar2(25), dept_no  number, salary number);
    
    create or replace type type_depts is table of number;
    
    insert into depts values (10, 'ABC', '111');
    insert into depts values (20, 'ABC1', '111');
    insert into depts values (30, 'ABC2', '111');
    insert into depts values (40, 'ABC3', '111');
    insert into depts values (50, 'ABC4', '111');
    
    insert into emps values (1, 'PQR', 10, 100);
    insert into emps values (2, 'PQR1', 20, 100);
    insert into emps values (3, 'PQR2', 30, 100);
    insert into emps values (4, 'PQR3', 10, 100);
    insert into emps values (5, 'PQR4', 30, 100);
    insert into emps values (6, 'PQR5', 10, 100);
    insert into emps values (7, 'PQR6', 40, 100);
    insert into emps values (8, 'PQR7', 80, 100);
    
    commit;
    
    /* Block to find a DEPT_NO in EMP that does not exist in DEPT table */
    set serveroutput on;
    declare
      dept    type_depts;
    
      type type_emp is table of pls_integer index by pls_integer;
      emp     type_emp;
    
      idx     pls_integer;
    begin
      select dept_no
        bulk collect into dept
        from depts;
    
      execute immediate 'select empno from emps where dept_no not in (select column_value from table(:1))' bulk collect into emp using dept;
    
      for i in emp.first..emp.last loop
        dbms_output.put_line('Emp No:- ' || emp(i));
      end loop;
    end;
    
    anonymous block completed
    Emp No:- 8
    

    As you say, the 'mystatement"contains the FORALL statement; Is the name of the Table known at runtime, or it is passed as an additional parameter? If the Table name is known, then, IMO, there is no any dynamic SQL. A FORALL statement should be enough.

    Please provide details. In addition, please read {message identifier: = 9360002}.

  • PL/SQL, Collection and email 'question '.

    Hi all
    I'm spending external monitoring scripts to internal procedures or packages.
    In this specific case, I create a procedure (it can be a lot, but I started to test it as a procedure) that checks free space on storage space (the percentage estimate).
    Everything works fine but...
    I want to send the result set to my email account (in the body of the message, not as an attachment.). So, first, I used the following code:
    create or replace
    PROCEDURE TBSALERT AS
    tbs VARCHAR(100);
    per NUMBER;
    conn utl_smtp.connection;
    v_From VARCHAR2(80) := '[email protected]';
    v_Recipient VARCHAR2(80) := '[email protected]';
    v_Subject VARCHAR2(80) := 'TBS Status';
    v_Mail_Host VARCHAR2(30) := 'smtp.domain.com.com';
    CURSOR tbs_alertc IS
    SELECT A.tablespace_name "Tablespace", trunc(b.free/A.total*100) "Free %" FROM (SELECT tablespace_name,sum(bytes)/1024/1024 total FROM sys.dba_data_files where tablespace_name not like 'UNDO%' GROUP BY tablespace_name) A,(SELECT tablespace_name,sum(bytes)/1024/1024 free FROM sys.dba_free_space where tablespace_name not like 'UNDO%' GROUP BY tablespace_name) B WHERE A.tablespace_name=b.tablespace_name;
    BEGIN
    OPEN tbs_alertc;
    LOOP
    FETCH tbs_alertc INTO tbs,per;
    EXIT WHEN tbs_alertc%NOTFOUND;
    conn := UTL_SMTP.OPEN_CONNECTION(v_Mail_Host);
    UTL_SMTP.HELO(conn, v_Mail_Host);
    UTL_SMTP.MAIL(conn, v_From);
    UTL_SMTP.RCPT(conn, v_Recipient);
    UTL_SMTP.OPEN_DATA(conn);
    UTL_SMTP.WRITE_DATA(conn, UTL_TCP.CRLF ||'Alerta TBS: '||tbs|| ' Free%: '||per);
    DBMS_OUTPUT.PUT_LINE('Alerta TBS :'||tbs||' Percent :'||per);
    UTL_SMTP.CLOSE_DATA(conn);
    UTL_SMTP.QUIT(conn);
    END LOOP;
    CLOSE tbs_alertc;
    END;
    /
    The problem with that I get an email for each tablespace from the list (if I don't make a mistake, this behavior is because I make a loop of sending an email for each row in the cursor).
    So, I think that "I must use a PL/SQL collection", but, unfortunately, I am not able to solve my 'problem '.
    This is the code with I was playing around:
    create or replace
    PROCEDURE TBSALERTNEW AS
       TYPE tbslst IS TABLE OF SPACESTATUS_VW.TABLESPACE%TYPE;
       TYPE perlst IS TABLE OF SPACESTATUS_VW.Free%TYPE;
       CURSOR c1 IS SELECT TABLESPACE, FREE from SPACESTATUS_VW;
       tbs tbslst;
       per  perlst;
       TYPE spacestlst IS TABLE OF c1%ROWTYPE;
       spacest spacestlst;
    conn utl_smtp.connection;
    v_From VARCHAR2(80) := '[email protected]';
    v_Recipient VARCHAR2(80) := '[email protected]';
    v_Subject VARCHAR2(80) := 'TBS Status';
    v_Mail_Host VARCHAR2(30) := 'smtp.domain.com';
    PROCEDURE print_results IS
       BEGIN
    --      dbms_output.put_line('Results:');
          IF tbs IS NULL OR tbs.COUNT = 0 THEN
             RETURN; -- Don't print anything if collections are empty.
          END IF;
          FOR i IN tbs.FIRST .. tbs.LAST
          LOOP
             dbms_output.put_line(' i Tablespace: ' || tbs(i) || ' Free %:' ||
                per(i));
          END LOOP;
       END;
    BEGIN
       dbms_output.put_line('--- Processing all results at once ---');
       OPEN c1;
       FETCH c1 BULK COLLECT INTO tbs, per;
       CLOSE c1;
       print_results;
    
       dbms_output.put_line('--- Fetching records rather than columns ---');
       OPEN c1;
       FETCH c1 BULK COLLECT INTO spacest;
       FOR i IN spacest.FIRST .. spacest.LAST
       LOOP
    -- Now all the columns from the result set come from a single record.
          dbms_output.put_line(' h Tablespace ' || spacest(i).TABLESPACE || ' Free %: '
             || spacest(i).Free);
       END LOOP;
    END;
    Somethings to notice:
    a. This code is not exactly mine, she is part of an Oracle example (I thought it should be easier to play with something that worked).
    b. I created a display from the query in the first procedure, in order to facilitate the work on the second procedure.
    c. when debug you the code, it works fine.
    d I don't know where (or how) to use the UTL_SMTP part to send the complete set of results in the body of the email.
    e. I am company running Oracle 10.2.0.4 on Linux x86_64

    Any help will be appreciated.

    Thanks in advance.

    >
    So I think that "I have to use a collection of PL/SQL.
    >
    Why? Simply create a long string with a line for each table space. Add a newline at the end of each line.
    What makes a string body.

    Create VARCHAR2 (32000);

    The loop allows you to add a line for each table space.

    Easy to use a PL/SQL table.

  • Select the data from collections plsql

    Hi all

    I'm not a developer but working as a DBA, so not very familiar with pl/sql, always crossed with documentation and could lead to a solution of my problem. I need advice from expert here.

    Problem: I am writing in a kind of special program plsql for surveillance of certain lots, I know that we have much option to do the same db/grid control including... etc but for some
    the reason I have to do this, use only plsql.

    Requirement: my requirement is to select data in the plsql table and then have the opportunity to ask questions again and again. I prefer not to go to table, rather than directly from plsql...

    I wrote below the code for the sample, bulk data in collection type collection and can print using the loop.

    Declare
    TS type is table v$ session % rowtype index by pls_integer;
    tsess ts.
    Start
    Select * bulk collect into tsess from v$ session;
    I'm looping 1.tsess.count
    dbms_output.put_line (tsess (i) .terminal);
    end loop;
    end;
    /

    But is it possible same collection (tsess in the example above) can be queried using a select as ' select * from table (Tsess) "I searched the net and found this can be done using create type at the database level.» But my problem is that I can't create any object in the database as being it's a production one.

    I was looking as if is it possible even can be accomplished... as cast / multiset... However, I could not get it through.

    your help would be appreciated!

    Kind regards

    I don't think you should use the tables here, only SQL, take a look at the factors of subquery and will indicate if it is not enough...

    Published by: BrendanP on February 12, 2012 03:07 for an example:

    I understand you want to "Refresh" of data that you already have the database purely to be able to use the SQL such as ORDER BY in multiple ways. Here's how you can do it in the original SQL for a particular example, where you query v$ sql time control processor and disk reads separately (I tested it but the result won't be good look here, so omitting it):

    WITH v AS (
    SELECT
        Substr (sql_text,1,500)             sql_text,
        cpu_time/1000000                    cpu_seconds,
        disk_reads,
        buffer_gets,
        executions,
        CASE WHEN rows_processed != 0 THEN Round( buffer_gets / Nvl (Replace (rows_processed, 0, 1) ,1)) END Buffer_gets_rows_proc,
        Round (buffer_gets / Nvl (Replace (executions, 0, 1), 1)) Buffer_gets_executions,
        elapsed_time / 1000000              elapsed_second,
        module
    FROM v$sql s)
    SELECT
        'CPU'                order_by,
        cpu_seconds          order_val,
        sql_text,
        cpu_seconds,
        disk_reads,
        buffer_gets,
        executions,
        buffer_gets_rows_proc,
        buffer_gets_executions,
        elapsed_second,
        module
    FROM v
     UNION
    SELECT
        'Disk reads',
        disk_reads,
        sql_text,
        cpu_seconds,
        disk_reads,
        buffer_gets,
        executions,
        buffer_gets_rows_proc,
        buffer_gets_executions,
        elapsed_second,
        module
    FROM v
    ORDER BY order_by, order_val DESC
    

Maybe you are looking for