2014-02-13 113 views
2

我試圖拿現有的表並創建兩個。我有一個sections表,其中有一個file_url,現在我需要將其移至url字段media_files表中。另外,我想填充attachments表,該表充當has_many :through(在Rails中),這意味着它跟蹤media_file_idsection_id的外鍵關係。PostgreSQL插入到多個表中,使用第二次插入中的第一次插入的外鍵

,我已經得到最接近的是這樣的:

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

+0

的sqlfiddle會有所幫助。 –

回答

1

如果你想避免在第一個INSERT中應該使用DISTINCT子句的重複問題。這將使兩個部分指向相同的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

+0

在這種情況下,'DISTINCT'會讓我失去與'file_url'匹配的'sections'的關係。在這種情況下,我仍然想使用現有的'media_files'標識生成'attachments'行。 – gylaz

+0

@gylaz它不會,鏈接到相同文件(2,3)的部分指向與小提琴中所看到的相同的media_file。所以它的工作原理與你描述的完全一樣。 –

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

+0

這將創建模擬:http://sqlfiddle.com/#!15/6e9c8/1 –

+0

@JakubKania:是的,我正在考慮這個。但是,在'media_files'表中原來的插入內容已經存在,顯然這不是問題(或者gylaz沒有考慮它) –

+0

理想情況下,如果'sections'中有一個重複的'file_url' - 我想第一次創建一個'media_files'行,第二次遇到它時,從'media_files'中獲取現有的行。 – gylaz