我的数据库有很多客户,客户编号(NUMBER(10)
)可能会超出范围。
由于其他旧系统,我对此键无能为力。解决方案是添加另一列,以后将用作new
客户参考。
无论如何,有没有办法在不停机的情况下将所有值从旧列复制到新列?
如果我运行此SQL,表将被锁定(I / O)大约2-3分钟(不可接受)
UPDATE table SET new_customer_ref = old_customer_number;
编辑:谢谢大家的帮助。我最终使用了@Simulant
提供的解决方案这就是我所做的:
-- Copy all old numbers to new reference in batches of 5000
DECLARE
i NUMBER := 1;
batchsize NUMBER := 5000;
maxId NUMBER;
BEGIN
SELECT MAX(ID) INTO maxId FROM CUSTOMER;
EXCEPTION
WHEN no_data_found THEN maxId := 0; /* Prevent endless loop if no customers. */
LOOP
UPDATE CUSTOMER SET new_ref = old_number WHERE ID >= i AND ID < i + batchSize;
i := i + batchSize;
COMMIT;
EXIT WHEN i>maxId ;
END LOOP;
END;
/
答案 0 :(得分:2)
您可以编写一个脚本(以您选择的任何一种语言),该脚本能够连接到数据库并以100-1000行的块为单位更新值。这样,您可以拥有多个事务,每个事务的运行时间都较短。
由于迁移现在是异步的,因此您应在应用程序代码中处理新列可能为null的情况,而该值未迁移。在这种情况下,依靠旧值,并在更改新值时也进行更新。如果新值已经存在,则不需要特殊处理。完成完整的迁移后,您可以删除此后备处理。
答案 1 :(得分:0)
您可以更改现有列而不是创建新列。
ALTER TABLE Table_name MODIFY customer NUMBER(50);
答案 2 :(得分:0)
在这种情况下,COMPUTED COLUMN
很有帮助,如果您被允许更改表的结构,这样就不需要随时更新记录
ALTER TABLE TABLE_NAME ADD [new_customer_ref] AS [old_customer_number]