PostgreSQL插入到多个表中,使用第二次插入时第一次插入的外键

时间:2014-02-13 20:37:01

标签: sql postgresql

我正在尝试使用现有的表并创建两个。我有一个sections表,其中有file_url,现在我需要将其移到url表的media_files字段中。另外,我想填充充当attachments(在Rails中)的has_many :through表,这意味着它会跟踪media_file_idsection_id的外键关系。

我得到的最接近的是:

WITH ids AS (
    INSERT INTO media_files (url, mimetype)
    SELECT file_url, 'image/jpeg'
    FROM sections
    WHERE file_url IS NOT NULL
    RETURNING id AS media_file_id, sections.id AS section_id
)
INSERT INTO attachments (media_file_id, section_id)
SELECT media_file_id, section_id
FROM ids

但是我收到了这个错误:

PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "sections"
LINE 6:         RETURNING id AS media_file_id, sections.id AS sectio...

这是有道理的,但我不确定如何抓住section_id

有没有办法让这个工作?也许有更好的替代方法?

修改:这是指向SQL Fiddle

的链接

2 个答案:

答案 0 :(得分:2)

我只能考虑在外部插入中使用额外的连接:

WITH ids AS (
    INSERT INTO media_files (url, mimetype)
    SELECT file_url, 'image/jpeg'
    FROM sections
    WHERE file_url IS NOT NULL
    RETURNING id AS media_file_id, url AS file_url
)
INSERT INTO attachments (media_file_id, section_id)
SELECT ids.media_file_id, s.id
FROM ids
  JOIN sections s ON s.file_url = ids.file_url;

SQLFiddle:http://sqlfiddle.com/#!15/6fcaf/4

答案 1 :(得分:1)

如果您想避免重复问题,请在第一个DISTINCT中使用INSERT子句。这将使两个部分指向相同的media_file,但它应该是好的。 (从@a_horse_with_no_name回复升级)

WITH ids AS (
    INSERT INTO media_files (url, mimetype)
    SELECT DISTINCT file_url, 'image/jpeg'
    FROM sections
    WHERE file_url IS NOT NULL
    RETURNING id AS media_file_id, url AS file_url
)
INSERT INTO attachments (media_file_id, section_id)
SELECT ids.media_file_id, s.id
FROM ids
  JOIN sections s ON s.file_url = ids.file_url;

Fiddle