Dynamic SQL in the discharge line to cursor line

Hello

Anoyne can help me?

I want to create a function that returns an object in the pipeline.

I have create a type of oracle and a collection, lets say:

CREATE or REPLACE type line_man as an object (LTC varchar2 (2),)
number of num,
user_t varchar2 (10));

CREATE or REPLACE type table_man as the line_man table;

After that, I created a function that returns a pipeline:


create or replace function man_tst (p_1 in number,
P_2 number,
P_3 number) table_man return pipeline is
vStm varchar2 (4000);
v_cur sys_refcursor;
line_man s_cur;
Start
vStm: = ' select LTC, num, user_t from table_1 where 1 = 1';
-a code that might change the place where clause
...
Open the v_cur for vstm;
loop
extract the v_cur in s_cur;
When the output v_cur % notfound;
line (table_man (s_cur));
end loop;
end man_tst;


But when I try to compile, it gives me an error:
[Error] PLS-00382 (167:15): PLS-00382: expression is of the wrong type

What I am doing wrong? That's how I suppose maybe pass the values of the line?

Thank you

Here is an example of work - using treatment in bulk to minimize the change between SQL and PL/SQL context engines:

SQL> create or replace type TLineMan as object(
  2          sld     varchar2(2),
  3          num     number,
  4          user_t  varchar2(10)
  5  );
  6  /

Type created.

SQL>
SQL>
SQL> create or replace type TLineManTable as table of TLineMan;
  2  /

Type created.

SQL>
SQL> create or replace function ManTest( rowCount number )  return TLineManTable pipelined is
  2          buf     TLineManTable;
  3          c       sys_refcursor;
  4  begin
  5          open c for
  6                  'select
  7                          TLineMan( rownum, object_id, substr(object_name,1,10) )
  8                  from    user_objects
  9                  where   rownum <= :0'
 10          using IN rowcount;
 11
 12          loop
 13                  fetch c bulk collect into buf limit 100;
 14
 15                  for i in 1..buf.Count loop
 16                          pipe row( buf(i) );
 17                  end loop;
 18
 19                  exit when c%NotFound;
 20          end loop;
 21
 22          close c;
 23
 24          return;
 25  end;
 26  /

Function created.

SQL> show errors
No errors.
SQL>
SQL> select * from TABLE( ManTest(2) );

SL        NUM USER_T
-- ---------- ----------
1      284971 ADDFORMULA
2      282910 ASSERT

SQL> 

However-, I wouldn't really code of any pipeline in this way. It makes no sense to slap a pipeline on top a cursor like the fact this example.

The pipes are ideal for transforming data - for example, transform a web URL that returns a CSV text in a table. Pushing data Oracle SQL in a PL/SQL pipeline and then pushing that same data back to the ranks... as channeled SQL engine parts of additional mobile this performance impact without real justification and benefits...

Tags: Database

Similar Questions

  • Tables created in a stored procedure cannot be used with dynamic SQL? The impact?

    There is a thread on the forum which explains how to create tables within a stored procedure (How to create a table in a stored procedure , however, it does create a table as such, but not how to use it (insert, select, update, etc.) the table in the stored procedure.) Looking around and in the light of the tests, it seems that you need to use dynamic SQL statements to execute ddl in a stored procedure in Oracle DB. In addition, it also seems that you cannot use dynamic SQL statements for reuse (insert, select, update, etc.) the table that was created in the stored procedure? Is this really the case?

    If this is the case, I am afraid that if tables cannot be 'created and used"in a stored procedure using the dynamic SQL, as is the case with most of the servers of DB dynamic SQL is not a part of the implementation plan and, therefore, is quite expensive (slow). This is the case with Oracle, and if yes what is the performance impact? (Apparently, with Informix, yield loss is about 3 - 4 times, MS SQL - 4 - 5 times and so on).

    In summary, tables created within a stored procedure cannot be 'used' with dynamic SQL, and if so, what is the impact of performance as such?

    Thank you and best regards,
    Amedeo.

    Published by: AGF on March 17, 2009 10:51

    AGF says:
    Hi, Frank.

    Thank you for your response. I understand that the dynamic SQL is required in this context.

    Unfortunately, I am yet to discover "that seeks to" using temporary tables inside stored procedures. I'm helping a migration from MySQL to Oracle DB, and this was one of the dilemmas encountered. I'll post what is the attempt, when more.

    In Oracle, we use [global temporary Tables | http://www.psoug.org/reference/OLD/gtt.html?PHPSESSID=67b3adaeaf970906c5e037b23ed380c2] aka TWG these tables need only be created once everything like a normal table, but they act differently when they are used. The data inserted in TWG will be visible at the session that inserted data, allowing you to use the table for their own temporary needs while not collide with them of all sessions. The data of the TWG will be automatically deleted (if not deleted programmatically) when a) a commit is issued or b) the session ends according to the parameter that is used during the creation of the TWG. There is no real need in Oracle to create tables dynamically in code.

    I noticed that many people say that the "Creation of the tables within a stored procedure" is not a good idea, but nobody seems necessarily explain why? Think you could elaborate a little bit? Would be appreciated.

    The main reason is that when you come to compile PL/SQL code on the database, all explicit references to tables in the code must correspond to an existing table, otherwise a djab error will occur. This is necessary so that Oracle can validate the columns that are referenced, the data types of those columns etc.. These compilation controls are an important element to ensure that the compiled code is as error free as possible (there is no accounting for the logic of programmers though ;)).

    If you start to create tables dynamically in your PL/SQL code, so any time you want to reference this table you must ensure that you write your SQL queries dynamically too. Once you start doing this, then Oracle will not be able to validate your SQL syntax, check the types of data or SQL logic. This makes your code more difficult to write and harder to debug, because inevitably it contains errors. It also means that for example if you want to write a simple query to get that one out in a variable value (which would take a single line of SQL with static tables), you end up writing a dynamic slider all for her. Very heavy and very messy. You also get the situation in which, if you create tables dynamically in the code, you are also likely to drop tables dynamically in code. If it is a fixed table name, then in an environment multi-user, you get in a mess well when different user sessions are trying to determine if the table exists already or is the last one to use so they can drop etc. What headache! If you create tables with table names, then variable Dynamics not only make you a lot end up creating (and falling) of objects on the database, which can cause an overload on the update of the data dictionary, but how can ensure you that you clean the tables, if your code has an exception any. Indeed, you'll find yourself with redundant tables lying around on your database, may contain sensitive data that should be removed.

    With the TWG, you have none of these issues.

    Also, what is the impact on the performance of the dynamic SQL statements in Oracle? I read some contrasting opinions, some indicating that it is not a lot of difference between static SQL and SQL dynamic in more recent versions of Oracle DB (Re: why dynamic sql is slower than static sql is this true?)

    When the query runs on the database, there will be no difference in performance because it is just a request for enforcement in the SQL engine. Performance problems may occur if your dynamic query is not binding variable in the query correctly (because this would cause difficult analysis of the query rather than sweet), and also the extra time, to dynamically write the query running.

    Another risk of dynamic query is SQL injection which may result in a security risk on the database.

    Good programming will have little need for the tables of dynamically created dynamically or SQL.

  • A loop dynamic sql in the procedure

    Hi guys,.

    I'm having a procedure that will have two input start_date and end_date parameters

    I need a loop in alter procedure statement something like this using dynamic sql


    CHANGE TABLE M1

    SWAP PARTITION FOR (TO_DATE('01-JAN-2015','dd-MON-yyyy'))

    WITH TABLE T2

    INCLUDING THE INDEX;

    CHANGE TABLE M1

    BY EXCHANGE COMPETITION FOR (TO_DATE('02-JAN-2015','dd-MON-yyyy'))

    WITH TABLE T3

    INCLUDING THE INDEX;

    .

    .

    .


    For example I have dates in setting something like January 1, 2015-4 January 2015

    I need something like this, where T is a constant variable, I need to add T1, T2. T3 according to the dates of the range.

    Hello

    your procedure can not simply be rolled up, but the call session can be rolled up the output to a file.

    Try something like this

    col act_date noprint new_value act_date
    
    SET TERMOUT  OFF
    
    select to_char(sysdate, 'yyyy_mm_dd_hh24miss') act_date
      from dual;
    
    SET TERMOUT      ON
    set serveroutput on
    set feedback     off
    set linesize     3000
    
    col statement for a200 heading "-- alter statements"
    
    spool d:\temp\&act_date._&_CONNECT_IDENTIFIER._alter_partition.sql
    
    -- exec your_procedure
    
    -- or simple plain sql
    
    with data (start_date, end_date) as (
      select to_date('01/01/2016', 'dd/mm/yyyy'),
            to_date('05/01/2016', 'dd/mm/yyyy')
        from dual
        )
    select --level, to_char(start_date + (level - 1), 'dd-MON-yyyy' ) cur_date
                     'ALTER TABLE M1 EXCHANGE PARTITION FOR (TO_DATE(''' || to_char(start_date + (level - 1), 'dd-MON-yyyy' ) || ''',''dd-MON-yyyy'')) WITH TABLE T2 INCLUDING INDEXES;'
      || chr(10) ||  'ALTER TABLE M1 EXCHANGE PARTITION FOR (TO_DATE(''' || to_char(start_date + (level - 1), 'dd-MON-yyyy' ) || ''',''dd-MON-yyyy'')) WITH TABLE T3 INCLUDING INDEXES;'  as statement
      from data
    connect by level <= end_date - start_date + 1;
    
    spool off
    
    set feedback    on
    
    prompt @d:\temp\mk_alter.sql
    

    concerning
    Kay

  • How to use Bulk collect in dynamic SQL with the example below:

    My Question is

    Using of dynamic SQL with collection in bulkif we pass the name of the table as "to the parameter' function, I want to display those

    An array of column names without vowels (replace the vowels by spaces or remove vowels and display).

    Please explain for example.

    Thank you!!

    It's just a predefined type

    SQL> desc sys.OdciVarchar2List
     sys.OdciVarchar2List VARRAY(32767) OF VARCHAR2(4000)
    

    You can just as easily declare your own collection type (and you are probably better served declaring your own type of readability if nothing else)

    SQL> ed
    Wrote file afiedt.buf
    
      1  CREATE OR REPLACE
      2     PROCEDURE TBL_COLS_NO_VOWELS(
      3                                  p_owner VARCHAR2,
      4                                  p_tbl   VARCHAR2
      5                                 )
      6  IS
      7     TYPE vc2_tbl IS TABLE OF varchar2(4000);
      8     v_col_list vc2_tbl ;
      9  BEGIN
     10      EXECUTE IMMEDIATE 'SELECT COLUMN_NAME FROM DBA_TAB_COLUMNS WHERE OWNER = :1 AND TABLE_NAME = :2 ORDER BY COLUMN_ID'
     11         BULK COLLECT
     12         INTO v_col_list
     13        USING p_owner,
     14              p_tbl;
     15      FOR v_i IN 1..v_col_list.COUNT LOOP
     16        DBMS_OUTPUT.PUT_LINE(TRANSLATE(v_col_list(v_i),'1AEIOU','1'));
     17      END LOOP;
     18*  END;
    SQL> /
    
    Procedure created.
    
    SQL> exec tbl_cols_no_vowels( 'SCOTT', 'EMP' );
    MPN
    NM
    JB
    MGR
    HRDT
    SL
    CMM
    DPTN
    
    PL/SQL procedure successfully completed.
    

    Justin

  • Oracle dynamic SQL with the UNION operator

    Hello

    I have sql string contains two queries separated by the UNION operator. When I run by using DBMS_SQL, it becomes only the first SQL before the UNION operator.

    Can anyone correct how can I Sue UNION in DBMS_SQL?

    Thank you

    Sorry,

    I tested my code

                        BEGIN
                          FOR I IN (SELECT 1 A FROM DUAL UNION
                                  SELECT 2 A  FROM DUAL UNION
                                  SELECT 3 A  FROM DUAL) LOOP
                          DBMS_OUTPUT.PUT_LINE(I.A);
                         END LOOP;
                        END;
                        
    

    and copy this code and PASE to DBMS_SQL. PARSE (all other cases, "... and insert the INSERT STATEMENT but does not erase DBMS_OUTPUT.")

    Edited by: Quluzade Mr. Mahir on February 28, 2011 12:18

  • Using of the dynamic SQL and the cursor in a procedure

    Here is the procedure:
    create or replace
    Procedure type_paiement_total
    is
    
        cursor xbtable is select table_name from user_tables where table_name like 'XB%';
        n_table user_tables.table_name%type;
        req     varchar2(256);
        journal varchar2(2);
        mois varchar2(2);
        an varchar2(2);
      begin
        for n_table in xbtable
        loop
          execute immediate 'insert into xx_jk_xb (
          clie_code,journal, periode,origine, xb_ecri,xb_libe  ,dos_code,xb_debi,xb_cred,xb_term
    )
    select c.code,  
    substr(:1,3,2),
    substr(:1,7,2)||substr(:1,5,2)||,
    :1,  
    xb.ecri,  
    xb.libe,  
    d.code,
    xb.debi,
    xb.cred,
    xb.terme
    from                      
    '||n_table.table_name ||' xb,
    dossier d,                      
    client c                    
    where xb.cmpt=''4111''                    
    and xb.doss  =d.code                    
    and c.code   =d.clie
    and c.role=''1''' using n_table.table_name;
          execute immediate 'insert into xx_jk_logxb (recnum,xb_ref,trsf) values (seq_logmreg.nextval,:1,''OK'')' using n_table.table_name;
          commit;
          fetch xbtable into n_table;
        end loop;
      end;
    What he does (or what I intend to do)
    take the datas of a whole bunch of pictures and put them in the "XX_JK_XB" table and make a log of the tables covered in xx_jk_logxb give just the source table and the status (OK).
    Now when I run the procedure I get a "missing expression" th ' immediate «insert into xx_jk...»» »

    I just can't tell what is the problem here.

    clues?

    Seems to me that you are wrong assuming that the binding can be done by name and no position when you use immediate enforcement.

    Example:

    SQL> create table foo_tab( c1 varchar2(10), n1 number );
    
    Table created.
    
    SQL>
    SQL> begin
      2          for i in 1..10
      3          loop
      4                  execute immediate 'insert into foo_tab values( to_char(:1), :1 )' using i;
      5          end loop;
      6          commit;
      7  end;
      8  /
    begin
    *
    ERROR at line 1:
    ORA-01008: not all variables bound
    ORA-06512: at line 4
    
    SQL>
    SQL>
    SQL> begin
      2          for i in 1..10
      3          loop
      4                  execute immediate 'insert into foo_tab values( to_char(:1), :1 )' using i,i;
      5          end loop;
      6          commit;
      7  end;
      8  /
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    As you can see, 1 PL/SQL block attempts to re - use bind variable: 1 new - and only link once.

    Fact does not work like that - you must link it again. Binding is done by bind - 1 position = 1 to the help of var, 2nd = 2nd bind using var, etc.. Name of the connection variable used is irrelevant and not unique.

  • Dynamic SQL with a Ref Cursor

    Hello

    I have a package that returns a Ref Cursor, in this procedure, I have a dynamic sql code that is built according to certain values, and the query is a select query, is it possible that I can put that dynamic sql in the ref cursor and return of the procedure.

    Or y at - it no alternative better workaround.

    Thanks in advance.

    Naveen

    Yes you can.

    Try this...

    create or replace package test_pack is
    type ref_cur is ref cursor;
    procedure just_print(ref_var ref_cur);
    end;
    /
    
    create or replace package body test_pack is
    procedure just_print(ref_var ref_cur) is
    l_var emp%rowtype;
    begin
    loop
    fetch ref_var into l_var;
    exit when ref_var%notfound;
    dbms_output.put_line(l_var.ename);
    end loop;
    end;
    end;
    /
    
    declare
    cur_var test_pack.ref_cur;
    dsql varchar2(100);
    begin
    dsql := 'select * from emp where deptno=10';
    open cur_var for dsql;
    test_pack.just_print(cur_var);
    end;
    /
    CLARK
    KING
    MILLER
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.00
    

    Kind regards
    Prazy

  • How the date can be filled with timestamp in dynamic sql

    Hi all

    Below we have sql

    v_stmt: = ' MERGE IN MTH_EQUIPMENTS_EXT_B ED

    WITH THE HELP OF)

    SELECT TAG_DATA,

    EQUIPMENT_FK_KEY,

    WORKORDER_FK_KEY,

    SEGMENT_FK_KEY,

    SHIFT_WORKDAY_FK_KEY,

    HOUR_FK_KEY,

    ITEM_FK_KEY,

    READ_TIME,

    ATTR_GROUP_ID,

    RECIPE_NUM,

    RECIPE_VERSION,

    NVL (FND_GLOBAL. User_Id,-1) l_updated_by,.

    NVL (FND_GLOBAL. Login_Id,-1) l_last_update_login

    OF MTH_TAG_READINGS_T_STG

    WHERE DB_COL = ' | " ' || v_colname | " ' ||') TS

    WE (';)

    v_stmt: = v_stmt | "ED. EQUIPMENT_PK_KEY = TS. EQUIPMENT_FK_KEY AND

    ED. READ_TIME = TS. READ_TIME AND

    ED. ATTR_GROUP_ID = TS. ATTR_GROUP_ID)

    WHEN MATCHED THEN

    UPDATE

    GAME ED.'. v_colname |' = TS. TAG_DATA,

    ED. LAST_UPDATED_BY = 1, ";

    v_stmt: = v_stmt | "ED. LAST_UPDATE_LOGIN = TS.l_last_update_login

    WHEN NOT MATCHED THEN

    INSERT ('| v_colname |', EXTENSION_ID, EQUIPMENT_PK_KEY, WORKORDER_FK_KEY, SEGMENT_FK_KEY, SHIFT_WORKDAY_FK_KEY, HOUR_FK_KEY, ITEM_FK_KEY, READ_TIME, ATTR_GROUP_ID, LAST_UPDATE_DATE, LAST_UPDATED_BY,';)

    v_stmt: =.

    v_stmt | ("LAST_UPDATE_LOGIN, CREATED_BY, CREATION_DATE, RECIPE_NUM, RECIPE_VERSION)

    VALUES (TS. TAG_DATA, EGO_EXTFWK_S.NEXTVAL, TS. EQUIPMENT_FK_KEY, TS. WORKORDER_FK_KEY, TS. SEGMENT_FK_KEY, TS. SHIFT_WORKDAY_FK_KEY, TS. HOUR_FK_KEY, TS. ITEM_FK_KEY, TS. READ_TIME,';

    v_stmt: = v_stmt | "TS. ATTR_GROUP_ID,' | '''|| SYSDATE | "'| ', 1, TS.l_last_update_login, TS.l_updated_by,'|"' | SYSDATE | " ' ||', TS. RECIPE_NUM, TS. RECIPE_VERSION)';

    EXECUTE IMMEDIATE v_stmt;

    After you run the above SQL last date of update in MTH_EQUIPMENST_EXT_B is filled with sysdate but timestamp is not its always 00:00:00. Can we have timestamp also populated through dynamic sql in the last update date

    Kind regards

    Amrit

    Values to hardcode in the dynamic SQL - never use bind variables:

    v_stmt: = ' MERGE IN MTH_EQUIPMENTS_EXT_B ED

    WITH THE HELP OF)

    SELECT TAG_DATA,

    EQUIPMENT_FK_KEY,

    WORKORDER_FK_KEY,

    SEGMENT_FK_KEY,

    SHIFT_WORKDAY_FK_KEY,

    HOUR_FK_KEY,

    ITEM_FK_KEY,

    READ_TIME,

    ATTR_GROUP_ID,

    RECIPE_NUM,

    RECIPE_VERSION,

    NVL (FND_GLOBAL. User_Id,-1) l_updated_by,.

    NVL (FND_GLOBAL. Login_Id,-1) l_last_update_login

    OF MTH_TAG_READINGS_T_STG

    WHERE DB_COL =: 1) TS

    WE (';)

    v_stmt: = v_stmt | "ED. EQUIPMENT_PK_KEY = TS. EQUIPMENT_FK_KEY AND

    ED. READ_TIME = TS. READ_TIME AND

    ED. ATTR_GROUP_ID = TS. ATTR_GROUP_ID)

    WHEN MATCHED THEN

    UPDATE

    GAME ED.'. v_colname |' = TS. TAG_DATA,

    ED. LAST_UPDATED_BY = 1, ";

    v_stmt: = v_stmt | "ED. LAST_UPDATE_LOGIN = TS.l_last_update_login

    WHEN NOT MATCHED THEN

    INSERT ('| v_colname |', EXTENSION_ID, EQUIPMENT_PK_KEY, WORKORDER_FK_KEY, SEGMENT_FK_KEY, SHIFT_WORKDAY_FK_KEY, HOUR_FK_KEY, ITEM_FK_KEY, READ_TIME, ATTR_GROUP_ID, LAST_UPDATE_DATE, LAST_UPDATED_BY,';)

    v_stmt: =.

    v_stmt | ("LAST_UPDATE_LOGIN, CREATED_BY, CREATION_DATE, RECIPE_NUM, RECIPE_VERSION)

    VALUES (TS. TAG_DATA, EGO_EXTFWK_S.NEXTVAL, TS. EQUIPMENT_FK_KEY, TS. WORKORDER_FK_KEY, TS. SEGMENT_FK_KEY, TS. SHIFT_WORKDAY_FK_KEY, TS. HOUR_FK_KEY, TS. ITEM_FK_KEY, TS. READ_TIME,';

    v_stmt: = v_stmt | "TS. ATTR_GROUP_ID,: 2, 1, TS.l_last_update_login, TS.l_updated_by,: 3, TS. RECIPE_NUM, TS. RECIPE_VERSION)';

    V_stmt EXECUTE IMMEDIATE

    With the HELP of v_colname,.

    SYSDATE,

    SYSDATE;

    SY.

  • Quoted string inside dynamic SQL

    Hello
    My version of db: database Oracle 11 g Enterprise Edition Release 11.2.0.1.0 - 64 bit Production

    I run this code in a proc, and it goes to the exception block without running the code below:
    EXECUTE IMMEDIATE
        'SELECT LISTAGG (entitlement, '''','''') WITHIN GROUP (ORDER BY entitlement)
        FROM XMLTABLE (                                 
            ''''/ROWSET/ROW/ENTITLEMENTS/ENTITLEMENT''''      
            PASSING XMLPARSE (DOCUMENT p_xmldoc)        
            COLUMNS ENTITLEMENT VARCHAR2(30) PATH ''''.'''')'                                    
        INTO v_str;
    I made a mistake with quoted strings and I have tried different combinations, but anyway his does not work.
    THA real piece of code is below, whick I'm trying to run immediately in a string
    SELECT LISTAGG (entitlement, ',') WITHIN GROUP (ORDER BY entitlement)                              
                                            FROM XMLTABLE (                                 
                                                '/ROWSET/ROW/ENTITLEMENTS/ENTITLEMENT'      
                                                PASSING XMLPARSE (DOCUMENT p_xmldoc)        
                                                COLUMNS ENTITLEMENT VARCHAR2(30) PATH '.')
    p_xmldoc sample is less than
    '<?xml version="1.0"?>
    <ROWSET>
    <ROW>
    <ENTITLEMENTS>
      <ENTITLEMENT>AMEX</ENTITLEMENT>
      <ENTITLEMENT>JCB</ENTITLEMENT>
    </ENTITLEMENTS>
    </ROW>
    </ROWSET>'
    My goal is to get
    v_str = AMEX, JCB
    Please advice.

    Hello

    Use the notation by Q.
    Assuming that the dynamic control does not contain a right brace immediately before a single quote, you can say:

    
    sql_txt := Q'{SELECT LISTAGG (entitlement, ',') WITHIN GROUP (ORDER BY entitlement) ...}';
    dbms_output.put_line (sql_txt || ' = sql_txt');
    -- EXECUTE IMMEDIATE sql_txt;
    

    With Q-rating, you can't excape double, or otherwise single quotes.

    When you write code dynamic SQL, put the full command in a single VARCHAR2 variable (such as the sql_txt above). During the test, display it. If it looks right, then a comment the line where actually run you it.

  • RE: Dynamic Sql

    Hello gurus,

    I have a doubt!

    How to get the value of a dynamic sql inside the loop For?
    DECLARE
       lv_v_sql   VARCHAR2 (4000);
    BEGIN
       lv_v_sql :=
             'SELECT a FROM'
          || ' (SELECT 1 AS a FROM DUAL '
          || 'UNION ALL '
          || 'SELECT 2 AS a FROM DUAL'
          || ' UNION ALL '
          || 'SELECT 3 AS a FROM DUAL '
          || ' UNION ALL '
          || ' SELECT 4 AS a FROM DUAL'
          || ' UNION ALL '
          || ' SELECT 5 AS a FROM DUAL) '
          || ' where a='
          || 1;
    
       EXECUTE IMMEDIATE lv_v_sql;
    
       DBMS_OUTPUT.put_line (lv_v_sql);
    
       FOR i IN lv_v_sql
       LOOP
          DBMS_OUTPUT.put_line (i);
       END LOOP;
    END;
    Kind regards
    a friend :)

    Just add IN the clause EXECUTE IMMEDIATE. Example below shows you how to select EXECUTE IMMEDIATE data when it returns a single row and when she returns several lines:

    SQL> DECLARE
      2     lv_v_sql   VARCHAR2 (4000);
      3     v_a number;
      4     v_a_tbl sys.OdciNumberList;
      5  BEGIN
      6     lv_v_sql :=
      7           'SELECT a FROM'
      8        || ' (SELECT 1 AS a FROM DUAL '
      9        || 'UNION ALL '
     10        || 'SELECT 2 AS a FROM DUAL'
     11        || ' UNION ALL '
     12        || 'SELECT 3 AS a FROM DUAL '
     13        || ' UNION ALL '
     14        || ' SELECT 4 AS a FROM DUAL'
     15        || ' UNION ALL '
     16        || ' SELECT 5 AS a FROM DUAL) '
     17        || ' where a='
     18        || 1;
     19     EXECUTE IMMEDIATE lv_v_sql
     20       INTO v_a;
     21     DBMS_OUTPUT.put_line (lv_v_sql);
     22     DBMS_OUTPUT.put_line(v_a);
     23     lv_v_sql :=
     24           'SELECT a FROM'
     25        || ' (SELECT 1 AS a FROM DUAL '
     26        || 'UNION ALL '
     27        || 'SELECT 2 AS a FROM DUAL'
     28        || ' UNION ALL '
     29        || 'SELECT 3 AS a FROM DUAL '
     30        || ' UNION ALL '
     31        || ' SELECT 4 AS a FROM DUAL'
     32        || ' UNION ALL '
     33        || ' SELECT 5 AS a FROM DUAL) ';
     34     EXECUTE IMMEDIATE lv_v_sql
     35       BULK COLLECT
     36       INTO v_a_tbl;
     37     DBMS_OUTPUT.put_line (lv_v_sql);
     38     FOR i IN 1..v_a_tbl.COUNT
     39     LOOP
     40        DBMS_OUTPUT.put_line(v_a_tbl(i));
     41     END LOOP;
     42  END;
     43  /
    SELECT a FROM (SELECT 1 AS a FROM DUAL UNION ALL SELECT 2 AS a FROM DUAL UNION ALL SELECT 3 AS a FROM DUAL  UNION ALL  SELECT 4 AS a
    FROM DUAL UNION ALL  SELECT 5 AS a FROM DUAL)  where a=1
    1
    SELECT a FROM (SELECT 1 AS a FROM DUAL UNION ALL SELECT 2 AS a FROM DUAL UNION ALL SELECT 3 AS a FROM DUAL  UNION ALL  SELECT 4 AS a
    FROM DUAL UNION ALL  SELECT 5 AS a FROM DUAL)
    1
    2
    3
    4
    5
    
    PL/SQL procedure successfully completed.
    

    SY.

  • Dynamic SQL with dynamic identifiers

    Oracle 10gXE

    I have a table that is used to track student attendance. If the student is present on a given day, a record is inserted with the student ID and the date they frequented.

    presence of DESC
    Name of Type Null
    --------------- -------- ------
    ID NOT NULL NUMBER
    NUMBER OF STUDENT_ID
    SITE_ID NUMBER
    DATE OF ATTENDANCE_DATE

    I want to view a report (in TOP) which shows all students for a given site, the days when school was in session for this month (not Saturday, Sunday) and a X for the student who participated in that day or a null value if they do not have.

    ID # FNAME LNAME 3 4 5 6 7 10
    38754636 POE JANE X X X
    81248754 DOE KAYLA X X X X X
    43127409 RAO JOHN X X X X X

    In this example, days 3 and 7 of the month are from Monday to Friday and 8-9 have been excluded because they are on Saturday and Sunday.

    I am trying to find a way to dynamically generate a query for any month/year and returning to a report. The obstacle is that given that I don't know in advance which days in a month will be excluded, the identifiers in my select statement are not fixed.

    I found a query that returns a list of day numbers and dates for a given month. It looks like this:

    SELECT LEVEL lv, TO_DATE (TO_CHAR (LEVEL, '09')
    || TO_CHAR (EXTRACT (TO_DATE('01-SEP-11') MONTHS), '09')
    || To_char (EXTRACT (TO_DATE('01-SEP-11') YEAR), ' 9999'), 'dd.mm.yyyy') mon_day
    OF double WHERE ROWNUM < = EXTRACT (DAY OF LAST_DAY (TO_DATE('01-SEP-11')))
    CONNECT BY LEVEL = ROWNUM

    I combined this request with another brings my student attendance data and results that pivots in what I need. Then, I created a function that accepts the month and year as parameters and creates the combined request.

    SELECT c.ID student_id, c.last_name, c.first_name,.
    MAX (decode (mon_day, ' 01 - SEPT.-11', 'X', NULL)) '1', MAX (decode (mon_day, ' 02 - SEVEN.-11', 'X', NULL)) '2 ',.
    MAX (decode (mon_day, ' 05 - SEPT.-11', 'X', NULL)) '5', MAX (decode (mon_day, ' 06 - SEPT.-11', 'X', NULL)) "6."
    MAX (decode (mon_day, ' 07-SEP-11', 'X', NULL)) '7', MAX (decode (mon_day, ' 08 - SEPT.-11', 'X', NULL)) "8."
    MAX (decode (mon_day, ' 09 - SEPT.-11', 'X', NULL)) '9', MAX (decode (mon_day, 12-SEP-11', 'X', NULL)) "12."
    MAX (decode (mon_day, 13-SEP-11', 'X', NULL)) '13', MAX (decode (mon_day, 14-SEPT-11', 'X', NULL)) "14."
    MAX (decode (mon_day, 15-SEP-11', 'X', NULL)) '15', MAX (decode (mon_day, 16-SEP-11', 'X', NULL)) "16."
    MAX (decode (mon_day, 19-SEP-11', 'X', NULL)) '19', MAX (decode (mon_day, 20-7.-11', 'X', NULL)) "20."
    MAX (decode (mon_day, 21-SEP-11', 'X', NULL)) "21", MAX (decode (mon_day, 22-SEP-11', 'X', NULL)) '22 ',.
    MAX (decode (mon_day, 23-SEP-11', 'X', NULL)) '23', MAX (decode (mon_day, 26-SEP-11', 'X', NULL)) "26."
    MAX (decode (mon_day, 27-SEP-11', 'X', NULL)) '27', MAX (decode (mon_day, 28-SEP-11', 'X', NULL)) "28."
    MAX (decode (mon_day, 29-SEP-11', 'X', NULL)) '29', MAX (decode (mon_day, 30-SEP-11', 'X', NULL)) '30 '.
    (SELECT level lv, TO_DATE (TO_CHAR (LEVEL, '09')
    || TO_CHAR (EXTRACT (TO_DATE('01-SEP-11') MONTHS), '09')
    || To_char (EXTRACT (TO_DATE('01-SEP-11') YEAR), ' 9999'), 'dd.mm.yyyy') mon_day
    OF double WHERE ROWNUM < = EXTRACT (DAY OF LAST_DAY (TO_DATE('01-SEP-11')))
    CONNECTION LEVEL = ROWNUM) a, b of attendance, student c
    WHERE to_char(MON_DAY,'D') NOT IN (1.7)
    AND A.mon_day = b.attendance_date
    AND b.student_id = c.ID
    Group of c.ID, student_id, c.last_name, c.first_name

    Now I'm stuck on what I can pass this request in to get my result. What I've read, dynamic SQL method 4 would work if I incorporate Pro/C. I hope this isn't my only option. I have considered to try to do this in a function table in pipeline, but since the columns returned are not known in advance, I can't create a corresponding data type.

    I'm starting to wonder if I forgot a simpler method to achieve this.

    Published by: David Sumner on April 12, 2012 18:52

    Ignoring the actual query and looking at the dynamic SQL part of the question.

    There are 3 ways to run a dynamic select SQL in PL/SQL code.

    immediate execution requires a fixed number of bind variables, linking him in position and translates a single implicit output cursor extraction - requiring the projection of cursor to be known at the time of coding.

    REF CURSOR are essentially the same - the only exception being that it requires an extraction explicit coding process output cursor.

    DBMS_SQL differs in all of these respects. The connection is by name and not position. The connection is dynamic. Projection of the cursor must not be known at the time of coding. It is dynamically determined at runtime and fetch offers of release of the cursor with the projection of unknown SQL - coding time.

    Apex uses DBMS_SQL internally (in fact he uses DBMS_SYS_SQL properly run dynamic and specific patterns of Oracle SQL, as if a session connected as a scheme runs the SQL code). This allows the Apex to take a dynamic SQL that you enter a region (which can contain a variable number of bind variable), run it and make the projection of the cursor as an HTML report.

    Apex supports in turn also dynamic SQL - what you (Apex developer) to provide a dynamic SQL code for a region, instead of you having to provide SQL fixed (with bind variable) for the region in question.

    As Apex creates DBMS_SQL sliders, it doesn't have your SQL as a ref cursor or cursor DBMS_SQL. All they need is the source of the SQL statement. And that's what you create dynamically.

    So in the Apex, dynamic SQL means using a function from PL/SQL to return the source for Apex SQL analyze like a slider DBMS_SQL - instead of coding the source SQL statement in a fixed statement.

    So, using the option of function for an area considered in the Apex, allows you to provide the following in the code that must run to get the SQL statement for the report Apex (Apex running this as a dynamic function that returns a string):

    --// return the dynamic SQL for the report region
    return(
      case
        when :P1_OPTION = 1 then
          'select * from emp'
    
        when :P1_OPTION = 2 then
          'select * from dept where dept_id = :P1_DEPT_ID'
      end
    );
    

    You can also write a PL/SQL function that is stored in the database and call this function so that it can determine what is the dynamic SQL source code statement. For example

    --// calling database function to return the dynamic SQL for the report region
    return(
      GetDynamicReportSQL( page => 1, option => :P1_OPTION )
    );
    

    Dynamic SQL is fully supported by Apex - but does not require that you, the developer, to create the dynamic cursor and treat the dynamic linking and dynamic recovery of this slider.

    All you have to do is to provide the source code of this dynamic SQL (including the bind variable) to the Apex and it will do the whole thing from cursor for you.

  • Dynamic SQL is a valid option?

    Hello

    I have question on insertion I have a large amount of lines that I want to insert into a table. Insert rows are like;

    001 09 00 FF
    001 09 FF 11
    FF 00 11 001
    001 00 01 00

    There are four types of conditions. Only the last condition can be inserted, while the rest cannot be inserted (in other words, on four columns to all who have the value 'FF' must not be inserted).

    I wanted to use a simple constraint checking, but our DBA is not agree on this. The reason is that overall with many conditions will create a problem with the database-level locking.

    Now, I think to use dynamic SQL and the place of the condition in the WHERE clause. I think right and make any sense?

    I think I have to be aware of performance because there will be a mass insertion.

    Published by: uk113 on July 28, 2009 06:03

    In fact, I agree with kind of your DBA, but not his reasons. A check against the content of a column constraint will not cause a locking more in the database column without constraint. If you update a row in the table, Oracle will have a lock on the rows updated if they are limited or not. A newly inserted row never "locked" because it is no longer visible in the session that he introduced to the validation of this session.

    You say "I have a lot of lines that I want to insert into a table" which implies to me that you have the source data in an accessible form electronically, which means you can do single insertion as a SQL statement. As many others have suggested, I would use a predicate on each of the columns that cannot contain FF to remove these rows from the result set that you will use to make the insertion.

    Given the constraints on the table for a loading block, particulalry if you know you will have a fairly large number of rows in your data source, which will infringe the constraint actually will force you in a row by row (or bulk collect bulk collect) scenario so that you can catch constraint violations and throw these lines. Although you can still use a predicate to filter the lines that would not allow the validation.

    If you need constraints after loading mass will depend on whether or not you expect to get new data in the table, and how it will be inserted or updated. If new data come mainly from single row inserts and updates (for example from the application screen), then I would certainly limit the columns to allow not FF. If you do only loads in bulk, I would add probably not these constraints. If you are likely to have a mix of bulk and individual tips, I add the constraints, but still have a predicate in loads in bulk to filter incorrect records.

    John

  • SQL * more the "prompt" command does not display a semicolon (;)

    In a script, I have a command prompt which wrote a useful message in a queue. The final character to be displayed by the command is a semicolon (;). The semicolon is not displayed. The same thing happens when I run the command from a SQL * over the command line. Here is the command and its output:

    SQL > PROMPT seeks access: SELECT * FROM < table_name > WHERE rowid = '< rowid > ';
    seeks access: SELECT * FROM < table_name > WHERE rowid = '< rowid >.

    Can someone tell me why the semicolon is not shown, and what I need to do to make it appear?


    Thank you
    Bill

    Try

    SQL > PROMPT seeks to access: SELECT * FROM  WHERE rowid='';;
    seeks to access: SELECT * FROM  WHERE rowid='';
    

    SQL * more is likely to interpret the single semicolon as the terminator of sql.

  • How to get sql % number of dynamic sql code lines

    Hello

    In this procedure I'm inserting and updating using dynamic sql. Now I want to go back two more PARAMETERS, the parameter should be back the number of lines inserted and how updated by stmtas of UPDATE as well as an INSERT. I'm not able to do can help you on that?

    CREATE OR REPLACE PROCEDURE Sp_Array_Test( PV_TGT_NAME   IN  VARCHAR2,
                                               PV_SRC_NAME   IN  VARCHAR2,
                                               PV_PK_COLS    IN  VARCHAR2,
                                               PN_ERR_CD     OUT NUMBER,
                                               PN_ERR_MSG    OUT VARCHAR2)
    AS
    
    
    TYPE ARR_TAB IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    
    
    --UTL_FP        UTL_FILE.FILE_TYPE;
    LV_AN_
    
    
    
    BLOCK   VARCHAR2(32767);
    LN_CUR        BINARY_INTEGER := DBMS_SQL.OPEN_CURSOR;
    LN_DESC       DBMS_SQL.DESC_TAB;
    LN_COL_CNT    PLS_INTEGER := 0;
    LV_SEL_UPD_STMT   VARCHAR2(4000);
    LV_SEL_INS_STMT   VARCHAR2(4000);
    ARR_INDX      NUMBER := 1;
    LV_DATA_TYPE  VARCHAR2(8);
    LN_FIND_FLAG  NUMBER := 0;
    LN_TAB        ARR_TAB;
    LV_COLS_ARR   ARR_TAB;
    LV_ERR_MSG    VARCHAR2(500);
    
    
    
    
    --PROCEDURE FILE_WRITE ( FH_IN     IN UTL_FILE.FILE_TYPE,
    --                STRING_IN IN VARCHAR2 ) IS
    --BEGIN
    --   UTL_FILE.PUT_LINE(FH_IN,STRING_IN);
    --   LV_AN_BLOCK := LV_AN_BLOCK||STRING_IN;
    --EXCEPTION
    --   WHEN OTHERS THEN
    --      RAISE;
    --END FILE_WRITE;
    
    
    
    
    BEGIN
    
    
    --   UTL_FP := UTL_FILE.FOPEN('TEST_DIR', 'TEST.sql', 'W');
    
    
        LV_SEL_UPD_STMT := 'SELECT A.'||REPLACE(PV_PK_COLS,',','||A.')||' PK_COLS , A.* , B.ROWID FROM '||PV_SRC_NAME||' A, '||PV_TGT_NAME||' B WHERE ';
    
    
        LV_SEL_INS_STMT := 'SELECT A.* FROM '||PV_SRC_NAME||' A WHERE NOT EXISTS (SELECT ''1'' FROM '||PV_TGT_NAME||' B WHERE ';
    
    
        LN_TAB(ARR_INDX) := 'DECLARE ';
        ARR_INDX := ARR_INDX + 1;
    
    
        LN_TAB(ARR_INDX) := 'CURSOR CUR_VIEW_UPD IS '||LV_SEL_UPD_STMT ;
        ARR_INDX := ARR_INDX + 1;
    
    
    
    
        SELECT SUBSTR(COLS,DECODE(RN,1,1,INSTR(COLS,',',1,RN-1)+1),DECODE(RN,1,INSTR(COLS,',',1,RN)-1,INSTR(COLS,',',1,RN)-INSTR(COLS,',',1,RN-1)-1))
    BULK COLLECT INTO LV_COLS_ARR
          FROM ( SELECT RN, PV_PK_COLS||',' COLS
                   FROM (SELECT ROWNUM RN
                           FROM ALL_OBJECTS
                          WHERE ROWNUM <= LENGTH(PV_PK_COLS)- LENGTH(REPLACE(PV_PK_COLS,','))+1)) ;
        FOR K IN 1 .. LV_COLS_ARR.COUNT LOOP
            LV_SEL_UPD_STMT     := LV_SEL_UPD_STMT||' A.'||LV_COLS_ARR(K)||' = ';
            LN_TAB(ARR_INDX) := ' A.'||LV_COLS_ARR(K)||' = ';
            LV_SEL_UPD_STMT     := LV_SEL_UPD_STMT||' B.'||LV_COLS_ARR(K) ||CASE WHEN K = LV_COLS_ARR.COUNT THEN NULL ELSE ' AND ' END;
            LN_TAB(ARR_INDX) := LN_TAB(ARR_INDX)||' B.'||LV_COLS_ARR(K) ||CASE WHEN K = LV_COLS_ARR.COUNT THEN ' ;' ELSE ' AND ' END;
            ARR_INDX := ARR_INDX + 1;
        END LOOP;
    
    
        LN_TAB(ARR_INDX) := 'CURSOR CUR_VIEW_INS IS '||LV_SEL_INS_STMT ;
        ARR_INDX := ARR_INDX + 1;
    
    
        FOR K IN 1 .. LV_COLS_ARR.COUNT LOOP
            LV_SEL_INS_STMT     := LV_SEL_INS_STMT||' A.'||LV_COLS_ARR(K)||' = ';
            LN_TAB(ARR_INDX) := ' A.'||LV_COLS_ARR(K)||' = ';
            LV_SEL_INS_STMT     := LV_SEL_INS_STMT||' B.'||LV_COLS_ARR(K) ||CASE WHEN K = LV_COLS_ARR.COUNT THEN NULL ELSE ' AND ' END;
            LN_TAB(ARR_INDX) := LN_TAB(ARR_INDX)||' B.'||LV_COLS_ARR(K) ||CASE WHEN K = LV_COLS_ARR.COUNT THEN ' );' ELSE ' AND ' END;
            ARR_INDX := ARR_INDX + 1;
        END LOOP;
    
    
    
    
        LV_ERR_MSG := 'WHILE PARSING SELECT STATEMENT -- '||LV_SEL_UPD_STMT;
        DBMS_SQL.PARSE(LN_CUR, LV_SEL_UPD_STMT, DBMS_SQL.NATIVE);
    
    
        LV_ERR_MSG := 'WHILE DESCRIBING SELECT STATEMENT -- '||LV_SEL_UPD_STMT;
        DBMS_SQL.DESCRIBE_COLUMNS(LN_CUR, LN_COL_CNT, LN_DESC);
    
    
    
    
    
    
       FOR i IN LN_DESC.FIRST .. LN_DESC.LAST LOOP
          IF LN_DESC(i).col_type = 2 THEN
             LV_DATA_TYPE := 'NUMBER';
          ELSIF LN_DESC(i).col_type = 12 THEN
             LV_DATA_TYPE := 'DATE';
          ELSE
             LV_DATA_TYPE := 'VARCHAR2';
          END IF;
           LN_TAB(ARR_INDX) := '   T_'||LN_DESC(i).col_name||' DBMS_SQL.'||LV_DATA_TYPE||'_TABLE;';
           ARR_INDX := ARR_INDX + 1;
       END LOOP;
    
    
    
    
    
    
        LN_TAB(ARR_INDX) := 'BEGIN ';
        ARR_INDX := ARR_INDX + 1;
        LN_TAB(ARR_INDX) := '   EXECUTE IMMEDIATE ''ALTER SESSION SET NLS_DATE_FORMAT = ''''DD-MON-YYYY HH24:MI:SS'''''';';
        ARR_INDX := ARR_INDX + 1;
        LN_TAB(ARR_INDX) := '   OPEN CUR_VIEW_UPD;';
        ARR_INDX := ARR_INDX + 1;
        LN_TAB(ARR_INDX) := '   LOOP';
        ARR_INDX := ARR_INDX + 1;
        LN_TAB(ARR_INDX) := '      FETCH CUR_VIEW_UPD BULK COLLECT INTO T_'||LN_DESC(LN_DESC.FIRST).col_name||',';
        ARR_INDX := ARR_INDX + 1;
        FOR i IN LN_DESC.FIRST + 1 .. LN_DESC.LAST - 1 LOOP
          LN_TAB(ARR_INDX) := '                        T_'||LN_DESC(i).col_name||',';
          ARR_INDX := ARR_INDX + 1;
        END LOOP;
       LN_TAB(ARR_INDX) := '                        T_'||LN_DESC(LN_DESC.LAST).col_name||' LIMIT 500 ;';
       ARR_INDX := ARR_INDX + 1;
       LN_TAB(ARR_INDX) := '     FORALL I IN 1 .. '||'T_'||LN_DESC(LN_DESC.LAST).col_name||'.COUNT ';
       ARR_INDX := ARR_INDX + 1;
        LN_TAB(ARR_INDX) := '      UPDATE '||PV_TGT_NAME||' SET  ';
        ARR_INDX := ARR_INDX + 1;
        LN_FIND_FLAG := 0;
        FOR I IN LN_DESC.FIRST + 1 .. LN_DESC.LAST-1 LOOP
          FOR K IN 1 .. LV_COLS_ARR.COUNT LOOP
             LN_FIND_FLAG := 0;
             IF LN_DESC(I).COL_NAME = LV_COLS_ARR(K) THEN
                LN_FIND_FLAG := 1;
                EXIT;
             END IF;
          END LOOP;
          IF LN_FIND_FLAG = 0 THEN
            LN_TAB(ARR_INDX) := '                        '||LN_DESC(i).col_name||' = '||'T_'||LN_DESC(i).col_name||'(I)'||CASE WHEN I = LN_DESC.LAST-1 THEN ' WHERE ' ELSE ',' END;
            ARR_INDX := ARR_INDX + 1;
          END IF ;
        END LOOP;
    
    
       LN_TAB(ARR_INDX) := '                        ROWID = '||'T_'||LN_DESC(LN_DESC.LAST).col_name||'(I) ;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '      COMMIT;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '      EXIT WHEN CUR_VIEW_UPD%NOTFOUND;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '   END LOOP;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '   CLOSE CUR_VIEW_UPD;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '      COMMIT;';
       ARR_INDX := ARR_INDX + 1;
    
    
    
    
        LN_TAB(ARR_INDX) := '   OPEN CUR_VIEW_INS;';
        ARR_INDX := ARR_INDX + 1;
        LN_TAB(ARR_INDX) := '   LOOP';
        ARR_INDX := ARR_INDX + 1;
        LN_TAB(ARR_INDX) := '      FETCH CUR_VIEW_INS BULK COLLECT INTO T_'||LN_DESC(LN_DESC.FIRST+1).col_name||',';
        ARR_INDX := ARR_INDX + 1;
        FOR i IN LN_DESC.FIRST + 2 .. LN_DESC.LAST - 2 LOOP
          LN_TAB(ARR_INDX) := '                        T_'||LN_DESC(i).col_name||',';
          ARR_INDX := ARR_INDX + 1;
        END LOOP;
       LN_TAB(ARR_INDX) := '                        T_'||LN_DESC(LN_DESC.LAST-1).col_name||' LIMIT 500 ;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '     FORALL J IN 1 .. '||'T_'||LN_DESC(LN_DESC.FIRST + 1).col_name||'.COUNT ';
       ARR_INDX := ARR_INDX + 1;
       LN_TAB(ARR_INDX) := '     INSERT INTO '||PV_TGT_NAME||' (';
       ARR_INDX := ARR_INDX + 1;
        FOR i IN LN_DESC.FIRST + 1 .. LN_DESC.LAST - 1 LOOP
          LN_TAB(ARR_INDX) := '                        '||LN_DESC(i).col_name||CASE WHEN I = LN_DESC.LAST - 1  THEN ' )' ELSE ',' END ;
          ARR_INDX := ARR_INDX + 1;
        END LOOP;
        FOR i IN LN_DESC.FIRST + 1 .. LN_DESC.LAST - 1 LOOP
          LN_TAB(ARR_INDX) := CASE WHEN I = LN_DESC.FIRST + 1 THEN 'VALUES (' ELSE NULL END ||'                        T_'||LN_DESC(i).col_name||'(J)'||CASE WHEN I = LN_DESC.LAST - 1  THEN ' ) ;' ELSE ',' END ;
          ARR_INDX := ARR_INDX + 1;
        END LOOP;
    
    
       LN_TAB(ARR_INDX) := '      COMMIT;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '      EXIT WHEN CUR_VIEW_INS%NOTFOUND;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '   END LOOP;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '   CLOSE CUR_VIEW_INS;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := '      COMMIT;';
       ARR_INDX := ARR_INDX + 1;
    
    
       LN_TAB(ARR_INDX) := 'END ;';
       ARR_INDX := ARR_INDX + 1;
    
    
    
    
       FOR J IN 1 .. LN_TAB.COUNT LOOP
    --     DBMS_OUTPUT.PUT_LINE( LN_TAB(J));
    --     FILE_WRITE(UTL_FP,LN_TAB(J));
         LV_AN_BLOCK := LV_AN_BLOCK||LN_TAB(J);
       END LOOP;
    
    
    --   UTL_FILE.FCLOSE(UTL_FP);
    
    
       EXECUTE IMMEDIATE LV_AN_BLOCK;
    
    
    PN_ERR_CD    := 0;
    PN_ERR_MSG   := 'Successful Completion';
    
    
    EXCEPTION
    WHEN OTHERS THEN
    PN_ERR_CD    := SQLCODE;
    PN_ERR_MSG   := LV_ERR_MSG||' -- '||SQLERRM ;
    END;
    /
    

    Thank you all for your answers. I agree with you all. I have manged this time by adding variable bind, then run it immediately ON aid. I don't know how it's going to be training.

    From now on my side no problem I don't thank you.

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

Maybe you are looking for