2012-09-08 8 views
5

Chcę utworzyć "przygotowaną instrukcję" w postgresie przy użyciu modułu node-postgres. Chcę go utworzyć bez wiązania go z parametrami, ponieważ powiązanie odbędzie się w pętli.node-postgres: jak przygotować instrukcję bez wykonywania zapytania?

W documentation czytam:

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. 

Próbowałem

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

ale gdy próbuję przechodzącą tylko klucze tekstowe Nazwa & w obiekcie konfiguracyjnym, otrzymuję wyjątek:

(przetłumaczony) komunikat jest wiążący 0 parametrów, ale przygotowana instrukcja oczekuje 1

Czy jest coś, czego mi brakuje? Jak utworzyć/przygotować wyciąg bez wiązania go z określoną wartością, aby uniknąć ponownego przygotowania instrukcji na każdym etapie pętli?

Odpowiedz

9

Właśnie znalazłem answer on this issue przez autora node-postgres.

Po pierwszym zgłoszeniu nazwanym zapytaniem jest ono analizowane, wiązane i wykonywane jednocześnie. Każde kolejne zapytanie wydane w tym samym połączeniu o tej samej nazwie automatycznie pominie krok "analizy" i tylko ponownie powiąże i wykona już zaplanowane zapytanie.

Obecnie węzeł-Postgres nie obsługuje sposobu przygotowania nazwanego, przygotowanego zapytania i nie wykonuje zapytania. Ta funkcja jest obsługiwana w obrębie biblioteki libpq oraz protokołu klient/serwer (używanego przez czyste połączenia JavaScript javascript ), ale nie ujawniłem jej bezpośrednio w interfejsie API. I pomyślałem, że to może dodać złożoności API bez żadnych rzeczywistych korzyści. Ponieważ instrukcje nazwane są powiązane z klientem, w którym są utworzone , jeśli klient jest odłączony i podłączony ponownie lub inny klient jest zwracany z puli klientów, podana instrukcja nie będzie dłużej działać (wymaga ponownego przetworzenia).

2

Aktualizacja: Czytanie pytania ponownie, oto co uważam za konieczne. Musisz także przekazać tablicę "wartości".

Tylko w celu wyjaśnienia; gdzie normalnie "przygotujesz" zapytanie, po prostu przygotuj obiekt, który mu przekażesz, bez tablicy wartości. Następnie, gdzie normalnie "wykonasz" zapytanie, ustaw tablicę wartości w obiekcie i przekaż ją do zapytania. Jeśli jest to pierwszy raz, sterownik wykona rzeczywiste przygotowanie dla ciebie za pierwszym razem i proste do wykonania wiązanie i wykonanie dla reszty iteracji.

+0

Problem z tego rozwiązania jest to, że przygotowana instrukcja zostanie wykonana z wartościami „Cokolwiek” użytych w czasie tworzenia. Czuję również akward, aby użyć pierwszej iteracji pętli do stworzenia –

+0

Tak właśnie zaprojektowano API, przynajmniej to jest to, co otrzymałem od czytania dokumentów i korzystania z nich w jednym z moich własnych projektów.Interfejs API oczekuje, że utworzysz obiekt zapytania, gdy będziesz go potrzebować, a następnie zdecyduje, czy musi przygotować instrukcję, czy też nie, zależnie od tego, czy wie o tym, co już wstawiłeś w "tekście". –

0

Można użyć pg-prepared na to:

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' robi coś innego niż to, o co prosi OP. daje możliwość używania nazwanych obiektów zastępczych w zapytaniach. –

+0

OP chce utworzyć gotowe wyciągi bez wiązania wartości parametrów podczas tworzenia. Tak dzieje się na przykładzie z przygotowanym pg. Najpierw należy utworzyć instrukcję bez wiązania wartości parametrów i zapisać ją w elemencie var. Następnie wywołujesz go z parametrami. Zatem OP może tego użyć, tworząc instrukcję bez wiązania zmiennych, a następnie wywołać ją z wartościami parametrów w pętli. – pihvi

+1

w twoim przypadku * baza * musi przygotować zapytanie ponownie. tym, co OP chce, jest złagodzenie db poprzez przygotowanie testu tylko raz. Zgodnie z zaakceptowaną odpowiedzią, pg-ready może osiągnąć ten cel, podając unikalny atrybut "nazwa" dla zapytania - cf https://github.com/brianc/node-postgres/wiki/Prepared-Statements –