L oop через фиксированный список значений - PullRequest
0 голосов
/ 06 мая 2020

У меня есть список таблиц, которые необходимо переименовывать перед каждой миграцией данных.

Я придумал следующую процедуру, чтобы проверить, существует ли таблица, и в конечном итоге переименовать ее, добавив дату создания:

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 вручную и повторения кода для каждого из объектов, которые мне нужно проверить: есть ли способ вставить их в виде списка в переменную таблицы или около того, и иметь код l oop для каждого из значений?

Спасибо.

1 Ответ

0 голосов
/ 06 мая 2020

Да, мне нравится идея @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 символов в имени. Короткое имя должно быть уникальным, иначе у двух таблиц будет одно и то же короткое имя. Порядок сортировки - это только переименование каждый раз в одном и том же порядке.

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

Вам нужно будет добавить проверки, существует ли длинная таблица и существует ли уже переименованная таблица. Я бы тоже записал эти операторы в таблицу журнала.

Относительно ": я бы использовал их только в том случае, если у вас есть имена таблиц со смешанным регистром в базе данных.

...