无序主键列的大规模主键版本

时间:2013-10-18 12:15:52

标签: sql sql-server oracle sqlite postgresql

我有一个包含一些表的数据库,每个表都有ID主键列。所有ID都包含大量随机数,例如8271400149827141241等。从1(1开始,按时间顺序编辑和更改此值的最简单方法是什么? 23等)?行的顺序并不重要。

我想为SQL Server,Oracle,PostgreSQL和SQLite做这些(每个都可以有不同的解决方案)。

另外假设有些表依赖于ID(外键)。

3 个答案:

答案 0 :(得分:1)

对于Oracle

A)。如果存在引用要更新的表的表,则首先要做的是禁用外键约束。您可以使用以下查询生成所有ALTER语句:

SELECT 'ALTER TABLE ' || owner || '.' || table_name ||
       ' DISABLE CONSTRAINT ' || constraint_name || ';'
  FROM all_constraints
WHERE constraint_type = 'R'
  AND r_constraint_name = 
                        (SELECT constraint_name
                          FROM all_constraints
                         WHERE constraint_type = 'P'
                           AND table_name = 'YOUR_TABLE_NAME'
                           AND owner = 'OWNER_OF_THAT_TABLE');

B)。运行生成的ALTER语句。

C)。接下来,您必须生成新的ID。您可以添加新列来保存这些值,也可以创建临时表。新栏目方法:

ALTER TABLE YOUR_TABLE_NAME ADD temp_new_id NUMBER;

d)。填充列:

-- Create a sequence to generate new IDs
CREATE SEQUENCE YOUR_TABLE_NAME_seq START WITH 1 CACHE 20;
UPDATE YOUR_TABLE_NAME SET temp_new_id = YOUR_TABLE_NAME_seq.nextVal;
COMMIT;

E)。以这种方式更新每个从属表中的ID:

UPDATE some_dep_table sdt SET sdt.master_table_id = 
  (SELECT ytn.temp_new_id FROM YOUR_TABLE_NAME ytn WHERE sdt.master_table_id = ytn.id);
COMMIT;

F)。更新您的表 - 将ID从临时列移动到具有ID:

的实际列
UPDATE YOUR_TABLE_NAME SET id = temp_new_id;
COMMIT;

克)。从表中删除临时列:

ALTER TABLE YOUR_TABLE_NAME DROP COLUMN temp_new_id;

H)。依赖表的ENABLE约束(使用查询从点a生成它们),只需将DISABLE替换为ENABLE即可。)

答案 1 :(得分:1)

Oracle解决方案:给表some_table,列id为主键:

CREATE TABLE my_order AS SELECT id, rownum rn FROM some_table;
ALTER TABLE my_order ADD CONSTRAINT pk_order PRIMARY KEY (id);

UPDATE
  (SELECT t.*, o.rn FROM some_table t JOIN my_order o on (t.id = o.id))
SET id = rn;

DROP TABLE my_order;

你应该能够在PostgreSQL中运行类似的东西,只需使用解析函数row_number而不是Oracle的rownum。我不确定其他引擎。

对于引用表,只需确保外键约束为ON UPDATE CASCADE。

答案 2 :(得分:1)

对于PostgreSQL:

UPDATE table SET id = t.new_id

FROM (
    SELECT id as old_id, ROW_NUMBER() OVER (ORDER BY id) AS new_id
    FROM table
) t

WHERE id = t.old_id

这将用(1,2,...)替换ID并保存他们的订单。