2016-05-24 10 views
8

Mam tabeli, która zawiera kolumnę danych ze strukturą podobną do następujących:JDBC Przygotowany parametr oświadczenie wewnątrz json

{"title": "some title", "objects": [{"id": "id1"}, {"id": "id2"}]} 

teraz chcę znaleźć wszystkie wiersze, które mają obiekt z konkretnym identyfikatorze w ich obiektów Array wewnątrz danych. Następująca kwerenda działa idealnie z konsoli psql:

SELECT id, data FROM table_name WHERE data->'objects' @> '[{"id": "id1"}]' 

jednak nie mogę uzyskać to do pracy jako przygotowanym oświadczeniu nad sterownikiem JDBC. wartość id powinno być parametrem, więc próbowałem to jako ciąg znaków, który jest przekazywany do connection.prepareStatement(query);:

"SELECT id, data FROM table_name WHERE data->'objects' @> '[{\"id\": ?}]'" 

tutaj, gdy próbuję ustawić argumenty otrzymuję ten wyjątek:

org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0. 

kiedy wypróbować jedną z poniższych argumentów jest ustawione prawidłowo:

"SELECT id, data FROM table_name WHERE data->'objects' @> [{\"id\": ?}]" 
"SELECT id, data FROM table_name WHERE data->'objects' @> [{'id': ?}]" 

ale wynik nie jest oczywiście prawidłowo sformatowany zapytania:

SELECT id, data FROM table_name WHERE data->'objects' @> [{"id": 'id1'}] 
SELECT id, data FROM table_name WHERE data->'objects' @> [{'id': 'id1'}] 

w obu przypadkach dostaję następujący wyjątek:

org.postgresql.util.PSQLException: ERROR: syntax error at or near "[" 

Jaka jest poprawna składnia, aby ustawić parametr wewnątrz JSON? Używam PostgreSQL 9.5

+0

Łańcuchy w języku SQL są rozdzielane pojedynczymi cudzysłowami, a nie podwójnymi cudzysłowami. – Leo

+0

spróbuj WYBIERZ identyfikator, dane z tabeli nazwa WHERE dane -> "obiekty" @>? gdzie ? is [{"id": "id1"}] – Leo

+0

nie wiesz, które masz na myśli, ale te pomijane to ciągi Javy przekazywane do 'connection.prepareStatement' – mohamnag

Odpowiedz

6

I rzeczywiście dotarła do ponad JDBC deweloperów w Github i po pewnych dyskusjach wydaje się, że obecnie najlepszym rozwiązaniem jest mieć przygotowaną instrukcję w następujący sposób:

String query = "SELECT id, data FROM table_name WHERE data->'objects' @> ?::jsonb"; 

i przekazać cały kryteriów jak stringified obiektu JSON dla parametru:

PreparedStatement st = connection.prepareStatement(query); 
st.setString(1, "[\"id\":" + "id1" + "]"); 
st.executeQuery(); 

ów nie idealne rozwiązanie, ale wydaje się, że najlepsza możliwa ze względu na brak możliwości serwera. Na koniec nie jest tak źle, jak (teoretycznie) nie ma ryzyka wstrzyknięcia SQL.

Więcej szczegółów na temat połączonego problemu Github.

+0

Dzięki za podzielenie się swoimi wnioskami. Skończyło się na tym samym podejściu. –

+0

nie ma problemu, to wydaje się być dość popularnym problemem, a najlepszym rozwiązaniem jest posiadanie szerszego zestawu selektorów po stronie serwera. pozwala, aby ludzie z Postgres usłyszeli nas. – mohamnag

Powiązane problemy