我有一个表列表,每次数据迁移之前都需要重命名。
我想出了以下过程来检查该表是否存在,并在创建日期之后附加名称,最终对其进行重命名:
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变量,并为需要检查的每个对象重复执行代码:有没有办法将它们作为列表插入表变量左右,并进行代码循环对于那里的每个值?
谢谢。
是的,我喜欢@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
您需要添加检查长表是否存在以及是否已经存在重命名的表。我也将这些语句记录到日志表中。
关于"
:仅当数据库中混合了大小写表名时,我才使用它们。