2017-04-11 5 views
2

문제가되는 다중 행 노드 - 포스트 그레스 삽입이 있습니다. 공통 테이블 식을 사용하여 기본 테이블과 외래 키가있는 두 테이블을 업데이트하는 매개 변수가있는 쿼리입니다. 쿼리는 기본 테이블에 대한 매개 변수와 함께 작동하지만 다중 행인 외래 키 테이블을 매개 변수화하려고하면 구문 오류가 발생합니다.

먼저이 함수는 배열을 사용하여 값의 문자열을 반환합니다.

const buildValues = (id, values) => { 
    return values 
     .map(val => "(" + id + ", '" + val + "', " + false + ")") 
     .join(", "); 
    }; 

여기 내 쿼리입니다 :

app.post('/api/saveperson', function (req, res) { 
    pg.connect(connectionString, (err, client, done) => { 

    const insertPerson = ` 
    WITH x AS (INSERT INTO people (title, notes, name) 
     VALUES ($1, $2, $3) 
     RETURNING personId 
    ), 
    b AS (
     INSERT INTO sports (personid, name, favorite) 
     VALUES $4) 
    INSERT INTO instructions (personid, name, favorite) 
    VALUES $5; 
    `; 

     client.query(insertPerson, 
      [ req.body.title 
      , req.body.notes 
      , req.body.name 
      , queries.buildValues("SELECT personId FROM x", req.body.sports) 
      , queries.buildValues("SELECT personId FROM x", req.body.instructions) 
      ] 
     ) 
      .then(() => client.end()) 
      .catch(err => console.log(err)); 
    }); 
    return res.json(req.body); 
}); 
+0

스포츠에 삽입 할 열 수는 아직 3 단 하나의 값 ($ 4), 지침 같은 ... –

+0

이 문제에 접근하는 더 나은 방법이 있나요 ? 알 수없는 길이의 배열 두 개가 추악해질 수 있으므로 함수를 반복 사용하여 (예 : $ 4, $ 5, $ 6 ...) 사용하고 싶습니다. – Matt

+0

위의 코드에서 'client.query (insertRecipe')를'client.query (insertPerson ' –

답변

1

이 최선의 해결책이다,하지만 난 pg-promise 라이브러리 대신 pg의를 사용하여 종료하는 경우 확실하지. 그럼 거래와 체인으로 연결된 쿼리를 사용 :

db.tx(t => { 
     // BEGIN has been executed 
     return t.one(
      `INSERT INTO people (title, notes, name) 
      VALUES ($[title], $[notes], $[name]) 
      RETURNING personid`, req.body) 
      .then(data => { 
      let sportsQueries = req.body.sports.map(sport => { 
       return t.none(`INSERT INTO sports (personid, name) 
          VALUES ($1, $2)`, [data.personid, sport]);  
      }); 

      let instructionsQueries = req.body.instructions.map(ins => { 
       return t.none(`INSERT INTO instructions (personid, instruction) 
          VALUES ($1, $2)`, [data.personid, ins]); 
      }); 

      return t.batch(sportsQueries.concat(instructionsQueries)); 

      }); 
    }) 
    .then(data => { 
     // Success, and COMMIT has been executed 
    }) 
    .catch(error => { 
     // Failure, and ROLLBACK has been executed 
    }) 
+0

이 모양이 맞습니다. 고성능 버전의 경우 [pg-promise가있는 다중 행 삽입] (http://stackoverflow.com/questions/37300997/)을 참조하십시오. multi-row-insert-with-pg-promise), 즉 각각의 삽입 세트를 하나의 쿼리로 생성 할 수 있으므로 트랜잭션이 훨씬 빨라집니다.) –

+0

감사합니다! – Matt