Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Unable to INSERT PL/SQL record with EXECUTE IMMEDIATE

424775Jul 16 2007 — edited Jul 18 2007

Hi All,

I am selecting data from a source table and after some modification inserting into a target table. Source and target table name are available at run time. You can say only source table structure is fixed.
I have crated a pl/sql table of type source record and inserting record by record in target table using execute immediate. But I am not able to write

EXECUTE IMMEDIATE string USING pl_sql_table(index); and getting error as

PLS-00457: expressions have to be of SQL types

Please see the part of code below. Is it possible to use FORALL with dynamic sql like
FORALL pl_sql_table.FIRST .. pl_sql_table.COUNT
EXECUTE IMMEDIATE .... pl_sql_table(j); -- Like this.

Please suggest why I am not able to write record here. I also want to replace 'INSERT in a loop' with a single INSERT statement out of the loop, to upload whole pl_sql table into target table in one go.

Thanks,
Ravi

DECLARE

    TYPE rec_tab_CMP IS RECORD 
    (
	model_id		NUMBER(38),    
	absolute_rank		NUMBER(5)          
    );
    v_rec_tab_CMP  rec_tab_CMP;


    TYPE t_rec_tab_CMP IS TABLE OF v_rec_tab_CMP%TYPE INDEX BY BINARY_INTEGER; 
    v_records_CMP               t_rec_tab_CMP;

    rc                          SYS_REFCURSOR;
    v_old_table_name            VARCHAR2(30); -- passed from parameter  
    v_new_table_name            VARCHAR2(30); -- passed from parameter  
    dyn_str                     VARCHAR2(500);
    v_columns_str               VARCHAR2(200) := ' model_id, absolute_rank '; 

BEGIN

  	EXECUTE IMMEDIATE 'CREATE TABLE '|| v_new_table_name || ' AS SELECT * FROM ' || v_old_table_name ||' WHERE 1 = 2 ' ;

	OPEN rc FOR 'SELECT '|| v_columns_str ||' FROM '|| v_old_table_name;
	FETCH rc BULK COLLECT INTO v_records_CMP;

	FOR j IN 1..v_records_CMP.COUNT
	LOOP

	   v_records_CMP(j).model_id := 1; -- Do someting here, This thing can be performed in SQL stmt directly. 

	   dyn_str := 'INSERT INTO '|| v_new_table_name ||' ( '|| v_columns_str || ' ) VALUES (:1, :2) ';

	   EXECUTE IMMEDIATE dyn_str USING v_records_CMP(j).model_id		,
					   v_records_CMP(j).absolute_rank	;

	-- Here in place of two columns I want to use one record like 
	-- EXECUTE IMMEDIATE dyn_str USING v_records_CMP(j);
	-- But it is giving me error like 
        --          EXECUTE IMMEDIATE dyn_str USING v_records_st(j);
        --   PLS-00457: expressions have to be of SQL types
	--

	END LOOP;

	CLOSE rc;

END;
/
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 15 2007
Added on Jul 16 2007
5 comments
1,473 views