SQL - 将一列复制到另一列
Posted
技术标签:
【中文标题】SQL - 将一列复制到另一列【英文标题】:SQL - Copy one column to another 【发布时间】:2018-10-29 07:07:13 【问题描述】:我有一个包含很多客户的数据库,并且客户编号 (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;
/
【问题讨论】:
只有表会被“锁定”,绝对不是“数据库”。并且该表仅针对其他 UPDATE 或 DELETE 语句锁定。它没有被锁定以读取插入语句。 如果update
对您来说太慢,您可以随时创建一个新表,例如:Select a,b, old_customer_number, old_customer_number as new_customer_ref from table
。删除您的原始表格并将此表格重命名为原始表格。
@MayankPorwal - 似乎与替换表相关的停机时间 - 重新授予权限,重新编译无效代码等 - 将大大超过 2-3 分钟更新锁定。
【参考方案1】:
您可以编写一个脚本(使用您选择的任何语言),该脚本能够连接到您的数据库并以 100-1000 行为单位更新值。这样,您就有了多个事务,每个事务的运行时间都更短。
由于迁移现在是异步的,您应该在应用程序代码中处理新列可能为空,而值未迁移。在这种情况下,依赖旧值并在更改时更新新值。如果新值已经存在,则不需要特殊处理。完成迁移后,您可以删除此回退处理。
【讨论】:
【参考方案2】:您可以更改现有列而不是创建新列。
ALTER TABLE Table_name MODIFY customer NUMBER(50);
【讨论】:
OP 明确表示他们对此密钥无能为力。【参考方案3】:我认为在这种情况下COMPUTED COLUMN
非常有用,如果您可以更改表的结构,这样您就不需要随时更新记录了
ALTER TABLE TABLE_NAME ADD [new_customer_ref] AS [old_customer_number]
【讨论】:
以上是关于SQL - 将一列复制到另一列的主要内容,如果未能解决你的问题,请参考以下文章