Skip to Main Content
  • Questions
  • Getting Compilation errors for PACKAGE BODY NAV_PKG_ST Error: PLS-00306: wrong number or types of arguments in call to '||' Line: 1728 Text: EXECUTE IMMEDIATE 'INSERT INTO '||TAB_COUNT.TABLE_NAME ||' VALUES '||V_CRS_IS_DART_COLL(I)

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Srinadh.

Asked: March 24, 2017 - 3:32 pm UTC

Last updated: March 28, 2017 - 1:12 am UTC

Version: Oracle 11g

Viewed 1000+ times

You Asked

Thanks in Advance TOM

I am Srinadh And i have an issue in my code.

i am using dynamic sql to insert data into some of tables(Cursor C_TABLES ) from Views(Cursor DAIL_VIEWS ).

i am getting the above error and also i'm not sure can we use Dynamic Sql(Execute Immediate) inside the ForAll Insert ?

Could you please provide the solution for the above issue?

PROCEDURE IS_LOAD_LOGICAL_DATA_PR_SRI 
  IS
  
  CURSOR DAIL_VIEWS IS
    SELECT VIEW_NAME
      FROM ALL_VIEWS
     WHERE VIEW_NAME LIKE 'V_DART_%'
       AND SUBSTR(VIEW_NAME, 8, 4) IN
           (SELECT DOMAIN
              FROM IS_DOMAIN_REVIEW_MASTER
             WHERE DEL_FLG <> 'Y'
          ORDER BY SUBSTR(VIEW_NAME, 8, 4);

  CURSOR C_TABLES IS
    SELECT TABLE_NAME
      FROM ALL_TABLES
     WHERE TABLE_NAME LIKE 'IS_DART_%'
     ORDER BY SUBSTR(TABLE_NAME, 9, 4);

  V_SQL VARCHAR2(1000);
  
  TYPE CRS_IS_DART IS REF CURSOR;
  V_CRS_IS_DART CRS_IS_DART;
  
  TYPE CRS_IS_DART1 IS RECORD
  (USUBJID        VARCHAR2(1999),
  STUDY          VARCHAR2(1999),
  PATIENT        VARCHAR2(1999),
  LSTCHGTS       DATE,
  DOCNUM         VARCHAR2(1999),
  LOGINTS        DATE,
  CUT_OFF_GROUP  VARCHAR2(500),
  PATIENT_STATUS VARCHAR2(4000)
  );
  TYPE CRS_IS_DART_COLL IS TABLE OF CRS_IS_DART1;
  V_CRS_IS_DART_COLL CRS_IS_DART_COLL;
  
  LV_DB_NAME        VARCHAR2(100);
  
  BEGIN
  
    SELECT UPPER(substr(global_name, 1, (instr(global_name, '.') - 1)))
      INTO LV_DB_NAME
      FROM global_name;
      
  IF LV_DB_NAME IN ('LSHDEV2', 'LSHTST') THEN
        
      FOR DAIL_COUNT IN DAIL_VIEWS LOOP
        FOR TAB_COUNT IN C_TABLES LOOP

          IF SUBSTR(DAIL_COUNT.VIEW_NAME, 8, 4) =
             SUBSTR(TAB_COUNT.TABLE_NAME, 9, 4) THEN

            OPEN V_CRS_IS_DART FOR 
               'Dynamic Sql Select Statement using View name from Cursor DAIL_VIEWS and Some conditions ';
               BEGIN
                 
               LOOP                  
                  FETCH V_CRS_IS_DART BULK COLLECT 
                   INTO V_CRS_IS_DART_COLL;
                
                FORALL I IN 1..V_CRS_IS_DART_COLL.COUNT
                
                EXECUTE IMMEDIATE 'INSERT INTO '||TAB_COUNT.TABLE_NAME ||' VALUES '||V_CRS_IS_DART_COLL(I);

                     EXIT WHEN V_CRS_IS_DART%NOTFOUND;

                END LOOP; 
             EXCEPTION
               WHEN OTHERS THEN
                 raise;
              END;                       
          END IF;
        END LOOP;
      END LOOP;
 END IF; 
  COMMIT;
EXCEPTION
  WHEN OTHERS THEN
    RAISE_APPLICATION_ERROR(-20002, SUBSTR(SQLERRM, 1, 500));
END IS_LOAD_LOGICAL_DATA_PR_SRI;

and Connor said...

EXECUTE IMMEDIATE 'INSERT INTO '||TAB_COUNT.TABLE_NAME ||' VALUES '||V_CRS_IS_DART_COLL(I);

wont work because 'V_CRS_IS_DART_COLL' is a record, and you are trying to do a concatenate operation on a record.

You probably want to recode that as something like:

EXECUTE IMMEDIATE 'INSERT INTO '||TAB_COUNT.TABLE_NAME ||
' VALUES (:1,:2,:3,:4,:5,:6,:7,:8)'
using
V_CRS_IS_DART_COLL(I).USUBJID
,V_CRS_IS_DART_COLL(I).STUDY
,V_CRS_IS_DART_COLL(I).PATIENT
,V_CRS_IS_DART_COLL(I).LSTCHGTS
,V_CRS_IS_DART_COLL(I).DOCNUM
,V_CRS_IS_DART_COLL(I).LOGINTS
,V_CRS_IS_DART_COLL(I).CUT_OFF_GROUP
,V_CRS_IS_DART_COLL(I).PATIENT_STATUS

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Information Required

Srinadh Tummala, March 27, 2017 - 8:11 am UTC

Thanks for the answer McDonald and that was more Helpful.:)

and i want to know is there any other way to do the same?

Means instead of Record can we any other collection type to insert all data at once(||V_CRS_IS_DART_COLL(I)) and not using Bind variables?

And also one more question

using bind variables and inserting one by one value into the table is impact any performance?

Thanks in Advance.
Connor McDonald
March 28, 2017 - 1:12 am UTC

Inserting 1 by 1 will always be slower than inserting in a batch.

If you cannot use insert-select like my example, then you would bulk binding, ie FORALL to batch load the rows.


Things are better in 12c when going between plsql types and sql - more info here:

http://www.oracle.com/technetwork/issue-archive/2013/13-nov/o63plsql-2034269.html

https://livesql.oracle.com/apex/livesql/file/content_CHREI3LLPBLRAHQR9TDJIO677.html

but you still wont be able to bind a record type variable dynamically

SQL> create table t ( x int , y int );

Table created.

SQL>
SQL> declare
  2    r t%rowtype;
  3  begin
  4    execute immediate 'insert into t values :1' using r;
  5  end;
  6  /
declare
*
ERROR at line 1:
ORA-00902: invalid datatype
ORA-06512: at line 4


More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library