我在 plsql 脚本中有一些 (5) 重命名语句
drop table new;
rename old to new;
“旧”表包含非常有价值的信息。
如我所见,如果保证重命名命令是原子的,那么我将解决一个问题。
是原子的吗?如果没有,有没有办法进行“安全”重命名?
提前致谢
RENAME
是一个 DDL 命令。所以它是一个单独的离散事务,如果这就是你在这种情况下所说的原子的意思。因此,它几乎与任何东西一样安全。我无法想象重命名会如何导致您丢失数据。但是,如果您感到偏执,请记住这就是大自然为我们提供备份和恢复的原因。
编辑
DROP
确保在成功和失败时不会丢失数据的方法RENAME
是部署RENAME
两次:
SQL> rename old_table to something_else;
SQL> rename new_table to old_table;
SQL> drop table something_else;
这样您就可以在线获取数据。这也最大限度地减少了停机时间。
鉴于您的评论“这是一个日常过程”和“是的,我担心 drop 和 rename 语句之间的失误”
你有多少钱(或者更具体地说,你有分区选项)?如果是这样,请查看分区交换
您的永久表由单个分区组成。在一天结束时,您将该分区与表交换(作为单个原子语句)。通过不删除/重命名主表,您不应该使任何包等无效(尽管这可能取决于数据库版本)。
未能使用视图并执行 CREATE OR REPLACE VIEW main AS SELECT * FROM table_a 并且每天晚上您将视图替换为不同表上的新视图。不过,这可能会使软件包无效。
Rename
将是原子的,所以你应该没问题。正如 APC 所指出的,
我无法想象重命名会如何导致您丢失数据。
我可以在您的脚本中看到的唯一内容是删除之后和重命名之前的时间,没有new
表,因此某些 SQL 可能会失败。但是,那个时间会很短,任何更复杂的东西(比如Insert From Select
)都会有更大的问题。
我猜您担心旧表上的并发 DML(插入/更新/删除)在重命名期间可能会丢失?在这种情况下,请不要担心 - RENAME 是 DDL,它会在持续时间内锁定表。
如果您担心删除和重命名之间的时间,这里有另一个想法:使用指向“正确基础表”的视图。
你会从
CREATE VIEW someName as Select * From OldTable;
然后你可以设置你的newTable。当你准备好了,然后
CREATE OR REPLACE View someName as Select * From NewTable;
然后你可以删除你的 OldTable。下次您获得一些新数据时,构建另一个 NewTable_2(或重用 OldTable .. 那么使用 Table1 和 Table2 可能会更好)并再次重新定义视图。
该视图尽可能简单,因此它应该可以毫无问题地更新。唯一棘手的事情是始终构建一个新表(或在两个表之间切换),但这不应该太难设置,并且可能比完全避免原始建议可能出现的任何问题更容易。