2017-04-11 22 views
2

我有一個多行node-postgres插入,給我的問題。這是一個參數化查詢,它使用公用表表達式來更新主表和兩個帶有外鍵的表。該查詢使用主表的參數,但是,當我嘗試對多行的外鍵表進行參數化時,會引發語法錯誤。

首先,我有這個函數接受一個數組並返回一串值。

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