我有一个带有一些表的数据库,每个表都有ID
主键列。所有ID
s 都包含巨大的随机数,例如827140014
,9827141241
等。从 1 (1
, 2
,3
等)开始按时间顺序编辑和更改此值的最简单方法是什么?行的顺序无关紧要。
我想为 SQL Server、Oracle、PostgreSQL 和 SQLite 做这件事(每个都有不同的解决方案)。
另外假设有一些表依赖于ID
(外键)。
我有一个带有一些表的数据库,每个表都有ID
主键列。所有ID
s 都包含巨大的随机数,例如827140014
,9827141241
等。从 1 (1
, 2
,3
等)开始按时间顺序编辑和更改此值的最简单方法是什么?行的顺序无关紧要。
我想为 SQL Server、Oracle、PostgreSQL 和 SQLite 做这件事(每个都有不同的解决方案)。
另外假设有一些表依赖于ID
(外键)。
对于甲骨文
一个)。如果有表引用您要更新的表,您要做的第一件事就是禁用外键约束。您可以使用以下查询生成所有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');
乙)。运行生成的 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)。
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。
对于 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 并保存它们的顺序。