Jdbi: BindList tidak dapat menemukan parameter bernama saya dalam kueri dan memberikan pengecualian

Dibuat pada 1 Feb 2018  ·  4Komentar  ·  Sumber: jdbi/jdbi

Saya mendapat SQL Query dengan parameter bernama :featureIds

const val selectGeoCoordinates = "SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN (:featureIds);"

Ketika saya mencoba mengikat daftar Int ke parameter bernama

val values: List<Int> = listOf(4138, 1752, 1161, 371, 1860, 5498)
val geoCoordinatesList = geo.withHandle<List<GeoCoordinates>, Exception> { handle ->
                handle.createQuery(selectGeoCoordinates).bindList("featureIds", values)
                        .mapTo<GeoCoordinates>().list()
            }

Saya mendapatkan pengecualian berikut pada eksekusi:

    Caused by: org.jdbi.v3.core.statement.UnableToExecuteStatementException: Unable to execute, no named parameter matches 'featureIds'. [statement:"SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN :featureIds ;", rewritten:"SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN :featureIds ;", parsed:"ParsedSql{sql='SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN ? ;', parameters=ParsedParameters{positional=false, parameterNames=[featureIds]}}", arguments:{ positional:{}, named:{__featureIds_0:4138,__featureIds_4:1860,__featureIds_3:371,__featureIds_2:1161,__featureIds_1:1752,__featureIds_5:5498}, finder:[]}]
    at org.jdbi.v3.core.statement.ArgumentBinder.lambda$bindNamed$0(ArgumentBinder.java:58)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at org.jdbi.v3.core.statement.ArgumentBinder.bindNamed(ArgumentBinder.java:57)
    at org.jdbi.v3.core.statement.ArgumentBinder.bind(ArgumentBinder.java:27)
    at org.jdbi.v3.core.statement.SqlStatement.internalExecute(SqlStatement.java:1443)
    at org.jdbi.v3.core.result.ResultProducers.lambda$getResultSet$2(ResultProducers.java:59)
    at org.jdbi.v3.core.result.ResultIterable.lambda$of$0(ResultIterable.java:53)
    at org.jdbi.v3.core.result.ResultIterable.stream(ResultIterable.java:141)
    at org.jdbi.v3.core.result.ResultIterable.collect(ResultIterable.java:197)
    at org.jdbi.v3.core.result.ResultIterable.list(ResultIterable.java:186)

Jika saya menggunakan .bind("featureIds", 4138) berhasil, oleh karena itu saya menganggap penamaan itu benar.

Ada yang punya ini? Bantuan apa pun diterima karena saya benar-benar bingung dengan yang ini :(

Komentar yang paling membantu

Oke... Saya menemukan solusi saat mencoba StringTemplateEngine. Ketika saya meletakkan parameter untuk daftar di <> itu berfungsi.
"SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN (<featureIds>);"

.bindList("featureIds", values) berfungsi.

Mungkin tambahkan ini ke dokumentasi dan berikan contoh untuk bindList ? :)

Semua 4 komentar

Oke... Saya menemukan solusi saat mencoba StringTemplateEngine. Ketika saya meletakkan parameter untuk daftar di <> itu berfungsi.
"SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN (<featureIds>);"

.bindList("featureIds", values) berfungsi.

Mungkin tambahkan ini ke dokumentasi dan berikan contoh untuk bindList ? :)

Yap, bindList sebenarnya memperluas mendefinisikan <featureIds> sebagai misalnya :__featureIds_0, :__featureIds_1, ...etc dan mengikat elemen daftar ke variabel pengganti tersebut.

Jika Anda menggunakan Postgres, Anda dapat mengikat daftar sebagai array SQL menggunakan where featureIds = any(:featureIds) dalam kueri dan menggunakan bindByType("featureIds", featureIds, new GenericType<List<Long>>() {}) .

Bukan untuk menjadi zombie, tetapi ketika menggunakan bindMap dengan Map<String, Object> untuk siapa kunci tunggal berisi List , ini sepertinya tidak berhasil. Tampaknya parameter seperti itu perlu diikat secara terpisah dari peta dengan bindList . Apakah ini akurat?

Contoh:

  a,b,c
from
  table
where
  a = :some_string
  and b = ANY(<list_of_strings>)

Dengan mengikat:

.bindMap(Map.of(
  'some_string', 'foobar',
  'list_of_strings', Lists.newArrayList('q', 'r', 's')
))

Akan memicu:

org.jdbi.v3.core.statement.UnableToCreateStatementException: Undefined attribute for token '<list_of_strings>' 

Itu benar. bindMap hanya mengikat argumen, sedangkan bindList juga perlu mendefinisikan atribut agar templating berfungsi seperti yang diharapkan. Mereka tidak diatur untuk bekerja sama, meskipun itu mungkin saja berubah di masa depan.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat