Specify separator on jooq groupConcatDistinct method - java

Is there a way to specify a custom separator for the method groupConcatDistinct in JOOQ? There is a second parameter for the method groupConcat but this one returns multiple times the same values, which I don't want.
Thanks!

Okay I found the answer, with groupConcatDistinct the separator is chained and not a parameter. Like this groupConcatDistinct(...).separator(", ")

This is just an oversight in API design. I've created a feature request here:
https://github.com/jOOQ/jOOQ/issues/7956
As always when working with jOOQ and you encounter a missing feature, you can resort to using plain SQL templating. E.g.
Field<String> f = DSL.field(
"group_concat(distinct {0}, ', ')",
SQLDataType.VARCHAR,
MY_COLUMN
);

Related

Usage of ? in native SQL query on jsonb

I need to fire a select query against Postgres jsonb column:
entityManager.createNativeQuery(
"select * from table where jsonbcol -> 'usernames' ? :un"
).setParameter("un", userName).getResultList()
Upon running the Exception is thrown:
org.hibernate.engine.query.ParameterRecognitionException: Mixed parameter strategies -
use just one of named, positional or JPA-ordinal strategy
I tried escaping like \\? and ?? but that didn't help.
How to do that call properly?
The proper escape sequence makes the query like this:
entityManager.createNativeQuery(
"select * from table where jsonbcol -> 'usernames' \\?\\? :un"
).setParameter("un", userName).getResultList()
The backslashes escape hibernate parameter detection, and the two question-marks are the JDBC escape.
There is an alternative solution that can turn out to be an elegant workaround. Postgres operator ? is based on the jsonb_exists() function, so instead of
where jsonbcol -> 'usernames' \\?\\? :un
you can use
where jsonb_exists(jsonbcol -> 'usernames', :un)
As the documentation says:
In JDBC, the question mark (?) is the placeholder for the positional parameters of a PreparedStatement. There are, however, a number of PostgreSQL operators that contain a question mark. To keep such question marks in a SQL statement from being interpreted as positional parameters, use two question marks (??) as escape sequence.

PreparedStatement IN clause Regexp alternative?

I came across the same issue as the author of this question (PreparedStatement IN clause alternatives?), and wondered if using mysql's REGEXP would be an elegant way of getting the same functionality of IN while using only one PreparedStatement for varying number of values to match? Some example SQL here to show what I am talking about:
SELECT first_name, last_name
FROM people
WHERE first_name REGEXP ?
Multiple values could be supplied using a string like "Robert|Janice|Michael". I did not see REGEXP mentioned anywhere in that post.
Technically, yes, it is an alternative.
Note, however, that using a regex for matching is less efficient that the in operator ; it incurs more work for the database, that needs to initialize the regex engine, and run it against each and every value (it cannot take advantage of an index).You might not notice it on small volumes, but as your data grows larger this might become an issue. So I would not recommend that as a general solution: instead, just write a few more code lines in your application to properly use the in operator, and use regexes only where they are truly needed.
Aside: if you want to match the entire string, as in does, you need to surround the list of values with ^ and $, so the equivalent for:
first_name in ('Robert', 'Janice', 'Michael')
Would be:
first name regexp '^(Robert|Janice|Michael)$'
Another approach:
FIND_IN_SET(name, 'Robert,Janice,Michael')
Yes, that could be substituted in. But it must be a commalist of the desired values. This also works for FIND_IN_SET(foo, '1,123,45'). Note that 12 will not match.

Querydsl Like Surprise

I have just dabbled into using Querydsl, and am thoroughly enjoying the improvement it brings to interacting with JPA.
One remaining question I have is why do you have to wrap a like parameter with %?
Have I improperly configured something? Considering there is a method for starts/endsWith, I assumed like(str) would automatically wrap my str.
But to my surprise I needed to do this: "%" + str + "%" to get what I had expected.
Why is that? Is there a better way?
Yes, there is. (At least in QueryDSL 4.1.3), there is a contains(String s) method and variants of it (containsIgnoreCase etc.). This is what you are looking for.
Like is there to do custom wildcard matching (the algorithm expect you to add the % characters by yourself and wherever you feel they are needed).
Apart from StartsWith / EndsWith which have implicit % characters.. there is Containing keyword which prepends and appends the % character. And this is what you are looking for here.
findByAttributeContaining(String charset);
Documentation example: spring jpa examples

How to escape special characters used in SQL query?

Is there a Java library for escaping special characters from a string that is going to be inserted into an SQL query.
I keep writing code to escape various things, but I keep finding some new issue trips me up. So a library that takes care of all or most of the possibilities would be very handy.
EDIT: I am using MySQL (if that makes any difference).
Well... jdbc. Pass the strings as parameters, and don't append them to the query string
A little bit more research points me to this:
http://devwar.blogspot.com/2010/06/how-to-escape-special-characters-in.html
Which suggests to use apache.commons.lang.StringEscapeUtils, I will try this out
I know this is a long time thread, but using the commonslang library there is a method called escapeSql(String). Also using prepared statement automatically escape the offending SQL character.

Android Single Quote In SQL With a LIKE StateMent

I am having problem querying single quote while using the sql LIKE statement
this is my SQL query for searching the MUSIC file in the SD CARD.
final Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
final String[] cursor_cols = {
MediaStore.Audio.Media.TITLE
};
where = MediaStore.Audio.Media.TITLE + " like ('%"+SomeSongTitle+"%')";
cursor = getContentResolver().query(uri, cursor_cols, where, null, null);
SomeSongTitle is some arbitrary input text that the a user input.
My Question is why when SomeSongTitle contains a single Quote(for example SomeSongTitle=don't), it crashes.
And How to fix it?
thankz for reading and hope to hear some solution from you guys =D. hehe
If you don't want to do String substitution you can use SQLiteDatabase.rawQuery to get your Cursor object. And then do something like:
String query = "select * from your_table_name where" + MediaStore.Audio.Media.TITLE + " like ('%?%')";
cursor = yourDB.rawQuery(query, new String[] {SomeSongTitle});
That should get around the quoting issue.
To fix it you need to replace the single quote with two single quotes. Try using something like...
SomeSongTitle = SomeSongTitle.replace("'", "''");
If you use bindings (?) for the argument(s) in the where clause, then you do not need and should not use any single quotes because the binding already takes care of that.
In particular, the second argument in a binding is an array of strings,
String[], providing one String for each ?. In the binding process, each of those Strings is treated by sql as if it has single quotes around it. Binding creates a compiled sql statement with variable substitution, so it is efficient to write your sql as a fixed String and binding rather than make a different statement each call.
You'll need to escape the single quote. There are much more sophisticated methods to do this, but an easy way to start is to simply to a find and replace in order to add a slash (\) before the quote mark so that it looks like this: (\').
You can read more about it SQL Injection. Specifically, look at the section on Mitigation.
Android's database API sits on top of sqlite. In its FAQ, you can see that to "escape" a single quote, you just use two single quotes. See here.

Categories