我正在尝试复制一个条目。那部分并不难。棘手的部分是:有n
条目与外键相关联。对于每个条目,都有n
条目与之相关联。我使用查找手动复制并交叉引用外键
是否有一些子程序或方法来复制条目并搜索和复制外来条目?也许这个类型的复制有一个名字,我还没有发现,这种类型的操作是否有特定的数据库相关标题?
PostgreSQL 8.4.13
main
条目(uid是连续的)
uid | title
-----+-------
1 | stuff
department
(departmentid是serial,uidref是上面的uid的外键)
departmentid | uidref | title
--------------+--------+-------
100 | 1 | Foo
101 | 1 | Bar
sub_category
部门(textid是连续的,departmentref对于以上的部门是外国的)
textid | departmentref | title
-------+---------------+----------------
1000 | 100 | Text for Foo 1
1001 | 100 | Text for Foo 2
1002 | 101 | Text for Bar 1
答案 0 :(得分:1)
您可以使用data-modifying CTEs在一个语句中完成所有操作(需要Postgres 9.1 或更高版本)。
您的主键为serial
列会使其更容易:
WITH m AS (
INSERT INTO main (<all columns except pk>)
SELECT <all columns except pk>
FROM main
WHERE uid = 1
RETURNING uid AS uidref -- returns new uid
)
, d AS (
INSERT INTO department (<all columns except pk>)
SELECT <all columns except pk>
FROM m
JOIN department d USING (uidref)
RETURNING departmentid AS departmentref -- returns new departmentids
)
INSERT INTO sub_category (<all columns except pk>)
SELECT <all columns except pk>
FROM d
JOIN sub_category s USING (departmentref);
将<all columns except pk>
替换为您的实际列。 pk
适用于primary key
,例如main.uid
。
查询不返回任何内容。你可以几乎返回任何东西。你没有指明任何东西。
你不会称之为“复制”。该术语通常用于保持多个数据库实例或对象同步。您只是复制一个条目 - 并依赖于递归的对象。
除了命名惯例外:
使用命名约定会更简单,该约定标记所有列,表示“表foo的ID”,并带有相同的(描述性)名称,如foo_id
。还有其他的命名约定,但这是编写查询的最佳选择,IMO。