How to write prepared statements for this query? - java

Hi i have written a join query for my app and its working. My next requirement is to convert that query to prepared statement where I am stuck.
"SELECT * FROM " + TableA.TABLE + " as d LEFT JOIN " + TableB.TABLE + " as c ON d."+ TableA.DAMAGECODE + "=c." + TableB.DAMAGECODE + " AND d."
+ TableA.INDEX + "=c." + TableB.DAMAGECODEINDEX + " AND d."
+ TableA.OBJECTTYPE + "=c." + TableB.OBJECTCLASS + " WHERE d."+ TableA.LEAF + " = '1' AND d." + TableA.OBJECTTYPE + " = ? AND " + "(d."+ TableA.DAMAGECODE + " LIKE ? OR d." + TableA.DAMAGETEXT + " LIKE ?) AND c." + TableB.CONSTRUCTIONSERIES + " = ? ORDER BY " + TableA.DAMAGETEXT;
cursor = db.rawQuery(sql,new String[]{String.valueOf(objectClass),"'%" + query + "%'","'%" + query + "%'",constructionSeries});
When i ran raw query i am getting results ,but when ran the above prepared statements i am getting cursor count always zero

You don't need to add the ' yourself when you pass a String parameters, the PreparedStatement will manage those itself.
"'%" + query + "%'"
For the moment you have condition like
where columnA = "'%somethingToFind%'"
So unless you have a value in columnA like 'somethingToFindInColumnA' (note the quote at the begin and the end of that String). You will never get a result.
Remove those to get something like :
"%" + query + "%"
Full answer :
db.rawQuery(sql,new String[]{String.valueOf(objectClass),"'%" + query + "%'","'%" + query + "%'",constructionSeries});
Become :
db.rawQuery(sql,new String[]{String.valueOf(objectClass),"%" + query + "%","%" + query + "%",constructionSeries});

Related

UNION in Spring data JPA native query two table

I have a requirement where i need to fetch number of record both the table using JPA native UNION query for Pagination
table 1=>txrh_bcaterms
table 2=> txrm_bcaterms
Ex: txrh_bcaterms UNION txrm_bcaterms
In Below code i am trying to fetching the record in both table Using UNION
#Query(nativeQuery = true,value= "SELECT "
+ " customerid, "
+ "finance_type, "
----------
-------etc----
+ "institution, "
+ "limit_groupid, "
+ "tx_booking_location, "
+ "finance_tenor_days, "
+ "margin_type , "
+ "additional_margin_percentage, "
+ "margin_percentage, "
+ "stale_document_condition_proforma_fin, "
+ "customer_name "
+ "from "
+ "txrh_bcaterms "
+ "where "
+ " institution=:institution "
+ "AND tx_booking_location=:txBookingLocation "
+ "OR finance_type=:financeType "
+ "OR customerid=:customerID "
+ "OR limit_groupid=:limitGroupID "
+ "UNION "
+ "SELECT "
+ "customerid, "
+ "finance_type, "
----------
-------etc----
+ "institution, "
+ "limit_groupid, "
+ "tx_booking_location, "
+" finance_tenor_days, "
+ "margin_type, "
+ "additional_margin_percentage, "
+ "margin_percentage, "
+ "stale_document_condition_proforma_fin, "
+ "customer_name "
+ "from txrm_bcaterms "
"
+ " institution=:institution "
+ "AND tx_booking_location=:txBookingLocation "
+ "OR finance_type=:financeType "
+ "OR customerid=:customerID "
+ "OR limit_groupid=:limitGroupID "
)
Page<Map<String,Object>> historyAndMaster(#Param("institution") String institution, #Param("txBookingLocation") String txBookingLocation,
#Param("financeType") String financeType, #Param("customerID") String customerID, #Param("limitGroupID") String limitGroupID, Pageable page);
NOTE:Actually stepid is the primary key txrh_bcaterms table and stepid is not there txrm_bcaterms table
ERROR
-------
in ui i passed institution =BC/AC/EC then UNION query able to execute and getting data
but if i passed SC then getting below exception
Caused by ERROR: each UNION query must have the same number of columns
Position: 581
at org.axonframework.axonserver.connector.ErrorCode.lambda$static$15(ErrorCode.java:107)
... 9 common frames omitted
=>If there is no same number of columns then how it is worked BC/AC/EC
I am new the Spring Data JPA Could you please help me to resolve this issue
Any other better suggestion welcome!

JDBC query returning zero when using simple arithmetic operations and alias even though the data in table is not zero

I am building a web portal through android and a query i am running through JDBC drivers is returning 0 where data should not be zero.
This is the query:
ResultSet set = statement.executeQuery("select it.itcod, it.itnam, it.packn, it.tradp, " +
"sum(nvl(itd.slbox,0) - nvl(itd.srbox,0) - nvl(itd.brbox,0) - nvl(itd.gsbox,0)) as sbox, " +
"sum(nvl(itd.slbbx,0) - nvl(itd.srbbx,0) - nvl(itd.brbbx,0) - nvl(itd.gsbbx,0)) as sbbx, " +
"SUM(NVL(itd.PRBOX,0) - NVL(itd.RPBOX,0) - NVL(itd.TRBOX,0)) as pbox, " +
"SUM(NVL(itd.PRBBX,0) - NVL(itd.RPBBX,0) - NVL(itd.TRBBX,0)) as pbbx " +
"from items it " +
"LEFT join item_daily itd " +
"on (it.cocod = itd.cocod " +
"and it.itcod = itd.itcod " +
"and ITD.ddate between " + fdate + " and " + tdate + ")" +
"WHERE IT.COCOD = " + COCOD +
"AND IT.DCODE = " + DCODE +
"AND NVL(IT.FREZE,'N')!='Y' " +
"group by it.cocod, it.itcod, it.itnam, it.packn, " +
" it.tradp, it.pkqty, it.dcode, it.freze, " +
" it.ishow, it.sltax, it.dcont, it.mcode, " +
" it.nwcod " +
"order by itnam ");
I have tried using resultsetmetadata but that does not work either.
you should be careful to this line
+ fdate + " and " + tdate
because you should use like this:
" .. to_date('"+fdate+"','***your_date_format') and to_date('"+fdate+"','***your_date_format')"

org.postgresql.util.PSQLException: The column index is out of range: 2, number of columns: 1

I have the following code:
String insert = "INSERT INTO " + tableName +
"(" + COLUMNS.TILE_ID + "," + COLUMNS.TILE_DATA + "," +
COLUMNS.TILE_LEVEL + "," + COLUMNS.TILE_COLUMN +
"," + COLUMNS.TILE_ROW +
"," + COLUMNS.TILE_IMAGE_FORMAT + "," + COLUMNS.TILE_SOURCE +
")";
String values = id + ",?" + "," +
tile.getLevel() + "," + tile.computeColumn() + "," +
tile.computeRow() + ",\'" + tile.getFileType().toUpperCase() +
"\'," + "\'" +
tile.getSource() + "\');";
String query = insert + " VALUES (" + values;
System.out.println(query);
PreparedStatement statement = conn.prepareStatement(query);
statement.setBytes(2, tile.getData());
return this.conn.createStatement().executeUpdate(query);
The query value:
INSERT INTO level1 (TILE_ID,TILE_DATA,TILE_LEVEL,TILE_COLUMN,TILE_ROW,TILE_IMAGE_FORMAT,TILE_SOURCE) VALUES (0,?,1,0,0,'JPG','null');
The error I get:
org.postgresql.util.PSQLException: The column index is out of range: 2, number of columns: 1.
My Table:
tile_id bigint NOT NULL,
tile_data bytea,
tile_level smallint,
tile_row integer,
tile_column integer,
tile_image_format image_format,
tile_source character varying(30),
CONSTRAINT level10_pkey PRIMARY KEY (tile_id)
Any ideas?
You haven't posted your stacktrace but your error seems to appear from this:
statement.setBytes(2, tile.getData());
Which is because you have only one parameter to bind to:
INSERT INTO level1 (TILE_ID,TILE_DATA,TILE_LEVEL,TILE_COLUMN,TILE_ROW,TILE_IMAGE_FORMAT,TILE_SOURCE) VALUES (0,?,1,0,0,'JPG','null');
The fact that the parameter is at position 2 in the values list is not what counts. It's the fact that it's the first place holder that matters. So your code should be,
statement.setBytes(1, tile.getData());
Thanks to e4c5 answer, I fixed my code as following:
String insert = "INSERT INTO " + tableName +
"(" + COLUMNS.TILE_ID + "," + COLUMNS.TILE_DATA + "," +
COLUMNS.TILE_LEVEL + "," + COLUMNS.TILE_COLUMN +
"," + COLUMNS.TILE_ROW +
"," + COLUMNS.TILE_IMAGE_FORMAT + "," + COLUMNS.TILE_SOURCE +
")";
String values = id + ",?" + "," +
tile.getLevel() + "," + tile.computeColumn() + "," +
tile.computeRow() + ",\'" + tile.getFileType().toUpperCase() +
"\'," + "\'" +
tile.getSource() + "\');";
String query = insert + " VALUES (" + values;
PreparedStatement statement = conn.prepareStatement(query);
statement.setBytes(1, tile.getData());
int result = statement.executeUpdate();
statement.close();
return result;
The fact that the parameter is at position 2 in the values list is not what counts. It's the fact that it's the first place holder that matters.

Dynamic pivot in SQL Server database

I'm writing a query where there is pivot table that has to generated. Right now below is my code.
select *
from
(select [case owner], [time taken(minutes)] from StatusTable) as pivotdata
pivot(
sum([time taken(minutes)])
for [CASE OWNER] in
("XXX", "AAA", "BBB")
) as pivoting
But instead of giving the rows in for-in, I need to get this dynamically, I've seen a query here SQL Server dynamic PIVOT query? And modified my query to be
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME([case owner])
FROM StatusTable c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'select *
from
(select [case owner], [time taken(minutes)] from StatusTable) as pivotdata
pivot(
sum([time taken(minutes)])
for [CASE OWNER] in
('+#cols+')
) as pivoting'
execute(#query)
And this is working fine, but the problem is that I've to use this query in my JDBC program. And without using execute(#query), it is not running in my SQL Server. Can I make this query similar to the first query, so that I can use the same in my program?
Microsoft's JDBC Driver for SQL Server (mssql-jdbc) supports the execution of an anonymous code block (multiple SQL statements) so we can just execute the same SQL code, including the EXECUTE(...) at the end:
String sql = " "
+ "SET NOCOUNT ON; "
+ "DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX); "
+ " "
+ "SET #cols = "
+ " STUFF( "
+ " ( "
+ " SELECT distinct ',' + QUOTENAME([case owner]) "
+ " FROM StatusTable c "
+ " FOR XML PATH(''), TYPE "
+ " ).value('.', 'NVARCHAR(MAX)'), "
+ " 1, "
+ " 1, "
+ " ''); "
+ " "
+ "set #query = 'select * "
+ "from "
+ "( "
+ " select [case owner], [time taken(minutes)] from StatusTable "
+ ") as pivotdata "
+ "pivot( "
+ " sum([time taken(minutes)]) for [CASE OWNER] in ('+#cols+') "
+ ") as pivoting'; "
+" "
+ "execute(#query); ";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
ResultSetMetaData rsmd = rs.getMetaData();
// print column headings
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
System.out.printf("%5s", rsmd.getColumnLabel(i));
}
System.out.println();
rs.next();
// print column values
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
System.out.printf("%5s", rs.getString(i));
}
System.out.println();
/* console output:
AAA BBB XXX
2 13 1
*/

Set parameter for identical subquery in PreparedStatement

I have PreparedStatement like this:
PreparedStatement st = conn
.prepareStatement("Select * from "
+ "(select Count(*) from uch_otstyp b,prov_uch p "
+ "where b.\"ID_Poezd\"=?"
+ "and (b.\"NachKm\"*1000+b.\"NachM\")>? "
+ "and (b.\"NachKm\"*1000+b.\"NachM\")<=? "
+ "and b.\"ID_Poezd\"=p.\"ID_Poezd\" "
+ "and b.\"ID_Uch\"=p.\"ID_Uch\" "
+ "and p.\"MES\"=? "
+ "and p.\"GOD\"=? "
+ "and p.\"Nput\"=? "
+ "and b.\"Kod_Otstup\"=? "
+ "and b.\"DEPTH\"<1),"
+ ""
+ "(select Count(*) from uch_otstyp b,prov_uch p "
+ "where b.\"ID_Poezd\"=?"
+ "and (b.\"NachKm\"*1000+b.\"NachM\")>? "
+ "and (b.\"NachKm\"*1000+b.\"NachM\")<=? "
+ "and b.\"ID_Poezd\"=p.\"ID_Poezd\" "
+ "and b.\"ID_Uch\"=p.\"ID_Uch\" "
+ "and p.\"MES\"=? "
+ "and p.\"GOD\"=? "
+ "and p.\"Nput\"=? "
+ "and b.\"Kod_Otstup\"=? "
+ "and b.\"DEPTH\">=1)"
+ "and b.\"DEPTH\"<2)");
Parameter values of each subquery are identic. How can I set parameters only for one subquery and automaticaly fill parameters of another(not for each subquery)?
You could use named parameters, so that when a parameter appears multiple times in a query you would only have to specify it once. JDBC doesn't support named parameters, but you can write code to find the parameter names in a SQL string and figure out the order they appear so that the arguments can be added to the PreparedStatement. Spring-Jdbc does this for you with the NamedParameterJdbcTemplate, here's an example. This is in core spring, the package that implements the parameter-munging is org.springframework.jdbc.core.namedparam.

Categories