2014-11-20 1 views
1

매우 구체적인 통합 테스트를 위해 많은 수의 개체가있는 테스트 DB를 채우려는 중 하나에서 쿼리의 반환 된 ID를 사용하는 데 문제가 있습니다. 후속의 오브젝트의 필드의 값WITH 절에 SQL 쿼리를 연결하여 결국 업데이트를 수행합니다.

-- 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); 

나는 시험이 상태 실행시에 실행하고 문제가 하단에 질의하는 "선택 테이크와 업데이트 비디오"를 의미 나는 selected_take_id가 설정되어 있지 않습니다 생성 (V) 비디오, 실제로 작동하지 않았다.

이 스크립트가 실행될 때이 DB가 비어 있지 않다는 것을 알아 두어야합니다. 이렇게하기 전에 실행되는 2 개의 유사한 시드 파일이 있으므로 적어도 2 개의 비디오, 2 개의 테이크 등이 이미 db에 저장되어 있습니다. 누구든지 외래 키에 대한 값으로 정적 ID를 제공 할 필요없이이 작업을 수행하는 방법을 알고 있다면 시간이 많이 절약됩니다.

감사합니다.

+0

관련 스키마를 제공 할 수 있습니까? 예 : http://sqlfiddle.com/? –

+0

나는 그것을 알아 냈다. 그러나 읽는 데 시간을내어 줘서 고마워! –

답변

2

UPDATE ("기본 쿼리")가 동일한 SQL 문에 삽입 된 행을 찾길 기대하는 것처럼 보입니다.이 문은 명령문의 시작 부분에 존재하지 않는 행입니다. 에

하위 문 서로 와 메인 쿼리와 동시에 실행됩니다 : 그런 경우에는 Data-Modifying Statements in WITH에 설명 된대로

이 작동하지 않을 수 있습니다. 따라서 WITH 수정 문 을 사용할 때 지정된 업데이트가 실제로 수행되는 순서는 예측할 수 없습니다. 모든 문은 동일한 스냅 샷 (13 장 참조)으로 실행되므로 의 서로 다른 효과를 볼 수 없습니다. 이 행 업데이트의 실제 순서의 예측 불가능의 영향을 완화하고, 의 반품 데이터를 부속 명령문 서로 다른 및

당신은 아마 원하는 메인 쿼리 사이에 변화를 통신 할 수있는 유일한 방법임을 의미 대신 pl/pgsql의 절차 형식으로 배치 된 여러 개의 쿼리를 사용하여 DO block을 사용하십시오.

+0

감사합니다. @ Daniel-Vérité. 그것은 psql 커맨드 라인에서 같은 쿼리를 두 번 실행하면 첫 번째 호출에서 테이크를 업데이트하기 때문에 일어나는 일을 정의한 것이다 ... 나는 그 업데이트를 실행하기 전에 삽입 쿼리를 끝내기 만하면되기 때문이다. –