Using Prepared Statement in Complex query - jdbc

I am trying to use Prepared Statement for processing queries. The problem is I have severals if else statements that changes query based on the user input.
Here is my code
if( !star_firstName.isEmpty() || !star_lastName.isEmpty() ){
baseQuery = "select m.id, title, year, director, banner_url, trailer_url from movies m, stars s, stars_in_movies sim WHERE m.id=sim.movie_id AND s.id=sim.star_id";
}
if(!searchtext.isEmpty())
baseQuery = baseQuery + " AND upper(title) like '%" + searchtext.toUpperCase() + "%'" ;
if(!movie_year.isEmpty())
baseQuery = baseQuery + " AND year=" + movie_year;
if(!movie_director.isEmpty())
baseQuery = baseQuery + " AND upper(director) like '%" + movie_director.toUpperCase() + "%'";
if( !star_firstName.isEmpty())
baseQuery = baseQuery + " AND upper(first_name) like '%" + star_firstName.toUpperCase() + "%'" ;
if( !star_lastName.isEmpty())
baseQuery = baseQuery + " AND upper(last_name) like '%" + star_lastName.toUpperCase() + "%'" ;
if(!title1.isEmpty() ){
baseQuery = "SELECT m.id, title, year, director, banner_url, trailer_url FROM movies m where m.title like '" + title1 + "%" + "'";
}
if( !genre.isEmpty()){
baseQuery = "SELECT m.id, title, year, director, banner_url, trailer_url FROM movies m, genres g, genres_in_movies gim where g.id=gim.genre_id and m.id = gim.movie_id and g.name='" + genre + "'";
}
System.out.println(baseQuery);
ResultSet resultSet = statement.executeQuery(baseQuery);

A PreparedStatement won't help you in this case.
A PreparedStatement only helps performance if the query stays the same, and all that varies are the constants.
The other use of a PreparedStatement is to avoid the danger of SQL injection.
If that's what you are after, you could proceed like this (untested):
java.util.Vector<String> params = new Vector();
StringBuffer baseQuery = new StringBuffer("SELECT ...");
...
if (!dweebnoid.isEmpty()) {
baseQuery.append(" AND upper(dweebnoid) LIKE ?");
params.add("%" + dweebnoid + "%");
}
...
java.sql.PreparedStatement pstmt =
conn.prepareStatement(baseQuery.toString());
for (i=0; i<params.size();++i)
pstmt.setString(i+1, params.get(i));
java.sql.ResultSet resultSet = pstmt.executeQuery();

Related

JPA SPEL optional List parameter

I have a JPA query with multiple joins and optional parameters , the query works fine if there is no multiple values sent in the status list parameter but if I send multiple values its giving exception as
"Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: An expression of non-boolean type specified in a context where a condition is expected, near ','.
Below is the query, could you please help
#Query(value = select distinct a.invn, a.accid, ac.accountCode, b.Fbusinesscode" +
", b.scode, i.invtype, d.dtid, d.did " +
" from INV.BINv a " +
"join READONLY.Fbusiness b on a.FbusinessId =b.FbusinessId " +
"join READONLY.Acc ac on a.accid=ac.accid " +
"join INV.Doc c on a.invid = c.invid " +
"join INV.Dstreq d on c.docid = d.docid " +
"join INV.dassoc e " +
"on d.dassocId = e.dassocId " +
"join BLNG.InvMType AS i on e.invtypeId = i.invtypeId "+
"where (?#{#requestdto.invoiceNumber } is null OR a.InvoiceEntityNumber = ?#{#requestdto.invoiceNumber}) and " +
" (?#{#requestdto.mod} is null OR i.InvTypeName = ?#{#requestdto.mod}) and " +
" (?#{#requestdto.getStatus} is null OR e.distrstttypecode in ?#{#requestdto.getStatus}) "
Something like this should do it:
#Query("select distinct a.invn, a.accid, ac.accountCode, b.Fbusinesscode" +
", b.scode, i.invtype, d.dtid, d.did " +
" from INV.BINv a " +
"join READONLY.Fbusiness b on a.FbusinessId =b.FbusinessId " +
"join READONLY.Acc ac on a.accid=ac.accid " +
"join INV.Doc c on a.invid = c.invid " +
"join INV.Dstreq d on c.docid = d.docid " +
"join INV.dassoc e " +
"on d.dassocId = e.dassocId " +
"join BLNG.InvMType AS i on e.invtypeId = i.invtypeId "+
"where (?#{#requestdto.invoiceNumber } is null OR a.InvoiceEntityNumber = ?#{#requestdto.invoiceNumber}) and " +
" (?#{#requestdto.mod} is null OR i.InvTypeName = ?#{#requestdto.mod}) and " +
" (?#{#requestdto.status?.size() ?: 0} = 0 OR e.distrstttypecode in ?#{#requestdto.status}) "
Note that in original query you specified requestdto.getStatus which should likely be just requestdto.status.
References:
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#expressions-operator-elvis
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#expressions-operator-safe-navigation

Adding multiple times together

I'm trying to add some data that is pulled from a database in the format of HH:MM:SS I'm trying to get them to add together so if we have 00:00:05 then 00:00:10 so we have 00:00:15
I have attempted both TimeSpan, DateTime but I get the following error:
Microsoft VBScript runtime error '800a01a8'
Object required: 'TimeSpan'
Script Location, line 157
This is the code:
While Not objRS.EOF
activecalls = activecalls + objRS("talkingagents")
callswaiting = callswaiting + objRS("callswaiting")
averagetalkingtime = averagetalkingtime + objRS("convavgtalkduration")
totalqueue = totalqueue + 1
totalcalls = totalcalls + objRS("totalcalls")
newWait = objRS("convavgwaitduration")
TimeSpan t1 = TimeSpan.Parse(newWait)
TimeString FormattedDate = t1.Add(FormattedDate)
timeString = timeString.Add(t1).ToString("dd\.hh\:mm\:ss")
Not clear with your code but this probably what you are looking for.
t1 = CDate("00:00:05")
t2 = CDate("00:00:10")
t3 = t1 + t2
MsgBox Right("00" & Hour(t3), 2) + ":" + Right("00" & Minute(t3), 2) + ":" + Right("00" & Second(t3), 2)

"ORA-00917: missing comma" & vbLf

Below is my query which is created in .Net code for insertion in oracle table. I found other related articles but they are different and not answering this. I was creating below query using a datatable.
`Public Sub UpdateOracleRecordset(dtTable As DataTable)
Dim sql As String = String.Empty
Dim i As Integer = 0
sql = "insert into " + dtTable.TableName + "("
For Each dc As DataColumn In dtTable.Columns
sql = sql + dc.ToString() + ","
Next
sql = sql.TrimEnd(",") + ")" + " select "
Dim rowVal As String = String.Empty
For Each dtRow As DataRow In dtTable.Rows
For Each dc As DataColumn In dtTable.Columns
rowVal = rowVal + dtRow(dc).ToString() + ","
Next
rowVal = rowVal.TrimEnd(",")
Next
sql = sql + rowVal
ExecuteSQL(sql)
End Sub`
"insert into CS_INV(LOANNO,CASENUMBER,INQ_TYPE,FUP_REASON,FUP_DATE,FUP_PROM,USERID,DATA_DAT,UNIT) values ( 5735985,103550709,399,58,9/24/2018 1:37:01 AM,9/25/2018 12:00:00 AM,Anurag,9/24/2018 1:37:08 AM,1 ) "
Wenfried is right and I used prepared statements which helped to resolve the issue
Dim conn As New OracleConnection(oradb)
conn.Open()
Dim sql As String = String.Empty
Dim sqlValues As String = String.Empty
Dim i As Integer = 0
sql = "insert into " + dtTable.TableName + "("
For Each dc As DataColumn In dtTable.Columns
sql = sql + dc.ToString() + ","
sqlValues = sqlValues + ":" + dc.ToString() + ","
Next
sql = sql.TrimEnd(",") + ")" + " values ( " + sqlValues.TrimEnd(",") + ")"
Dim commandText = sql
Dim Command As New OracleCommand(sql, conn)
For Each dtRow As DataRow In dtTable.Rows
For Each dc As DataColumn In dtTable.Columns
Command.Parameters.Add(New OracleParameter(dc.ToString(), dtRow(dc)))
Next
Next
Command.ExecuteNonQuery()
conn.Close()

why an update query is not working?

I have an update query in a servlet. The syntax is is correct, but when I execute the query, nothing happens. The execution stays frozen and the command never ends. Minutes later the message "ADVERTENCIA: GRIZZLY0023: Interrupting idle Thread: http-thread-pool-8080(5)." is printed every couple of seconds
I have tried with:
con.stmt.executeUpdate ("SQL");
con.rset = con.stmt.executeQuery ("SQL");
and with PreparedStatement.
This is the query:
System.out.println(""
+ " UPDATE JSP_TABLE SET "
+ " field1 = '" + request.getParameter("input1") + "',"
+ " field2= '" + request.getParameter("input2") + "',"
+ " field3= '" + request.getParameter("input3") + "',"
+ " field4= '" + request.getParameter("input4") + "',"
+ " field5= '" + request.getParameter("input5") + "',"
+ " field6= '" + request.getParameter("input6") + "',"
+ " field7= '" + request.getParameter("input7") + "',"
+ " field8= '" + indicador + " VS " + request.getParameter("input8") + "',"
+ " field9= '" + request.getParameter("input") + " al " + request.getParameter("hasta9") + "'"
+ " WHERE ID_PK = " + request.getParameter("inputPK"));
All my Statements, ResultSets and Connections are closed at the end of use.
I have a second update which works fine.
package Funciones;
import conexion.conectar;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ActualizarDinamica extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, SQLException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
conectar con = new conectar();
try {
/*
* TODO output your page here. You may use following sample code.
*/
con.stmt = con.conn.createStatement();
String indicador = "";
switch (Integer.parseInt(request.getParameter("indicador"))) {
case 1:
indicador = "Nivel de Servicio";
break;
case 2:
indicador = "Venta";
break;
case 3:
indicador = request.getParameter("txt_otro");
break;
case 0:
indicador = "Presencia";
break;
};
/* way 1
* con.rset = con.stmt.executeQuery(""
+ " UPDATE JSP_TABLE SET "
+ " FIELD1 = '" + request.getParameter("input1") + "',"
+ " FIELD2 = '" + request.getParameter("input2") + "',"
+ " FIELD3 = '" + request.getParameter("input3") + "',"
+ " FIELD4 = '" + request.getParameter("input4") + "',"
+ " FIELD5 = '" + request.getParameter("input5") + "',"
+ " FIELD6 = '" + request.getParameter("input6") + "',"
+ " FIELD7 = '" + request.getParameter("input7") + "',"
+ " FIELD8 = '" + indicador + " VS " + request.getParameter("input8") + "',"
+ " FIELD9 = '" + request.getParameter("input9") + " al " + request.getParameter("input10") + "'"
+ " WHERE FIELD_PK = " + request.getParameter("input11_ID"));
con.rset = con.stmt.executeQuery(""
+ " UPDATE JSP_TABLE2 SET"
+ " FIELD_DATE = TO_DATE('" + request.getParameter("input12") + " " + request.getParameter("input14") + ":" + request.getParameter("input13") + "','DD/MM/YYYY HH24:MI')"
+ " WHERE FIELD_ID = " + request.getParameter("input11_ID"));
*/
/* way 2
con.stmt.executeUpdate(""
+ " UPDATE JSP_TABLE SET "
+ " FIELD1 = '" + request.getParameter("input1") + "',"
+ " FIELD2 = '" + request.getParameter("input2") + "',"
+ " FIELD3 = '" + request.getParameter("input3") + "',"
+ " FIELD4 = '" + request.getParameter("input4") + "',"
+ " FIELD5 = '" + request.getParameter("input5") + "',"
+ " FIELD6 = '" + request.getParameter("input6") + "',"
+ " FIELD7 = '" + request.getParameter("input7") + "',"
+ " FIELD8 = '" + indicador + " VS " + request.getParameter("input8") + "',"
+ " FIELD9 = '" + request.getParameter("input9") + " al " + request.getParameter("input10") + "'"
+ " WHERE FIELD_PK = " + request.getParameter("input11_ID"));
con.stmt.executeUpdate(""
+ " UPDATE JSP_TABLE2 SET"
+ " FIELD_DATE = TO_DATE('" + request.getParameter("input12") + " " + request.getParameter("input14") + ":" + request.getParameter("input13") + "','DD/MM/YYYY HH24:MI')"
+ " WHERE FIELD_ID = " + request.getParameter("input11_ID"));
*/
//way 3
PreparedStatement updateSmallQuery = null;
PreparedStatement updateBigQuery = null;
String bigQuery=
""
+ " UPDATE JSP_TABLE SET "
+ " FIELD1 = '" + request.getParameter("input1") + "',"
+ " FIELD2 = '" + request.getParameter("input2") + "',"
+ " FIELD3 = '" + request.getParameter("input3") + "',"
+ " FIELD4 = '" + request.getParameter("input4") + "',"
+ " FIELD5 = '" + request.getParameter("input5") + "',"
+ " FIELD6 = '" + request.getParameter("input6") + "',"
+ " FIELD7 = '" + request.getParameter("input7") + "',"
+ " FIELD8 = '" + indicador + " VS " + request.getParameter("input8") + "',"
+ " FIELD9 = '" + request.getParameter("input9") + " al " + request.getParameter("input10") + "'"
+ " WHERE FIELD_PK = " + request.getParameter("input11_ID");
String smallQuery= ""
+ " UPDATE JSP_TABLE2 SET"
+ " FIELD_DATE = TO_DATE('" + request.getParameter("input12") + " " + request.getParameter("input14") + ":" + request.getParameter("input13") + "','DD/MM/YYYY HH24:MI')"
+ " WHERE FIELD_ID = " + request.getParameter("input11_ID");
try {
con.conn.setAutoCommit(false);
updateSmallQuery = con.conn.prepareStatement(smallQuery);
updateBigQuery = con.conn.prepareStatement(bigQuery);
updateBigQuery.executeUpdate();
updateSmallQuery.executeUpdate();
con.conn.commit();
} catch (SQLException e) {
System.out.println("catch!");
System.out.println(e.getMessage());
if (con != null) {
try {
System.err.print("Transaction is being rolled back");
con.conn.rollback();
} catch (SQLException excep) {
}
}
} finally {
if (updateSmallQuery != null) {
updateSmallQuery.close();
}
if (updateBigQuery != null) {
updateBigQuery .close();
}
con.conn.setAutoCommit(true);
}
response.sendRedirect("sol_env_c.jsp");
} finally {
con.conn.commit();
con.conn.close();
con.stmt.close();
out.close();
}
}
}
Hope this help to find the answer.
PD: The small one run with no problems. the big one it's the problem.
EDIT:
This is conectar()
public conectar() {
try {
Class.forName("oracle.jdbc.OracleDriver");
System.out.println("Oracle JDBC driver loaded ok.");
conn = DriverManager.getConnection(params, user, password);
} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
}
}
Bill is almost certainly correct and you just have a lock on rows you're trying to update. You mentioned that 'the syntax is correct', which suggests you might have checked it directly in the database - e.g. with SQL*Plus or SQL Developer - and have not issued a rollback (or commit) in that session. Attempting to update the same rows from your code is then hanging waiting for the locks to be released.
If you can find the session where you ran the update manually, issue a rollback in it. If you can't, you can see which sessions are holding locks with a query like:
select vs.osuser, vs.process, vs.logon_time, vs.sid, vs.serial#, vs.program,
dl.lock_type, dl.mode_held, dl.blocking_others
from dba_locks dl
left join v$session vs on vs.sid = dl.session_id
where lock_type != 'Media Recovery'
and lock_type != 'Redo Thread';
While your code is running - and hung - you can see what's blocking it with something like:
select vsw.osuser, vsw.process, vsw.logon_time, vsw.sid, vsw.program,
dw.lock_type, dw.mode_held,
vsh.osuser, vsh.process, vsh.logon_time, vsh.sid, vsh.serial#, vsh.program
from dba_waiters dw
left join v$session vsw on vsw.sid = dw.waiting_session
left join v$session vsh on vsh.sid = dw.holding_session;
Or search for other examples, e.g. this. You need privileges to query the v$ performance views, and if you don't have them you may need DBA assistance. If you can't manually rollback the lock you might need DBA help to kill the locking session anyway.
You should really pay attention to the comments about parameterising your statements, too.

return id field when executing SQL in LINQ

I'm trying to execute an SQL insert query using LINQ and returning the ID field. My code does not work, can anybody tell me if my syntax is wrong?
string query = "insert into EnvironmentalReportDepts ";
query += "(fkDeptID, OrderNumber, fkEnvironmentalReportID) ";
query += "values(" + tmpDeptReport.fkDeptID + ", " + tmpDeptReport.OrderNumber + ", " + tmpDeptReport.EnvironmentalReport.EnvironmentalReportID + ") ";
query += "select scope_identity()";
var newDeptID = _database.ExecuteQuery<int>(query).ToList()[0];
Try changing
query += "select scope_identity()";
to
query += "; select scope_identity()";
Also, you may have to use
_database.ExecuteQuery<decimal>(query).ToList()[0];
change query to:
string query = "DECLARE #scope_identity int";
query += "insert into EnvironmentalReportDepts ";
query += "(fkDeptID, OrderNumber, fkEnvironmentalReportID) ";
query += "values(" + tmpDeptReport.fkDeptID + ", " + tmpDeptReport.OrderNumber + ", " + tmpDeptReport.EnvironmentalReport.EnvironmentalReportID + ") ";
query += "SET #scope_identity=##IDENTITY";
query += "select #scope_identity";

Resources