2014-11-20 34 views
1

我試圖填充測試數據庫與一個非常具體的集成測試一組對象,我使用返回的ID從作爲查詢的一個有麻煩後續對象的字段的值。鏈接SQL查詢的WITH子句,最終執行更新

-- create a user with an account with salesforce integration 
WITH p AS (
     INSERT INTO person (email, confirmed, first_name, last_name) VALUES 
     ('[email protected]', TRUE, 'Salesforce', 'Guy') 
     RETURNING id 
    ), 
    ac AS (
     INSERT INTO account (subscription_type, subscription_expires_on, salesforce_integration) VALUES (0, '2024-10-10', TRUE) 
     RETURNING id 
    ), 
    am AS (
     INSERT INTO account_member (person_id, account_id, admin) VALUES 
     ((SELECT p.id FROM p), (SELECT ac.id FROM ac), TRUE) 
     RETURNING account_id, person_id 
    ), 
    la AS (
     -- create a salesforce linked_account 
     INSERT INTO linked_account (person_id, provider_id, access_token) VALUES 
     ((SELECT p.id FROM p), 'salesforce', '00DC00000016x37!AQIAQIt5EpCIgTFl9hg2qF9Ed6vzLJmTg9Nrd.uxvVva5WaxzMChn4sBBgV6KXiICCBoJgcFYbrTqpFtFJwpd.B7fe5kG9_z') 
     RETURNING id 
    ), 
    v AS (
     -- create a video and take 
     INSERT INTO video (person_id, account_id) VALUES 
     ((SELECT p.id FROM p), (SELECT ac.id FROM ac)) 
     RETURNING id 
    ), 
    t AS (
     INSERT INTO take (video_id, key, duration, state, thumbnail_selected) VALUES 
     ((SELECT v.id FROM v), 'g1/g1546ad07eff44c397e356be7c4bea49/g1546ad07eff44c397e356be7c4bea49', 35, 2, 1) 
     RETURNING id 
    ) 
    -- update video with selected take 
    UPDATE video SET selected_take_id = (SELECT id FROM take WHERE take.video_id=video.id); 

我遇到了在測試運行時,它指出的問題是(V),我創建不具有selected_take_id集視頻,這意味着查詢「有選擇的取更新的視頻」在底部實際上並沒有工作。

重要的是要注意,當這個腳本運行時,這個數據庫不是空的,還有2個其他類似的種子文件在這之前運行,所以至少有2個視頻,2個等已經存儲在數據庫中。如果有人知道如何做這個工作,而不必提供靜態ID作爲外鍵的值,它會爲我節省大量的時間。

謝謝!

+0

你能否提供相關的模式,也許作爲一個http://sqlfiddle.com/? – 2014-11-21 01:31:51

+0

我想通了,但感謝花時間閱讀! – 2014-11-21 16:17:10

回答

2

它看起來像你期待UPDATE(以下簡稱「主查詢」)找到插在同一個SQL語句的行,即不會在聲明的開頭存在的行。

與子語句彼此 並與主查詢併發執行:

如果是這樣的話,這不能作爲記錄在Data-Modifying Statements in WITH工作。因此,在WITH中使用數據修改 語句時,指定更新實際發生的順序是不可預知的。所有語句都具有相同 快照執行(見第13章),所以他們無法「看到」彼此的對目標表 。這減輕了 不可預見性行更新的實際順序的影響,並表示 返回數據是 與子報表不同,主查詢

你可能想之間通信的改變的唯一途徑使用DO block而不是在pl/pgsql中以程序形式列出的幾個查詢。

+0

謝謝@ Daniel-Vérité。這是發生了什麼事情,因爲如果我在psql命令行中運行同樣的查詢兩次,它會從第一次調用更新take ...我想我只需要在嘗試運行該更新之前完成插入查詢。 – 2014-11-21 16:15:17