递归复制条目

时间:2014-01-09 15:06:26

标签: sql postgresql duplicates common-table-expression recursive-query

我正在尝试复制一个条目。那部分并不难。棘手的部分是:有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 

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。