【问题标题】:Oracle- creating dynamic function for deleting tables based on cursorOracle——创建基于游标删除表的动态函数
【发布时间】:2020-07-19 02:53:06
【问题描述】:

我正在尝试在 Oracle 中为所有需要删除并重新创建的表使用游标来构建动态函数。例如,我有以下示例表结构:

CREATE TABLE All_tmp_DATA AS
(SELECT 'T_tmp_test1' As Table_NM, 'TEST1' As Process_name FROM DUAL UNION ALL
 SELECT 'T_tmp_test2' As Table_NM, 'TEST1' As Process_name FROM DUAL UNION ALL
 SELECT 'T_tmp_test3' As Table_NM, 'TEST1' As Process_name FROM DUAL)

以上以“T_tmp”开头的表代表了数据库中所有在启动TEST1过程时如果它们的计数>1则需要删除的表。我真的需要一个函数来传递参数 Process_name,我可以在其中输入“TEST1”,并使用游标通过将其绑定到来自 All_tmp_DATA 的 Table_NM 并将其插入到以下代码中的 table_name 中来构建一个循环:

BEGIN  
  SELECT count(*)
    INTO l_cnt
    FROM user_tables
    WHERE table_name = 'MY_TABLE';
  IF l_cnt = 1 THEN
    EXECUTE IMMEDIATE 'DROP TABLE my_table';
  END IF;
END;

【问题讨论】:

  • 我以前从未听说过 Oracle 13。你确定版本号是正确的吗?此外,SELECT CREATE TABLE... 不是有效的 Oracle 语法。请说明您实际使用的数据库系统。
  • 嗨,鲍勃,很抱歉有错别字。如果您去掉第一行中的 SELECT,它应该创建临时表。这是 ORACLE TOAD 第 13 版。谢谢 Yen
  • TOAD 是一个 SQL 客户端,它的版本基本上与您的问题无关。更相关的是您使用的 Oracle 版本(例如select * from v$version

标签: sql oracle ddl dml


【解决方案1】:

一开始,我建议您在命名 Oracle 对象时不要使用混合大小写。


测试用例:

SQL> select * From all_tmp_data;

TABLE_NM    PROCE
----------- -----
T_tmp_test1 TEST1
T_tmp_test2 TEST1
T_tmp_test3 TEST1

SQL> create table "T_tmp_test1" as select * From dept;

Table created.

SQL> -- I don't have "T_tmp_test2"
SQL> create table "T_tmp_test3" as select * From emp;

Table created.

SQL>
SQL> select table_name From user_Tables where upper(table_name) like 'T_TMP%';

TABLE_NAME
------------------------------
T_tmp_test3
T_tmp_test1

删除ALL_TMP_DATA中包含的表的过程:

  • 与您的代码相反,我将表名与DROP 连接起来
  • 当您使用混合大小写的表名时,您必须将它们的名称括在双引号中,总是(我说过不要使用吗?)

正如最终的select 所示,这些表不再存在。

SQL> declare
  2    l_cnt number;
  3  begin
  4    for cur_r in (select table_nm from all_tmp_data) loop
  5      select count(*) into l_cnt
  6      from user_tables
  7      where table_name = cur_r.table_nm;
  8
  9      if l_cnt > 0 then
 10         execute immediate ('drop table "' || cur_r.table_nm || '"');
 11      end if;
 12    end loop;
 13  end;
 14  /

PL/SQL procedure successfully completed.

SQL> select table_name From user_Tables where upper(table_name) like 'T_TMP%';

no rows selected

SQL>

截至process 专栏:我不知道它是做什么用的,所以我就是这么做的——没有使用它。

【讨论】:

    【解决方案2】:

    您可以使用异常处理直接处理这种情况,如下所示:

    DECLARE
        TABLE_DOES_NOT_EXIST EXCEPTION;
        PRAGMA EXCEPTION_INIT ( TABLE_DOES_NOT_EXIST, -00942 );
    BEGIN
        FOR CUR_R IN (
            SELECT TABLE_NM
              FROM ALL_TMP_DATA
        ) LOOP
            BEGIN
                EXECUTE IMMEDIATE 'drop table "' || cur_r.table_nm || '"';
                DBMS_OUTPUT.PUT_LINE('"' || cur_r.table_nm || '" table dropped.');
            EXCEPTION
                WHEN TABLE_DOES_NOT_EXIST THEN
                    DBMS_OUTPUT.PUT_LINE('"' || cur_r.table_nm || '" table does not exists');
            END;
        END LOOP;
    END;
    /
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-20
      • 2021-01-14
      • 2015-06-28
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多