Home » SQL & PL/SQL » SQL & PL/SQL » Dynamic SQL (Oracle 11g, XP)
Dynamic SQL [message #597698] Mon, 07 October 2013 13:16 Go to next message
rajivn786
Messages: 161
Registered: January 2010
Senior Member
Hi,

Firstly the table structures :


  Create table cd_patient (pat_mrn varchar2(100)) ;
  Create table cd_encount (pat_mrn varchar2(100), encounter_id varchar2(1000));



I need to write a code which dynamically reads the table name from user_tables (starting with cd) & load the data from remote database which has the same table name & structure based on the load number..

Static PLSQL statement would be :

declare
 

 BEGIN
       INSERT INTO "cd_patient"  C-- DYNAMICALLY GET THE TABLE NAME 
         SELECT C1.PAT_MRN -- DYNAMICALLY GET THE COLUMN NAME
             FROM REMOTE_DB.CD_PATIENT@XXX C1
                 WHERE C1.LOAD_NUMBER > 2;

       INSERT INTO "cd_encount "  C-- DYNAMICALLY GET THE TABLE NAME 
         SELECT C1.PAT_MRN, C1.encounter_id  -- DYNAMICALLY GET THE COLUMN NAME
             FROM REMOTE_DB.cd_encount@XXX C1
                 WHERE C1.LOAD_NUMBER > 2;
 COMMIT;

  END;


There are 60 tables like this.SO, I can't use static 60 SQL's.

The code which I started :

DECLARE

 V_tbl          Varchar2(200);

   Cursor C_TBL Is
    SELECT TABLE_NAME
      FROM ALL_TABLES
      WHERE TABLE_NAME LIKE 'CD%';

    Cursor C_TBL_COL (P_TBL VARCHAR)
   Is
    SELECT COLUMN_NAME
      FROM ALL_TAB_COLUMNS
     Where TABLE_NAME LIKE 'CD%'
       AND TABLE_NAME = P_TBL
       ORDER BY COLUMN_ID;
  

BEGIN

For L1 in C_TBL loop
  V_tbl := L1.table_name;


EXECUTE IMMEDIATE 
  'INSERT INTO ' || V_tbl ||
      ' SELECT ' -- NOT SURE HOW TO RETRIEVE THE COLUMNS
           || ' FROM REMOTE_DB.' || V_tbl || 
              ' V1  WHERE V1.LOAD_NUMBER > 2';
          
COMMIT;     

END; 



Thanks.
Re: Dynamic SQL [message #597700 is a reply to message #597698] Mon, 07 October 2013 13:21 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>There are 60 tables like this.SO, I can't use static 60 SQL's.
YES, You can use static SQL.

> -- NOT SURE HOW TO RETRIEVE THE COLUMNS
query ALL_TAB_COLUMNS

dynamic SQL forces hard parse every execution & does not scale

[Updated on: Mon, 07 October 2013 13:21]

Report message to a moderator

Re: Dynamic SQL [message #597701 is a reply to message #597700] Mon, 07 October 2013 13:24 Go to previous messageGo to next message
rajivn786
Messages: 161
Registered: January 2010
Senior Member
I should have explained it more clearly..

I can use 60 sql's but it's more laborious to write all in a procedure..

So, if pass table name, the code should copy the data that's appended to a table in remote db greater than load number.

Can you modify execute immediate to achieve the result.
Re: Dynamic SQL [message #597702 is a reply to message #597701] Mon, 07 October 2013 13:27 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>I can use 60 sql's but it's more laborious to write all in a procedure..

you can write SQL to write the needed SQL
writing SQL is a one time event
using dynamic SQL you pay performance penalty every time code gets run.
Re: Dynamic SQL [message #597703 is a reply to message #597702] Mon, 07 October 2013 13:41 Go to previous messageGo to next message
rajivn786
Messages: 161
Registered: January 2010
Senior Member
This is the code which I wrote is working..
What do you say about the performance ??

DECLARE

 V_tbl          Varchar2(200);
 V_col          Varchar2(4000);
 V_SQL          Varchar2(4000);
 
   Cursor C_TBL Is
    SELECT TABLE_NAME
      FROM ALL_TABLES
      WHERE TABLE_NAME LIKE 'CD%';

    Cursor C_TBL_COL (P_TBL VARCHAR)
   Is
    SELECT COLUMN_NAME
      FROM ALL_TAB_COLUMNS
     Where TABLE_NAME LIKE 'CD%'
       AND TABLE_NAME = P_TBL
       AND TABLE_NAME = 'CM_USER'
       ORDER BY COLUMN_ID;

 TYPE V_TT IS TABLE OF C_TBL_COL%ROWTYPE INDEX BY PLS_INTEGER;
   L_TT V_TT;  

BEGIN

For L1 in C_TBL loop
  V_tbl := L1.table_name;
--  DBMS_OUTPUT.PUT_LINE (V_tbl);
OPEN C_TBL_COL (L1.table_name);
V_COL := '';
  
Loop
 FETCH C_TBL_COL BULK COLLECT INTO L_TT LIMIT 500;
  FOR indx IN 1 .. L_TT.COUNT
        LOOP
          V_col := V_col || ',' || L_TT(indx).COLUMN_NAME;
         --  DBMS_OUTPUT.PUT_LINE (V_col);
        END LOOP;
      EXIT WHEN L_TT.COUNT = 0;
    END LOOP;

 CLOSE C_TBL_COL;
 
--   DBMS_OUTPUT.PUT_LINE (LTRIM(V_col,','));
V_SQL := 
  'INSERT INTO ' || V_tbl ||
      ' SELECT ' || LTRIM(V_col,',')
           || ' FROM REMOTE_DB' || V_tbl || 
              '@prd.org V1  WHERE V1.LOAD_NUMBER > 2';

        DBMS_OUTPUT.PUT_LINE (V_SQL);  
COMMIT;     
END LOOP;
END; 



Re: Dynamic SQL [message #597705 is a reply to message #597703] Mon, 07 October 2013 13:43 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
COMMIT inside LOOP is a good way to generate ORA-01555 SNAPSHOT TOO OLD error

capture the SQL statements & place them in the procedure

[Updated on: Mon, 07 October 2013 13:44]

Report message to a moderator

Re: Dynamic SQL [message #597706 is a reply to message #597705] Mon, 07 October 2013 13:51 Go to previous messageGo to next message
rajivn786
Messages: 161
Registered: January 2010
Senior Member
Even after capturing SQL's & keeping in the procedure, we still need to commit as it's DML statement??
How do I capture SQL's?? Store in in CLOB variable by doing an union of all 60 tables & pass it as i/p to procedure?
Re: Dynamic SQL [message #597710 is a reply to message #597706] Mon, 07 October 2013 14:04 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>Even after capturing SQL's & keeping in the procedure, we still need to commit as it's DML statement??
yes
>How do I capture SQL's?
COPY & PASTE
Re: Dynamic SQL [message #597716 is a reply to message #597698] Mon, 07 October 2013 15:58 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
rajivn786 wrote on Mon, 07 October 2013 23:46

I need to write a code which dynamically reads the table name from user_tables (starting with cd) & load the data from remote database which has the same table name & structure based on the load number..


There are so many options available -

1.
SELECT    'insert into '
       || table_name
       || ' select * from '
       || table_name
       || '@database_link;'
  FROM user_tables;


2.
SQL*Plus COPY Command

3.
Go through this asktom link

Regards,
Lalit
Re: Dynamic SQL [message #597850 is a reply to message #597716] Tue, 08 October 2013 13:16 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
I'd say you missed most suitable option - materialized view.

SY.
Re: Dynamic SQL [message #597852 is a reply to message #597850] Tue, 08 October 2013 13:20 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Solomon Yakobson wrote on Tue, 08 October 2013 23:46
I'd say you missed most suitable option - materialized view.
.


It might be just a one time task.
Re: Dynamic SQL [message #597855 is a reply to message #597852] Tue, 08 October 2013 15:04 Go to previous message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
Lalit Kumar B wrote on Tue, 08 October 2013 14:20
It might be just a one time task.


Then it is even easier - export/import.

SY.
Previous Topic: ORA-01840: input value not long enough fro date format.
Next Topic: VARRAY error in PLSQL BLOCK
Goto Forum:
  


Current Time: Fri Apr 26 21:41:57 CDT 2024