Java Named Query - java

I'm trying to create a Java named query which does the following postgres query:
select * from call_attempt where result is NULL and id like '0000000101%';
The 0000000101 is set to id in my code, so this is what I want to do, but it's malformed: (I'm not sure how to set the id field while using the % and it has to be inside ' ')
#NamedQuery(name = AttemptEntity.JQL.NOTENDED,
query = "SELECT ae FROM AttemptEntity ae WHERE ae.result IS NULL,"
+ " ae.correlationId LIKE '=:id%'")

First, you forgot the and, and replaced it by a comma.
Second, the % must be passed as part of the argument:
SELECT ae FROM AttemptEntity ae WHERE ae.result IS NULL
and ae.correlationId LIKE :id
And then, when executing the query:
String id = "0000000101%";
query.setParameter("id", id);

You can't have the % in the NamedQuery, but you can have it in the value you assign the parameter.
query.setParamter("id", 0000000101+ "%");
You also need to add AND and remove the comma after NULL.
Reference: Named Query with like in where clause

Related

Java dynamically generate SQL query - ATHENA

I am trying to generate sql query based on user input. There are 4 search fields on the UI:
FIRST_NAME, LAST_NAME, SUBJECT, MARKS
Based on user input I am planning to generate SQL query. Input can be of any combination.
eg: select * from TABLE where FIRST_NAME="some_value";
This query needs to be generated when FIRST_NAME is given and other fields are null
select * from TABLE where FIRST_NAME="some_value" and LAST_NAME="some_value";
This query needs to be generated when FIRST_NAME and LAST_NAME are given and other fields are null
Since there are 4 input fields, number of possible queries that can be generated are 24 (factorial of 4).
One idea is to write if condition for all 24 cases.
Java pseudo code:
String QUERY = "select * from TABLE where ";
if (FIRST_NAME!=null) {
QUERY = QUERY + "FIRST_NAME='use_input_value';"
}
if (LAST_NAME!=null) {
QUERY = QUERY + "LAST_NAME='use_input_value';"
}
if (SUBJECT!=null) {
QUERY = QUERY + "SUBJECT='use_input_value';"
}
if (MARKS!=null) {
QUERY = QUERY + "MARKS='use_input_value';"
}
I am not able to figure out how to generate SQL queries with AND coditions for multiple Input values.
I have been through concepts on dynamically generate sql query but couldn't process further.
Can someone help me on this.
FYI: I have been through How to dynamically generate SQL query based on user's selections?, still not able to generate query string based on user input.
Let's think about what would happen if you just ran the code you wrote and both FIRST_NAME and LAST_NAME are provided. You'll wind up with this:
select * from TABLE where FIRST_NAME='use_input_value';LAST_NAME='use_input_value';
There are two problems here:
The query is syntactically incorrect.
It contains the literals 'use_input_value' instead of the values you want.
To fix the first problem, let's first add and to the start of each expression, and remove the semicolons, something like this:
String QUERY = "select * from TABLE where";
if (FIRST_NAME!=null) {
QUERY = QUERY + " and FIRST_NAME='use_input_value'";
}
Notice the space before the and. We can also remove the space after where.
Now the query with both FIRST_NAME and LAST_NAME will look like this:
select * from TABLE where and FIRST_NAME='use_input_value' and LAST_NAME='use_input_value'
Better but now there's an extra and. We can fix that by adding a dummy always-true condition at the start of the query:
String QUERY = "select * from TABLE where 1=1";
Then we append a semicolon after all the conditions have been evaluated, and we have a valid query:
select * from TABLE where 1=1 and FIRST_NAME='use_input_value' and LAST_NAME='use_input_value';
(It may not be necessary to append the semicolon. Most databases don't require semicolons at the end of a single query like this.)
On to the string literals. You should add a placeholder instead, and simultaneously add the value you want to use to a List.
String QUERY = "select * from TABLE where";
List<String> args = new ArrayList<>();
if (FIRST_NAME!=null) {
QUERY = QUERY + " and FIRST_NAME=?";
args.add(FIRST_NAME);
}
After you've handled all the conditions you'll have a string with N '?' placeholders and a List with N values. At that point just prepare a query from the SQL string and add the placeholders.
PreparedStatement statement = conn.prepareStatement(QUERY);
for (int i = 0; i < args.size(); i++) {
statement.setString(i + 1, args[i]);
}
For some reason columns and parameters are indexed starting at 1 in the JDBC API, so we have to add 1 to i to produce the parameter index.
Then execute the PreparedStatement.

What is the equivalent of '||' (concat) in Entitymanager java query?

I would like to rewrite an oracle stored procedure to java code, to select data with concatenated values in a query string to compare the following way:
Query qString =
"SELECT Obj " +
"FROM MyTable Obj2 WHERE ( Obj2.value1 || Obj2.value2 ) in " +
"(SELECT Obj2.value1 || MAX(Obj2.value2) FROM MyTable Obj2 WHERE Obj2.value2 >= :param GROUP BY Obj2.value1) " +
"ORDER BY Obj.value2, Obj.value1";
query = entityManager.createQuery(qString);
query.setParameter("param ", param );
When I run the query as a webservice on weblogic server I got error with the '|' character.
What can I use instead of the || operator to get the same result?
The Java Persistence Query Language provides the CONCAT() function, so you should be able to write Obj2.value1 || Obj2.value2 as CONCAT(Obj2.value1, Obj2.value2)

SQL search to return if several user inputs are empty

Here is my dillemma, I am trying to implement search for my website, and what I have is multiple comboboxes, and the user can select an option and press search, I do however want to at least return what exists based on their selection, i.e if they leave section blank, and only select semester, then I should have something in my result set, or if they select semester, and instructor, and leave the others blank, then I should have something in my result set, unfortunately its not working. Here is my Query.
SELECT *
FROM CoursesTaught c
WHERE c.Section = :section
AND c.CourseName=:courseName
AND c.Semester=:semeste
AND c.programName=:ProgramName
AND c.CoordinatorName=:coordinatorname
Essentially what I want to do is do a check that if empty, or "n/a" then rather than 'AND' do an 'OR' but I can't figure it out.
Probably easiest to use the union operator:
http://www.w3schools.com/sql/sql_union.asp
SELECT * FROM CoursesTaught c
WHERE c.Section = :section
union
SELECT * FROM CoursesTaught c
WHERE c.Semester=:semeste
Build your query dynamically depending on user selection. Similar question with answer how to do this in Java: How to dynamically generate SQL query based on user’s selections?
Unless you want to have a really ugly SQL query, you need to use a server side language to evaluate the user selections and build your query dynamically as a query string based on the users selection.
You can create query string manually i.e.
String query = "SELECT * FROM CoursesTaught c ";
String whereCondition = "";
if(!section.isEmpty)
if(whereCondition.isEmpty)
whereCondition = whereCondition + " AND c.Section = '" + section + "'";
else
whereCondition = "c.Section = '" + section + "'";
if(!courseName .isEmpty)
if(whereCondition.isEmpty)
whereCondition = whereCondition + " AND c.CourseName = '" + courseName + "'";
else
whereCondition = "c.CourseName = '" + courseName + "'";
.
.
.
if(!whereCondition.isEmpty)
query = query + whereCondition;
And you can pass query string to your executeQuery() method.
You'll probably see the best performance using the method suggested by Jared_S but you can do it with regular sql:
SELECT *
FROM CoursesTaught c
WHERE (c.Section = :section or :section is null)
AND (c.CourseName=:courseName or :courseName is null)
AND (c.Semester=:semester or :semester is null)
AND (c.programName=:ProgramName or :programName is null)
AND (c.CoordinatorName=:coordinatorname or :coordinatorName is null)
This assumes that the missing parameters are null, if not simply change the test to look for an empty string, assuming that's the parameter type.
One drawback to this approach is that you'll end up returning the entire table if all the parameters are null.

how to pass argument(Null) and Hard coded value in JOOQ

If I have a query which runs on SQL which is :
String contactWhere = " UNION SELECT FoldContact.FoldRSN,NULL PeopleRSNCode,'A' FileIndicator from People,Contact"
But how we pass NULL PeopleRSNCrypt and 'A' FIleIndicator in jooq. if we have
SelectQuery<Record> selectQuery = create.selectQuery();
selectQuery.addSelect(Contact.FOLD_CONTACT.FOLD_RSN);
Use Factory.value("A").as("FIleIndicator") and Factory.inline(null).as("PeopleRSNCrypt")

Hibernate #Formula is not supporting query contains 'CAST() as int' function

Following is the one of property of ExecutionHistory class, which value is fetched from
#Formula using JPA/Hibernate from exectution_history table,
#Formula("(SELECT SUM(dividend) || '/' || SUM(divisor) " +
"FROM (SELECT CAST(substr(sr.result, 1, position('/' in sr.result)-1 ) AS int) AS dividend ," +
"CAST(substr(sr.result, position('/' in sr.result)+1 ) AS int) AS divisor " +
"FROM suite_results as sr WHERE sr.execution_history=id) AS division)")
private String result;
When I tried to get instance of ExecutionHistory class, I found that above formula query
is converted by JPA/Hibernate like this:
select executionh0_.id as id7_1_, executionh0_.execution_plan as execution3_7_1_, executionh0_.start_time as start2_7_1_,
(SELECT SUM(sr.duration) FROM suite_results as sr WHERE sr.execution_history=executionh0_.id) as formula0_1_,
(SELECT SUM(executionh0_.dividend) || '/' || SUM(executionh0_.divisor) FROM
(SELECT CAST(substr(sr.result, 1, position('/' in sr.result)-1 ) AS executionh0_.int) AS executionh0_.dividend ,
CAST(substr(sr.result, position('/' in sr.result)+1 ) AS executionh0_.int) AS executionh0_.divisor
FROM suite_results as sr WHERE sr.execution_history=executionh0_.id) AS executionh0_.division) as
formula1_1_, executionp1_.id as id6_0_, executionp1_.build_number as
build2_6_0_, executionp1_.name as name6_0_, executionp1_.owner as owner6_0_, executionp1_.sut as sut6_0_,
executionp1_.wait_for_page_to_load as wait6_6_0_ from execution_history executionh0_
left outer join execution_plans executionp1_ on executionh0_.execution_plan=executionp1_.id where executionh0_.id=?
So the problem is that, here formula query contains "CAST() AS int", but during query conversion by Hibernate, it puts unnecessary table reference and execute it as "CAST() AS executionh0_.int" so it giving sql grammer exeception while execution.
I've no idea about how to avoid this problem, Can anybody help me in this?
Thanks.
It's an old question, but I'll post an answer anyway.
If you are using a SQL Server database, you can add double quotes around the type you are casting.
Something like this:
#Formula("CAST(FLOOR(CAST( dat_criacao AS \"float\")) AS \"datetime\")")
Don't know which database you're using, but in SQL Server you should use CONVERT rather than CAST in you Hibernate queries.

Categories