代码之家  ›  专栏  ›  技术社区  ›  Nickon

无序主键列的海量主键编辑[已关闭]

  •  0
  • Nickon  · 技术社区  · 11 年前

    我有一个数据库,里面有一些表,每个表都有 ID 主键列。全部的 身份证件 s包含巨大的随机数,如 827140014 , 9827141241 ,等等。从1开始,按时间顺序编辑和更改这些值的最简单方法是什么( 1 , 2 , 3 等等)?行的顺序无关紧要。

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

    此外,假设有一些表依赖于 身份证件 (外键)。

    3 回复  |  直到 11 年前
        1
  •  1
  •   Kombajn zbożowy    11 年前

    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
  •   Przemyslaw Kruglej    11 年前

    对于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;
    

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

    ALTER TABLE YOUR_TABLE_NAME DROP COLUMN temp_new_id;
    

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

        3
  •  1
  •   alexius    11 年前

    对于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并保存它们的顺序。