2013-07-24 50 views
0

我已經看到了解決這個問題的其他問題,我知道PostgreSQL沒有內置的upsert,必須使用2種方法完成。這是我在Ruby中使用pg gem的代碼。Postgres Ruby中的Upsert

@db.exec_params("UPDATE crawled SET url = $1, timestamp = $2 WHERE url = $1",[url,DateTime.now]) 

@db.exec_params("INSERT INTO crawled (url, timestamp) VALUES ($1, $2) WHERE NOT EXISTS 
       (SELECT 1 FROM crawled WHERE url = $1)",[url,DateTime.now]) 

然而,當我運行此我得到一個語法錯誤

exec_params': ERROR: syntax error at or near "WHERE" (PG::Error) 
LINE 1: ...ERT INTO crawled (url, timestamp) VALUES ($1, $2) WHERE NOT ... 

哪裏是我的錯?

回答

0

只是看着你的例子我有兩個問題。

  1. 哪條線路導致錯誤?

  2. table應該被換成表名,不是嗎? http://www.postgresql.org/docs/8.2/static/sql-insert.html

+0

@ db.exec_params(「INSERT INTO表(URL,時間戳)VALUES($ 1,$ 2)WHERE NOT EXISTS (SELECT 1從表其中URL = $ 1)「,[url,DateTime.now]) 這就是導致錯誤的那一行。 2)是的你是對的,並在我的實際代碼表中被表名替換。我將更新我的問題以反映這一點。 –

+0

'INSERT INTO' +'WHERE'沒有意義。你想做一些像'INSERT INTO films SELECT * FROM tmp_films WHERE date_prod <'2004-05-07';'? – phoet

+0

我正在看[在這個問題上的第二個解決方案](http://stackoverflow.com/questions/1109061/insert-on-duplicate-update-postgresql) –

0

僞代碼:

# transaction 
query('BEGIN'); 

# find out if row already exists, and lock it if it does 
result = query('SELECT * FROM crawled WHERE url = $1 FOR UPDATE', [url]) 

# row exists, so update it 
if (result.rows > 0) { 
    query('UPDATE crawled SET timestamp = $2 WHERE url = $1', [url, DateTime.now]) 
} 

# row doesn't exist, insert 
else { 
    query('INSERT INTO crawled (url, timestamp) VALUES ($1, $2)', [url, DateTime.now]) 
} 

# commit transaction 
query('COMMIT');