如何在 Oracle SQL Developer 的存储过程中将表名列表作为参数传递?如何使用 PLSQL VARRAY 或嵌套表?

Posted

技术标签:

【中文标题】如何在 Oracle SQL Developer 的存储过程中将表名列表作为参数传递?如何使用 PLSQL VARRAY 或嵌套表?【英文标题】:How to pass list of table names as parameter in stored procedure in Oracle SQL Developer? How to use PLSQL VARRAY or nested table? 【发布时间】:2020-11-14 14:03:00 【问题描述】:

我有一个代码,它接受一个表名作为参数,并在该表名上为分区创建子分区。我的表按源系统代码列表进行分区,并且范围按月进行子分区。

问题:如果假设我有可变的表列表并且我想为所有表创建子分区,那么我需要每次修改此过程以传递不同的表列表。 我可以使用 PLSQL VARRAY 或嵌套表来保存我的表列表,并将这个 VARRAY 或嵌套表作为参数传递给下面的过程,并为 VARRAY 或嵌套表所持有的所有表名创建子分区吗?

非常感谢您的帮助。非常感谢!

代码:

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;

【问题讨论】:

【参考方案1】:

我的 11g 没有启用分区,所以无法演示。

但是,看看这个例子(创建一些表)是否有帮助。您不必声明自己的类型 - sys.odcivarchar2list 应该这样做。使用table 函数读取它并在动态SQL 中使用它的column_value

程序:

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.

测试:

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>

【讨论】:

我无法理解如何使用上述示例作为我的查询的解决方案。 :( 在我上面的过程中,我想传递一个表名列表作为参数,它再次在过程中的 select 语句的 where 子句中处理以获取某些记录。此外,我需要筛选所有给定记录的两列值,并使用这些值创建子分区。 和我一样;您将编写自己的动态 SQL 来完成工作的 分区 部分。我不能,我的数据库不支持分区。除此之外,应该没问题。 很抱歉,我不明白您的问题是什么。我清楚地展示了如何传递表列表以及如何在 WHERE 子句中使用它。你没看到吗?也许你不喜欢它,但这是一个不同的问题。 非常感谢您的上述示例,我能够利用类似的功能并获得所需的结果。除了上面我在存储过程中使用了 pl/sql 嵌套游标 FOR 循环。

以上是关于如何在 Oracle SQL Developer 的存储过程中将表名列表作为参数传递?如何使用 PLSQL VARRAY 或嵌套表?的主要内容,如果未能解决你的问题,请参考以下文章

如何安装pl/sql developer

如何安装pl/sql developer

如何在 SQL Developer 中检查语法 Oracle 存储过程?

oracle 客户端 sql developer 如何修改jdk版本

如何在 Oracle SQL Developer 中查询数据库名称?

如何在 oracle sql developer 中运行存储过程?