2012-09-08 38 views
5

我想使用node-postgres模塊在postgres中創建一個「準備好的語句」。我想創建它,而不綁定到參數,因爲綁定將發生在循環中。node-postgres:如何在不執行查詢的情況下準備語句?

documentation我讀:

query(object config, optional function callback) : Query 
If _text_ and _name_ are provided within the config, the query will result in the creation of a prepared statement. 

我試圖

client.query({"name":"mystatement", "text":"select id from mytable where id=$1"}); 

但是當我嘗試只通過文字&名鍵的配置對象,我得到一個異常:

(已翻譯)消息綁定了0個參數,但準備好的語句期望1

有什麼我失蹤?你如何創建/準備一份陳述,而不將其綁定到具體的價值,以避免在循環的每一步重新準備陳述?

回答

9

我剛剛發現了node-postgres的作者answer on this issue

使用node-postgres第一次發出命名查詢時,它是一次性解析,綁定和執行的 。每個後續查詢在具有相同名稱的同一連接上發出的 將自動跳過 「解析」步驟,只重新綁定並執行已計劃的查詢。

當前node-postgres不支持創建已命名的 準備好的查詢並且不執行查詢的方式。此功能在libpq和客戶機/服務器協議(由純粹的 javascript綁定使用)內支持 ,但我沒有直接將其暴露在API中。 I 認爲它會增加API的複雜性而沒有任何真正的好處。 由於命名語句被綁定到創建它們的客戶端 ,如果客戶端斷開連接並重新連接或從客戶端池返回不同的 客戶端,則命名語句將不再工作 (它需要重新解析)。

2

更新:再次讀你的問題,這是我相信你需要做的。你還需要傳遞一個「值」數組。

只是爲了澄清;在那裏你通常會「準備」你的查詢,只需準備你傳遞給它的對象,而不需要value數組。然後,在通常「執行」查詢的位置,在對象中設置值數組並將其傳遞給查詢。如果這是第一次,那麼驅動程序會在第一次爲你做實際的準備工作,並簡單地爲迭代的其餘部分進行綁定和執行。

+0

與解決方案的問題是,準備的語句將在創建時使用了「任何」值來執行。使用循環的第一次迭代來創建它也感覺很尷尬 –

+0

這就是我設計API的方式,至少這是我通過閱讀文檔並在我自己的項目中使用它所得到的結果。API需要你在需要使用它的時候創建你的查詢對象,然後它會根據它是否知道你已經在'text'中輸入的內容來確定是否需要準備一個語句。 –

0

您可以使用pg-prepared爲:

var prep = require('pg-prepared') 

// First prepare statement without binding parameters 
var item = prep('select id from mytable where id=${id}') 

// Then execute the query and bind parameters in loop 
for (i in [1,2,3]) { 
    client.query(item({id: i}), function(err, result) {...}) 
} 
+0

'pg-prepared'做的事情與OP所要求的不同。它可以在查詢中使用指定的佔位符。 –

+0

OP希望在創建時不創建綁定參數值的情況下創建預準備語句。這就是pg-prepared中的例子。首先,您創建語句而不綁定參數值並將其存儲在var項目中。然後你用參數調用它。所以OP可以通過創建沒有變量綁定的語句來使用它,然後用循環中的參數值來調用它。 – pihvi

+1

在你的情況下,*數據庫*必須反覆準備查詢。 OP想要的只是通過準備一次stmt來減輕db。根據已接受的答案,如果pg-prepared爲查詢賦予唯一的「名稱」屬性,則可以達到此目的 - cf https://github.com/brianc/node-postgres/wiki/Prepared-Statements –

相關問題