JDBI using @bind for variables in queries inside quotes
Asked Answered
W

3

15

I'm wondering if/how this is possible, if it is, I'm sure its a simple fix that I can't seem to figure out

@SqlQuery("SELECT * FROM Table WHERE column LIKE '%:thingName%'")
public Set<Things> getThings(@Bind("thingName", String thingName)

Essentially for this toy example I am trying to select a row where a column contains [any text]thingName[anyText]. When using as above, I think the quotes obscure the bound variable so it literally looks for [any text]:thingName[anyText] and not my bound variable.

Thank you in advance, Madeline

Walling answered 31/5, 2013 at 21:8 Comment(1)
You should change the accepted answer to the concatenation solution. There is a way to do this without making code changes that may introduce a bug.Roof
G
13

It appears to be the case that you must add the '%' percentages to the bound variable:

@SqlQuery("SELECT * FROM Table WHERE column LIKE :thingName")
public Set<Things> getThings(@Bind("thingName") String thingName); // where thingName = "%" + thingName + "%"

See also: https://groups.google.com/forum/?fromgroups#!topic/jdbi/EwUi2jAEPdk

Quote from Brian McCallister

Using the :foo binding stuff creates a prepared statement and binds in the value for name in this case. You need the % to be part of the bound value, or you need to not use bindings to a prepared statement.

  • Approach 1 (the safer and generally better one): "select … from foo where name like :name" and bind the value ("%" + name)

  • Approach 2 (which opens you up to sql injection):

"select … from foo where name like '%' " and define("name", name) (or in sql object, (@Define("name") name) -- which puts name in as a literal in your statement.

The key thing is that the % character is part of the value you are testing against, not part of the statement.

Gullah answered 31/5, 2013 at 21:37 Comment(2)
Thank you for your reply! This is what I had done, I was hoping there was a better way out there but it seems not. - MadelineWalling
The answer below using a concatenation operation is a better answer as it doesn't require logical changes. If you're using postgres, you can do `'%' || :term || '%'Roof
T
24

I use concat to surround input with % signs while still using a bound variable to avoid SQL injection:

@SqlQuery("select * from atable where acolumn like concat('%',:thingName,'%')")
public Set getNames(@Bind("thingName") String thingName);
Thuggee answered 20/7, 2014 at 7:56 Comment(0)
G
13

It appears to be the case that you must add the '%' percentages to the bound variable:

@SqlQuery("SELECT * FROM Table WHERE column LIKE :thingName")
public Set<Things> getThings(@Bind("thingName") String thingName); // where thingName = "%" + thingName + "%"

See also: https://groups.google.com/forum/?fromgroups#!topic/jdbi/EwUi2jAEPdk

Quote from Brian McCallister

Using the :foo binding stuff creates a prepared statement and binds in the value for name in this case. You need the % to be part of the bound value, or you need to not use bindings to a prepared statement.

  • Approach 1 (the safer and generally better one): "select … from foo where name like :name" and bind the value ("%" + name)

  • Approach 2 (which opens you up to sql injection):

"select … from foo where name like '%' " and define("name", name) (or in sql object, (@Define("name") name) -- which puts name in as a literal in your statement.

The key thing is that the % character is part of the value you are testing against, not part of the statement.

Gullah answered 31/5, 2013 at 21:37 Comment(2)
Thank you for your reply! This is what I had done, I was hoping there was a better way out there but it seems not. - MadelineWalling
The answer below using a concatenation operation is a better answer as it doesn't require logical changes. If you're using postgres, you can do `'%' || :term || '%'Roof
T
0

enter image description here

This must be the case with LIKE while binding variables. As per JDBI doc(Here) using SQL query concatenation can solve the issue. It worked for me.

Treatment answered 19/10, 2022 at 13:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.