2009-11-02 53 views
4

我有一组由ID号索引的记录变更记录按键的数量众多,我需要将这些记录的索引转换到一个新的ID号。我有一个将旧数字映射到新数字的两列表格。使用映射表

例如给出这两个表,将更新语句是什么样子?

考虑:

OLD_TO_NEW 
oldid | newid 
----------------- 
1234  0987 
7698  5645 
...   ... 

id  | data 
---------------- 
1234  'yo' 
7698  'hey' 
...   ... 

极品:

id  | data 
---------------- 
0987  'yo' 
5645  'hey' 
...   ... 

此Oracle,所以我有机会获得PL/SQL,我只是想避免它。

回答

4

我有一个内嵌视图上OLD_TO_NEW.oldid唯一索引和更新:

update (select id, 
       newid 
      from old_to_new, 
       my_table 
     where my_table.id = old_to_new.oldid) 
set id = newid 
+0

根据需要完成工作。 – 2009-11-03 18:34:42

2
UPDATE base_table SET id = (SELECT newid FROM old_to_new WHERE oldid = id) 

这就是我如何在MySQL中做到这一点,我认为这是非常标准的。

+0

据我所知,将更新base_table每一个记录,即使有没有在old_to_new相应的记录。有效地试图设置一堆id为NULL的空洞。 – MatBailie 2009-11-02 17:51:24

+0

假设old_to_new并非详尽无遗,是的,但在这个问题中没有提到那种效果。 – Ramon 2009-11-03 06:37:38

0

的无论是从拉蒙和大卫·阿尔德里奇更新语句应该正常工作,但基于的记录数为更新可能更快,像这样一个临时表的工作:

create table temp as (
     select newid, data 
     from old_to_new join my_table on my_table.id = old_to_new.oldid); 

然后截断旧表和临时表复制到旧表或删除旧表,并重新命名临时表。 (注:添加一些额外的语句来处理记录,你没有新的值。)

+0

假设对正在更新的表没有外键约束。我曾经看到有人这样做,有一个级联删除火灾,并无意中消除了一堆或非常重要的数据。 – MatBailie 2009-11-02 17:53:23

+0

啊,但是如果有更新表的FK约束,那么截断会出错。 – 2009-11-02 18:06:09

+0

正如我所说的,除了“简单”更新语句之外,这个解决方案还有一些缺点..但性能可能会好很多。 – Thorsten 2009-11-02 21:26:32

0

这是我会怎么做它在Microsoft SQL Server 2005中已经很多年没有过访问Oracle数据库中,以便这可能对Oracle不起作用。

UPDATE target_table 
SET id = newid 
FROM OLD_TO_NEW 
WHERE target_table.id = OLD_TO_NEW.oldid; 

您可能想索引OLD_TO_NEW.oldid,以便更新连接可以高效运行。

+0

-1:oracle不支持UPDATE SET FROM WHERE语法。抱歉 – 2009-11-02 18:05:03

0

首先进行数据库备份。我还亲自在工作数据库中备份表格,以防出现问题,并且您需要赶紧回到旧的方式。

下一个问题是你有相关的表,也将需要这些编号吗?如果不是,则可以使用更新语句进行更新。编写您的更新说明,以便您可以进行选择并确保它会正确更新。如果您正在制作大量记录,则可能需要分批执行此操作,例如每次记录1000条记录。您可能需要注意的情况是,如果id的值与直接更新重叠可能无效(您将遇到唯一索引)。在这种情况下,您需要添加一列,填充新值,然后删除旧列并重新命名新列。 YOu还需要编写所有索引脚本,fks等,因为您还需要重新运行它们。

相关表变得复杂得多,但新列也是在这种情况下最好的方法。