简体   繁体   中英

How to pass list of table names as parameter in stored procedure in Oracle SQL Developer? How to use PLSQL VARRAY or nested table?

I have a code which accepts a table name as parameter and creates subpartitions on that table name for the partitions. My table is partitioned on list of source system codes and range subpartitoned on monthly basis.

Question: If suppose I have variable list of tables and I want to create subpartitions for all then I need to modify this procedure every time to pass varying list of tables. Can I use PLSQL VARRAY or nested table to hold my list of tables, and pass this VARRAY or nested table as a parameter to the below procedure and create subpartitions for all the table names the VARRAY or nested table is holding?

Your help is much appreciated. Many thanks!

Code:

CREATE OR REPLACE PROCEDURE execute_subpartition ( table_name IN varchar2)

IS
 tbl_nm varchar2(30) := table_name;
 sqlstr VARCHAR2(1000);

  CURSOR TabSubPartition IS
  SELECT TABLE_NAME, PARTITION_NAME
  FROM USER_TAB_PARTITIONS
  WHERE TABLE_NAME = tbl_nm
  ORDER BY PARTITION_NAME;
BEGIN
     FOR aSubPart IN TabSubPartition LOOP
       IF TRUNC(LAST_DAY(SYSDATE)) = TRUNC(SYSDATE)
        sqlstr := 'ALTER TABLE TUCEL001.' || aSubPart.TABLE_NAME || ' MODIFY PARTITION ' || 
     aSubPart.PARTITION_NAME ||' ADD SUBPARTITION '  || aSubPart.PARTITION_NAME || '_' || 
     TO_CHAR(TRUNC(LAST_DAY(SYSDATE) + 1), 'MON_YYYY') ||' VALUES LESS THAN (TIMESTAMP ''' || 
     TRIM(to_char(add_months((TRUNC(LAST_DAY(SYSDATE))+1), 1), 'SYYYY-MM-DD HH24:MI:SS', 
     'NLS_CALENDAR=GREGORIAN')) || ''')'; 
     dbms_output.put_line(sqlstr);
     EXECUTE IMMEDIATE sqlstr;
  
    ELSE
          dbms_output.put_line('the condition did not match');
    END IF;
  END LOOP;
Exception
   WHEN OTHERS
   THEN
 dbms_output.put_line('encountered an error, because the sub-partitions which are being created 
  already exists');
END;

My 11g doesn't have partitioning enabled so I can't demonstrate it.

But, see if this example (of creating some tables) helps. You don't have to declare your own type - sys.odcivarchar2list should do. Read it using the table function and use its column_value in your dynamic SQL.

Procedure:

SQL> create or replace procedure p_test (par_tables in sys.odcivarchar2list) as
  2    l_str varchar2(200);
  3  begin
  4    for cur_r in (select column_value as table_name
  5                  from table(par_tables)
  6                 )
  7    loop
  8      dbms_output.put_line('table name = ' || cur_r.table_name);
  9      l_str := 'create table ' || dbms_assert.qualified_sql_name(cur_r.table_name) ||
 10               '  (id     number,' ||
 11               '   name   varchar2(20))';
 12      execute immediate(l_str);
 13    end loop;
 14  end;
 15  /

Procedure created.

Testing:

SQL> exec p_test(sys.odcivarchar2list('tab_a', 'tab_b'));

PL/SQL procedure successfully completed.

SQL> desc tab_a;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
 NAME                                               VARCHAR2(20)

SQL> desc tab_b;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
 NAME                                               VARCHAR2(20)

SQL>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM