db2 ignore case in where clause - java

Normally we perform the ignore case as follow:
select * from user where UPPER(username) = UPPER('maker1');
Is this any way to do it in where clause condition?
I understand that we can do as follow:
select * from user where UPPER(username) in ( UPPER('maker1'), UPPER(maker2) );
But how about do it in preparedStatement ?
For example:
sb.append( "AND functionType IN (:functionType) " );
map.put( "functionType",
command.getListValues( command.getAllNonTradeFunctionsList( ) ) );
query.setProperties( map );

what is the issue you are facing here is the simple example demonstrating your problem
String query =
"SELECT agent.familyname, agent.givenname"
+ " FROM agent"
+ " WHERE agent.agentid = ?"
+ " AND ("
+ " familyname ilike ? OR givenname ilike ?"
+ ") "
+ " ORDER by familyname";
pst.setInt(1, piececreation.agentid);
pst.setString(2, agent_lastname.toLowerCase());
pst.setString(3, agent_name.toLowerCase());
let't me know if any other help needed

Related

Java + JDBC: Prepared statement failing

I'm trying to make a prepared statement and the drivers are working how I assume they are supposed to but the only problem is that my query is no longer valid.
I'm trying to write this query:
SELECT ip_address
FROM log_activity
WHERE created_at
BETWEEN "2017-01-01 00:00:00"
AND DATE_ADD("2017-01-01 00:00:00", INTERVAL 1 HOUR)
GROUP BY ip_address
HAVING COUNT(*) > 200;
But after inserting the parameters for the prepared statement it comes out as:
SELECT ip_address
FROM log_activity
WHERE created_at
BETWEEN '\'2017-01-01 00:00:00\''
AND DATE_ADD('\'2017-01-01 00:00:00\'', INTERVAL 1 'hour')
GROUP BY ip_address
HAVING COUNT(*) > 200;
Which is no longer valid SQL. So how do I remove these quotations from the parameters or what is a good way to work around this?
...
String startDateArg = "'" + args[0].split("=", 2)[1].replace(".", " ") + "'";
String durationArg = args[1].split("=", 2)[1];
int thresholdArg = Integer.parseInt(args[2].split("=", 2)[1]);
String duration = durationArg.equals("hourly") ? "hour" : durationArg.equals("daily") ? "day" : null;
String getUsersOverAPILimitQuery = "" +
"select ip_address " +
"from log_activity " +
"where created_at " +
" between ?" +
" and date_add(?, interval 1 ?) " +
"group by ip_address " +
"having count(*) > ?;";
PreparedStatement preparedStatement = con.prepareStatement(getUsersOverAPILimitQuery);
preparedStatement.setString(1, startDateArg);
preparedStatement.setString(2, startDateArg);
preparedStatement.setString(3, duration);
preparedStatement.setInt(4, thresholdArg);
System.out.println(preparedStatement);
ResultSet getUsersOverAPILimit = preparedStatement.executeQuery();
while (getUsersOverAPILimit.next()) {
String ip_address = getUsersOverAPILimit.getString("ip_address");
System.out.println(ip_address);
}
...
Instead of this:
String startDateArg = "'" + args[0].split("=", 2)[1].replace(".", " ") + "'";
Do this:
String startDateArg = args[0].split("=", 2)[1].replace(".", " ");
no need to add in the single quotes, the preparedstatement does it for you.

Pageable in JPA native query

I want to use pagination with a native query. I use for this this syntaxe as in this example : Spring Data and Native Query with pagination
and it's my query:
#Query(value="SELECT rownum() as RN, users.num, users .l_service,service.type_service, users.date, " +
"chambre.price," +
"price* ( case when(datediff(day,date_d,date_f)=0) then 1 " +
"else datediff(day,date_d,date_f) end ) as Montant," +
"case when (service.type_service='R') and datediff(day,date_d,date_f) >=21 " +
"then (21300+(datediff(day,date_d,date_f)-21)*200)" +
"else price*(case when(datediff(day,date_d,date_f)=0) then 1 else datediff(day,date_d,date_f)end) end AS Montant_final " +
" users.year, users.Etat, " +
" from chambre JOIN users ON chambre.code = users.type " +
"JOIN service on service.code = users.l_service " +
" WHERE users.Etat='V' and RN between ?#{ #pageable.offset -1} and ?#{#pageable.offset + #pageable.pageSize order by users.num",
countQuery ="select count(*) from users ",nativeQuery = true)
Page<Object> getStatistiques(Pageable pageable);
I get this error :
Cannot mix JPA positional parameters and native Hibernate positional/ordinal parameters
This is the solution I found to my problem:
#Query(value="SELECT * from (SELECT ROW_NUMBER() OVER (ORDER BY users.num) as RN, users.num, users .l_service,service.type_service, users.date, " +
"chambre.price," +
"price* ( case when(datediff(day,date_d,date_f)=0) then 1 " +
"else datediff(day,date_d,date_f) end ) as Montant," +
"case when (service.type_service='R') and datediff(day,date_d,date_f) >=21 " +
"then (21300+(datediff(day,date_d,date_f)-21)*200)" +
"else price*(case when(datediff(day,date_d,date_f)=0) then 1 else datediff(day,date_d,date_f)end) end AS Montant_final " +
" users.year, users.Etat, " +
" from chambre JOIN users ON chambre.code = users.type " +
"JOIN service on service.code = users.l_service " +
" WHERE users.Etat='V') AS STA where RN between ?#{ #pageable.offset -1} and ?#{#pageable.offset + #pageable.pageSize} order by STA.num",
countQuery ="select count(*) from users ",nativeQuery = true)
Page<Object> getStatistiques(Pageable pageable);
I share it with you perhaps it can help someone else!

Java JDBC - invalid character, put printing query and using it in SQLDeveloper works

rootID, FSA and others are all generated earlier in the code.
PreparedStatement getPotentialParents;
sql = "SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM "
+ "(SELECT * FROM("
+ "SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID "
+ "FROM UNIQUE_CLINIC p "
+ "START WITH PARENT_ID IS NULL "
+ "CONNECT BY PRIOR UNIQUE_ID = PARENT_ID "
+ "ORDER BY ROOT_ID))" + "WHERE ROOT_ID <> " + rootID + " "
+ "AND (FSA = '" + FSA + "' "
+ "OR NAME IN (" + others + ") "
+ "OR ADDRESS_1 IN (" + others + ") "
+ "OR ADDRESS_2 IN (" + others + "));";
System.out.println(sql);
getPotentialParents = connection.prepareStatement(sql);
rs = getPotentialParents.executeQuery();
I get this error when this query is run, during execution: ORA-00911: invalid character
However, the printed SQL can be run on SQLDeveloper without errors:
SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM (SELECT * FROM(SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID FROM UNIQUE_CLINIC p START WITH PARENT_ID IS NULL CONNECT BY PRIOR UNIQUE_ID = PARENT_ID ORDER BY ROOT_ID))
WHERE ROOT_ID <> 10548 AND (FSA = 'null' OR NAME IN ('BRENNAN''S AWESOME PHARMACY #1', '38 SOLUTIONS DR', 'NULLNULLNULL') OR ADDRESS_1 IN ('BRENNAN''S AWESOME PHARMACY #1', '38 SOLUTIONS DR', 'NULLNULLNULL') OR ADDRESS_2 IN ('BRENNAN''S AWESOME PHARMACY #1', '38 SOLUTIONS DR', 'NULLNULLNULL'));
I'm guessing JDBC is doing something to the SQL String before querying. Any idea what might be causing this? How can I get the actual query?
I've made some updates and it's still not working, giving me an invalid character. Once again, the printed sql can be run in sqldev with no problem.:
String FSA = rs.getString("FSA");
String rootID = String.valueOf((rs.getInt("ROOT_ID")));
String others = "'" + rs.getString("NAME").replace("'", "''") + "', '" + rs.getString("ADDRESS_1").replace("'", "''") + "', '" + rs.getString("ADDRESS_2").replace("'", "''") + "'";
Statement getPotentialParents = connection.createStatement();
sql = "SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM "
+ "(SELECT * FROM("
+ "SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID "
+ "FROM UNIQUE_CLINIC p "
+ "START WITH PARENT_ID IS NULL "
+ "CONNECT BY PRIOR UNIQUE_ID = PARENT_ID "
+ "ORDER BY ROOT_ID)) " + "WHERE ROOT_ID <> " + rootID + " "
+ "AND (FSA = '" + FSA + "' "
+ "OR NAME IN (" + others + ") "
+ "OR ADDRESS_1 IN (" + others + ") "
+ "OR ADDRESS_2 IN (" + others + "));";
System.out.println(sql);
rs = getPotentialParents.executeQuery(sql);
You Can not use PreparedStatement like this .
You have to use setString() methods to set values in qyery.
otherwise user CreateStatement instead of PreparedStatement
Statement getPotentialParents;
sql = "SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM "
+ "(SELECT * FROM("
+ "SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID "
+ "FROM UNIQUE_CLINIC p "
+ "START WITH PARENT_ID IS NULL "
+ "CONNECT BY PRIOR UNIQUE_ID = PARENT_ID "
+ "ORDER BY ROOT_ID))" + "WHERE ROOT_ID <> " + rootID + " "
+ "AND (FSA = '" + FSA + "' "
+ "OR NAME IN (" + others + ") "
+ "OR ADDRESS_1 IN (" + others + ") "
+ "OR ADDRESS_2 IN (" + others + "));";
System.out.println(sql);
getPotentialParents = connection.createStatement(sql);
rs = getPotentialParents.executeQuery();
First, check that this gives the expected results in Oracle:
VARIABLE rootid NUMBER;
VARIABLE fsa VARCHAR2(20);
VARIABLE name VARCHAR2(20);
VARIABLE address1 VARCHAR2(200);
VARIABLE address2 VARCHAR2(200);
BEGIN
:rootid := 10548;
:fsa := 'null';
:name := 'BRENNAN''S AWESOME PHARMACY #1';
:address1 := '38 SOLUTIONS DR';
:address2 := 'NULLNULLNULL';
END;
/
SELECT UNIQUE_ID,
NAME,
ADDRESS_1,
ADDRESS_2,
POSTAL_CODE
FROM (
SELECT *
FROM (
SELECT p.*,
CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID
FROM UNIQUE_CLINIC p
START WITH PARENT_ID IS NULL
CONNECT BY PRIOR UNIQUE_ID = PARENT_ID
ORDER BY ROOT_ID
)
)
WHERE ROOT_ID <> :rootid
AND ( FSA = :fsa
OR NAME IN ( :name, :address1, :address2 )
OR ADDRESS_1 IN ( :name, :address1, :address2 )
OR ADDRESS_2 IN ( :name, :address1, :address2 )
);
If it does then you can just use the bind variables in Java:
(Note, you do not need the trailing ; for the query.)
String sql = "SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM ( SELECT * FROM ( SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID FROM UNIQUE_CLINIC p START WITH PARENT_ID IS NULL CONNECT BY PRIOR UNIQUE_ID = PARENT_ID ORDER BY ROOT_ID ) ) WHERE ROOT_ID <> :rootid AND ( FSA = :fsa OR NAME IN ( :name, :address1, :address2 ) OR ADDRESS_1 IN ( :name, :address1, :address2 ) OR ADDRESS_2 IN ( :name, :address1, :address2 ) )";
PreparedStatement ps=connection.prepareStatement( sql );
OraclePreparedStatement ops = (OraclePreparedStatement) ps;
ops.setStringAtName( "fsa", rs.getString("FSA") );
ops.setIntAtName( "rootid", rs.getInt("ROOT_ID") );
ops.setStringAtName( "name", rs.getString("NAME") );
ops.setStringAtName( "address1", rs.getString("ADDRESS_1") );
ops.setStringAtName( "address2", rs.getString("ADDRESS_2") );
ps.execute();

Why does the PrepareStatement not generate correct SQL query?

Below is my PrepareStatement code. It does not generate correct SQL-query.
Also it does not come beyond 1st println-statement. Also it says ** NOT SPECIFIED ** in the query (please see below).
How can we fix this, please?
ps1 = con.prepareStatement(
"select stuId, name, relationsName, houseAddress, houseNumber from temp where "
+ " stuId like '?%' and "
+ " sex = '?' and "
+ " name like '?%' and "
+ " age BETWEEN ? and ? and "
+ " relationsName like '?%' "
+ " order by name asc limit 0, 150000 "
);
System.out.println("ps1 Before : " + ps1);
output:
ps1 Before : com.mysql.jdbc.JDBC4PreparedStatement#14d55de: select
stuId, name, relationsName, houseAddress, houseNumber from temp where
stuId like '?%' and sex = '?' and name like '?%' and age BETWEEN **
NOT SPECIFIED ** and ** NOT SPECIFIED ** and relationsName like '?%'
order by name asc limit 0, 150000
It does not come beyond this point. Also it says NOT SPECIFIED in the query (please see to the end).
Any insights please?
ps1.setString(1, stuId);
ps1.setString(2, gender);
ps1.setString(3, name);
ps1.setInt(4, startAge);
ps1.setInt(5, endAge);
ps1.setString(6, relationsName);
System.out.println("ps1 After : " + ps1);
rs = ps1.executeQuery();
because the placeholders where enclosed with single quotes, thus making it a value an not a parameter anymore. you should get rid of it, eg
ps1 = con.prepareStatement(
"select stuId, name, relationsName, houseAddress, houseNumber from temp where "
+ " stuId like ? and "
+ " sex = ? and "
+ " name like ? and "
+ " age BETWEEN ? and ? and "
+ " relationsName like ? "
+ " order by name asc limit 0, 150000 "
);
for LIKE statement, you should concatenate the value in java, not in sql,
ps1.setString(1, stuId + '%');

Using '%' as a wild card character in a parameter in SQL with Java

So in my program I have:
private static final String GET_USERS_BY_PARAMS = "select * from user t "
+ "where t.id like %?% "
+ "AND t.name LIKE %?% "
+ "AND t.location LIKE %?% "
+ "AND t.telephone LIKE %?% ";
All of the parameters given above are stored as varchar in the database.
However when I run the following:
statement = connection.prepareStatement(GET_USERS_BY_SEARCH_PARAMS);
statement.setString(1, userID);
statement.setString(2, name);
statement.setString(3, location);
statement.setString(4, telephone());
rs = statement.executeQuery();
I get a SQL exception stating that there was an invalid character. The application throws the error on the executeQuery, so setting the params isn't an issue. I was wondering if this was down to using the % symbols, whihc I included so that you could search without having to input the exact user ID, name, or etc.
Thanks for any help in advance!
The wildcard has to be part of the value passed to the prepared statement. So you need something like this:
private static final String GET_USERS_BY_PARAMS = "select * from user t "
+ "where t.id like ? "
+ "AND t.name LIKE ? "
+ "AND t.location LIKE ? "
+ "AND t.telephone LIKE ? ";
statement = connection.prepareStatement(GET_USERS_BY_SEARCH_PARAMS);
statement.setString(1, "%" + userID + "%");
statement.setString(2, "%" + name + "%");
statement.setString(3, "%" + location + "%");
statement.setString(4, "%" + telephone() + "%");
Btw: what datatype is user.id?
If that is a numeric value, LIKE won't work correctly. You should probably explictely cast the ID to a character value instead: where to_char(t.id) like ?
use CONCAT function,it will works,like this: LIKE CONCAT('%', ?, '%')
or also you can use LIKE ('%' || ? || '%')
You can write with concatenation operator
LIKE ('%' || ? || '%')

Categories