循环通过固定值列表

问题描述 投票:0回答:1

我有一个表列表,每次数据迁移之前都需要重命名。

我想出了以下过程来检查该表是否存在,并在创建日期之后附加名称,最终对其进行重命名:

DECLARE
     v_cnt PLS_INTEGER;
     v_date varchar2(50); 
     v_table varchar2(50);
     v_table_short varchar2(50);

BEGIN
    v_table:='MT_TABLE_1';
    v_table_short:=SUBSTR(v_table,8);

    SELECT COUNT(*)
    INTO v_cnt
    FROM dba_tables
    WHERE owner = 'OWNER'
    AND table_name = v_table;

      IF(v_cnt > 0) THEN
        select CREATED into v_date FROM DBA_OBJECTS WHERE OBJECT_TYPE = 'TABLE' AND OBJECT_NAME=v_table;
        execute immediate 'rename "'||v_table||'" to "'||v_table_short||'_'||v_date||'"';
      END IF;

    v_table:='MY_TABLE_2';
    v_table_short:=SUBSTR(v_table,8);

    SELECT COUNT(*)
    INTO v_cnt
    FROM dba_tables
    WHERE owner = 'OWNER'
    AND table_name = v_table;

      IF(v_cnt > 0) THEN
        select CREATED into v_date FROM DBA_OBJECTS WHERE OBJECT_TYPE = 'TABLE' AND OBJECT_NAME=v_table;
        execute immediate 'rename "'||v_table||'" to "'||v_table_short||'_'||v_date||'"';
      END IF;
END;
/

现在,我要避免手动定义v_table变量,并为需要检查的每个对象重复执行代码:有没有办法将它们作为列表插入表变量左右,并进行代码循环对于那里的每个值?

谢谢。

sql oracle plsql oracle-sqldeveloper plsqldeveloper
1个回答
0
投票

是的,我喜欢@Srinika的想法。像这样的东西:

CREATE TABLE table_list (
  sort_order NUMBER             UNIQUE,
  long_name  VARCHAR2(128 BYTE) PRIMARY KEY,
  short_name VARCHAR2(128 BYTE) UNIQUE
);
INSERT INTO table_list VALUES (1,'MY_TABLE_1','MYTAB1'); 
INSERT INTO table_list VALUES (2,'MY_TABLE_2','MYTAB2'); 

我为短名称添加了一个列,而不是即时对其进行计算,因为两个表的名称前8个字符可能相同。 short_name必须是唯一的,否则两个表将以相同的短名称结尾。排序顺序只是每次都以相同的顺序进行重命名。

CREATE OR REPLACE PROCEDURE rename_tables AS
  v_date       VARCHAR2(8);
  v_short_name VARCHAR2(128);
  v_stmt       VARCHAR2(200);
BEGIN
  v_date := TO_CHAR(SYSDATE, 'YYYYMMDD');
  FOR r IN (SELECT * FROM table_list ORDER BY sort_order) LOOP
    v_short_name := r.short_name || '_' || v_date;
    v_stmt := 'rename '||r.long_name||' to '||v_short_name;
    DBMS_OUTPUT.PUT_LINE(v_stmt);
    EXECUTE IMMEDIATE v_stmt;
  END LOOP;
END rename_tables;
/

调用此过程将产生输出:

rename MY_TABLE_1 to MYTAB1_20200330
rename MY_TABLE_2 to MYTAB2_20200330

您需要添加检查长表是否存在以及是否已经存在重命名的表。我也将这些语句记录到日志表中。

关于":仅当数据库中混合了大小写表名时,我才使用它们。

© www.soinside.com 2019 - 2024. All rights reserved.