How to set list in prepared statement - java

How can i set list in prepared statement(statement.setString(1, productCode); ).
See below my code snippet.
Thanks
public static List<Message> listAllWonBids(List<Message> productCode,
Connection connection) {
List<Message> winners = new ArrayList<Message>();
String sql = "SELECT b.`id`, b.`msisdn` as msisdn ,b.`productname` as productname, b.`productcode` as productcode, max(b.`amount`) as amount FROM "
+ TableNames.SAVEDBIDSTABLE
+ " b where productcode = ? "
+ " group by amount order by productcode, amount desc limit 1";
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
LOGGER.info(sql);
if (connection == null || connection.isClosed())
connection = DBConnection.getConnection();
statement = connection.prepareStatement(sql);
**statement.setString(1, productCode);**
resultSet = statement.executeQuery();
NOTE: productCode is coming from another list shown below
public static List<Message> allProductCode(Connection connection) {
List<Message> productcodes = new ArrayList<Message>();
PreparedStatement statement = null;
ResultSet resultSet = null;
String sql = "SELECT `productCode` FROM " + TableNames.AUCTIONTABLE1
+ " WHERE date(`endDate`) = curdate() order by `id` desc";

That is not possible, either you generate a where clause programmatically using the IN
"where productcode in (" + listToStringEncoding + ")"
or you loop over the list and call the statement multiple times.
Other possibility is to join the 2 statements...

You could combine those two queries. Something like:
String sql = "SELECT b.`id`, b.`msisdn` as msisdn ,b.`productname` as productname, b.`productcode` as productcode, max(b.`amount`) as amount FROM "
+ TableNames.SAVEDBIDSTABLE + " b where productcode in (SELECT `productCode` FROM "
+ TableNames.AUCTIONTABLE1 + " WHERE date(`endDate`) = curdate() order by `id` desc) group by amount order by productcode, amount desc limit 1";
Then you wouldn't need any parameters

Related

Automate changing Statement into Prepared Statement programmatically through Java ( In source code )

I have been assigned a task for automating the conversion of statements into prepared statements for security purpose. Since it's a repetitive task, I want to automate it.
for example
public String getEmployee(Connection connection, Long id , Long groupId) {
String result = "";
try {
Statement stmt = connection.createStatement();
String query = "select * from employee"
+ " where id = " + id ; // flaw 1
if(groupId != null) {
query += " and group_id = " + groupId; // flaw 2
}
ResultSet rs = stmt.executeQuery(query);
}
I want to remove the flaws with :
public String getEmployee(Connection connection, Long id , Long groupId) {
String result = "";
try {
String query = "select * from employee"
+ " where id = ? ";
if(groupId != null) {
query += " and group_id = ? ";
}
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setLong(parameterIndex++, id);
stmt.setLong(parameterIndex++, groupId);
ResultSet rs = stmt.executeQuery();
}
I need to write a java code, that can replace these Statements with Prepared Statements.
Input will be the java file.
I tried a lot, but couldn't find out a possible solution to this problem.
Can you please help me by guiding me, if it's feasible.

Testing for null inside SQL query

I want to implement search filter for this table:
CREATE TABLE ACCOUNT(
ID INTEGER NOT NULL,
USER_NAME TEXT,
PASSWD TEXT,
FIRST_NAME TEXT,
LAST_NAME TEXT,
LAST_LOGIN DATE,
DATE_REGISTERED DATE,
ROLE INTEGER,
CAN_LOGIN INTEGER
)
;
-- ADD KEYS FOR TABLE ACCOUNT
ALTER TABLE ACCOUNT ADD CONSTRAINT KEY1 PRIMARY KEY (ID)
;
SELECT * FROM ACCOUNT
WHERE '" + searchString + "' IN (ID, USER_NAME, FIRST_NAME, LAST_NAME)
ORDER BY %S %S offset ? limit ?;
But when I have empty search filter I get this error:
org.postgresql.util.PSQLException: ERROR: invalid input syntax for integer: "null" Position: 30
How can I edit the SQL query in a way that WHERE clause will be skipped if searchString is empty?
Here is the Java method:
public List<AccountsObj> list(int firstRow, int rowCount, String sortField, boolean sortAscending) throws SQLException
{
String SqlStatement = null;
if (ds == null)
{
throw new SQLException();
}
Connection conn = ds.getConnection();
if (conn == null)
{
throw new SQLException();
}
String sortDirection = sortAscending ? "ASC" : "DESC";
SqlStatement = "SELECT * FROM ACCOUNT "
+ " WHERE '" + searchString + "' IN (ID, USER_NAME, FIRST_NAME, LAST_NAME)"
+ " ORDER BY %S %S offset ? limit ? ";
String sql = String.format(SqlStatement, sortField, sortDirection);
PreparedStatement ps = null;
ResultSet resultSet = null;
List<AccountsObj> resultList = new ArrayList<>();
try
{
conn.setAutoCommit(false);
boolean committed = false;
ps = conn.prepareStatement(sql);
ps.setInt(1, firstRow);
ps.setInt(2, rowCount);
resultSet = ps.executeQuery();
resultList = ProcessorArrayList(resultSet);
conn.commit();
committed = true;
}
finally
{
ps.close();
conn.close();
}
return resultList;
}
Using SQL to check for a null search string you can do:
SELECT * FROM account WHERE ? IS NULL OR ? IN (user_name, first_name, last_name)
Here the ? IS NULL will short-circuit if the parameter is NULL and the second part will not be evaluated.
Note that, I've used two parameter bindings with the same value (your search string) here and that the ID column is gone - you cannot mix varchar and integer in the IN clause.
Edit For wildcard searches you can use LIKE or ILIKE (for case-insensitive searches)
SELECT * FROM account WHERE
(trim(?) = '') IS NOT FALSE
OR user_name like ?
OR first_name like ?
OR last_name like ?
Using a prepared statement you would call it like this (note that you have to bind the same parameter four times)
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, searchString);
ps.setString(2, searchString);
ps.setString(3, searchString);
ps.setString(4, searchString );
try (ResultSet rs = ps.executeQuery()) {
// read data
}
}
You can replace this line of your java code :
+ (searchString == null || searchString.length == 0 ) ? "" : (" WHERE '" + searchString + "' IN (ID, USER_NAME, FIRST_NAME, LAST_NAME)")
It basically checks if searchString is empty, and adds the line only if it is not

How to do INSERT SELECT INTO in Java using PrepareStatement

I'm trying to do an INSERT INTO SELECT which are inserting into in 1 table by selecting specific data in columns from 2 tables. The thing is, it will involve with user input from JTextField as well. I have searched for many solutions but still got an error and I just dunno what else to do. I'm using Java as PL and Oracle as DB. This is what I have got so far :
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe","ghost","slayer");
stmt = con.createStatement();
String sbjC = sbjCode.getText(); //textfield for subjectCode
String sbjN = sbjName.getText(); //textfield for subjectName
String matricsno = textstudentid.getText(); //textfield for matrics number
String sbjG = sbjGrade.getText(); //textfield for subjectGrade (not gonna be use in db, just for comparison)
String sql1 = "INSERT INTO transferred (subjectCode,subjectName,credit,prequisite,matricsNo) "
+ "SELECT b.subjectCode,b.subjectName,b.credit,b.prequisite,s.matricsNo "
+ "FROM bitm b, student s "
+ "WHERE b.subjectCode = '"+sbjC+"' AND b.subjectName = '"+sbjN+"' AND s.matricsNo = '"+matricsno+"'";
/* table Transferred has 5 column which are subjectCode,subjectName,credit,prequisite,matricsNo [matricsno as FK]
* table bitm has 5 column [subjectCode as PK]
* table student has 6 column [matricsno as PK]
*/
ps = con.prepareStatement(sql1);
ps.setString(1, sbjC);
ps.setString(2, sbjN);
ps.setString(3, "SELECT credit FROM bitm WHERE subjectCode = '"+sbjC+"' AND subjectName = '"+sbjN+"'");
ps.setString(4, "SELECT prequisite FROM bitm WHERE subjectCode = '"+sbjC+"' AND subjectName = '"+sbjN+"'");
ps.setString(5, "SELECT matricsno FROM student WHERE matricsno = '"+matricsno+"'");
ps.executeUpdate(sql1);
The only error I have got after executing and insert all data needed into JTextField is java.sql.SQLException : Invalid column index.
The SQL statement has been test in SQL Developer and succeed. Just I'm bit confused on how to do it on Java.
Thank you for all of your response and time.
I'm a newbie in Java.
For PreparedStatement, you'd code ? Into the sql and later replace that with values.
String sql1 = "INSERT INTO transferred (subjectCode,subjectName,credit,prequisite,matricsNo) "
+ "SELECT b.subjectCode,b.subjectName,b.credit,b.prequisite,s.matricsNo "
+ "FROM bitm b, student s "
+ "WHERE b.subjectCode = ? AND b.subjectName = ? AND s.matricsNo = ? ";
ps = con.prepareStatement(sql1);
ps.setString(1, sbjC);
ps.setString(2, sbjN);
ps.setString(3,matricsno);
ps.executeUpdate ();
This should do it.
Your error came from giving parameters (setString...) without matching ?
Unfortunately you absolutely misunderstood what the preparedStatemet does.
You have to write ? -s into the query and the preparedSatement is going to replace it on a typed way:
String sql1 = "INSERT INTO transferred (subjectCode,subjectName,credit,prequisite,matricsNo) "
+ "SELECT b.subjectCode,b.subjectName,b.credit,b.prequisite,s.matricsNo "
+ "FROM bitm b, student s "
+ "WHERE b.subjectCode = ? AND b.subjectName = ? AND s.matricsNo = ?";
ps = con.prepareStatement(sql1);
ps.setString(1, sbjC);
ps.setString(2, sbjN);
ps.setString(3, matNo);
ps.executeUpdate();
To answer my own question, I'll put comment on the changes that I have made to the code and make it work:
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe","aza","jaiza");
stmt = con.createStatement();
String sbjC = sbjCode.getText();
String sbjN = sbjName.getText();
String matricsno = textstudentid.getText();
String sbjG = sbjGrade.getText();
String sql1 = "INSERT INTO transferred (subjectCode,subjectName,credit,prequisite,matricsNo) "
+ "SELECT b.subjectCode,b.subjectName,b.credit,b.prequisite,s.matricsNo "
+ "FROM bitm b, student s "
+ "WHERE b.subjectCode = ? AND b.subjectName = ? AND s.matricsNo = ?"; // from textfield to ?
ps = con.prepareStatement(sql1);
ps.setString(1, sbjC);
ps.setString(2, sbjN);
ps.setString(3, matricsno);
//from all the SELECT statement to just 3 user-input-from-textfield column
ps.executeUpdate(); // remove the sql1 in ps.executeUpdate(sql1);

How to check if a Merge query was succesfull in JAVA (ResultSet)?

I want to check if this query returns a result or an error.
I use the next() method, for SELECT querys synce it checks if there's a next row but not sure about MERGE
public ResultSet example{
String sqlQuery = "MERGE INTO bonuses b "
+"USING ( "
+"SELECT employee_id, salary, dept_no "
+"FROM employee#link_to) e "
+"ON (b.employee_id = e.employee_id) "
+"WHEN MATCHED THEN "
+"UPDATE SET b.bonus = e.salary * 0.1 "
+"WHEN NOT MATCHED THEN "
+"INSERT (b.employee_id, b.bonus) "
+"VALUES (e.employee_id, e.salary * 0.05) "
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs;
try {
rs = stmt.executeQuery();
Err.errN(rs);
} finally {
}
return rs;
}
you can try this:
........
int affected_rows_number=stmt.executeUpdate("your_query");
affected_rows_number show you how many rows affected. You can understand it worked or now.

How to get a particular column's values alone?

I am using the mysql java connector. I need java to display the contents of the first column and the second column in different steps. How do I achieve this?
String qry = "select col1,col2 from table1";
Resultset rs = statement.executeQuery(qry);
I've posted a sample below:
Statement s = conn.createStatement ();
s.executeQuery ("SELECT id, name, category FROM animal");
ResultSet rs = s.getResultSet ();
int count = 0;
while (rs.next ())
{
int idVal = rs.getInt ("id");
String nameVal = rs.getString ("name");
String catVal = rs.getString ("category");
System.out.println (
"id = " + idVal
+ ", name = " + nameVal
+ ", category = " + catVal);
++count;
}
rs.close ();
s.close ();
System.out.println (count + " rows were retrieved");
(From: http://www.kitebird.com/articles/jdbc.html#TOC_5 )
Edit: just re-read the question and think you might mean you want to refer to a column later on in code, instead of in the inital loop as in my example above. In that case, you can create an array and refer to the array later on, or, as another answer suggests you can just do another query.
Load them into any data structure of your choice and then display them to your heart's content.
List<String> firstCol = new ArrayList<String>();
List<String> secondCol = new ArrayList<String>();
while(rs.next()){
firstCol.add(rs.getString("col1"));
secondCol.add(rs.getString("col2"));
}
Then you can manipulate with the two list as you want.
How about ... (insert drumroll here):
String qry1 = "select col1 from table1";
Resultset rs1 = statement.executeQuery(qry);
String qry2 = "select col2 from table1";
Resultset rs2 = statement.executeQuery(qry);
(You might want to phrase your question more clearly.)
You can do it like this :
String sql = "select col1,col2 from table1";
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) System.out.println(rs.getString("col1"));
I am using following Code:
Statement sta;
ResultSet rs;
try {
sta = con.createStatement();
rs = sta.executeQuery("SELECT * FROM TABLENAME");
while(rs.next())
{
Id = rs.getString("COLUMN_Name1");
Vid = rs.getString("COLUMN_Name2");
System.out.println("\n ID : " + Id);
System.out.println("\n VehicleID: " + Vid);
}
}
catch(Execption e)
{
}
And this code is 100% working.
String emailid=request.getParameter("email");
System.out.println(emailid);
rt=st.executeQuery("SELECT imgname FROM selection WHERE email='emailid'");
System.out.println(rt.getString("imgname"));
while(rt.next())
{
System.out.println(rt.getString("imgname"));
finalimage=rt.getString("imgname");
}

Categories