New to using JDBC and I was wondering if all operations produce a result set. For example I am making statements to insert/update to a database via:
StringBuffer query1 = new StringBuffer("UPDATE table SET col1 = value, WHERE some_col = some_val");
PreparedStatement pstmt1 = con.prepareStatment(query1.toString());
ResultSet rs1 = pstmt1.executeQuery();
So would this snippet, when executed just act out the appropriate update and be done? Or would I need to handle the result set in some way in order to complete the operation?
Thanks for the help in advance.
You should be using PreparedStatement#executeUpdate() rather than executeQuery(). It returns an int indicating the amount of affected rows.
int affectedRows = preparedStatement.executeUpdate();
That said, constructing a SQL string that way is not the normal idiom. You would rather like to use placeholders ? and use the PreparedStatement setters to set the values.
String sql = "UPDATE table SET col1 = ? WHERE some_col = ?";
// ...
preparedStatement = connection.prepareStatment(sql);
preparedStatement.setString(1, col1);
preparedStatement.setString(2, someCol);
int affectedRows = preparedStatement.executeUpdate();
// ...
See also:
Basic JDBC tutorial
Using PreparedStatement
No, you don't have to handle the ResultSet - it will be empty anyway, because an update operation shouldn't return results from the database. Usually you would call a different metho on the statement:
StringBuffer query1 = new StringBuffer("UPDATE table SET col1 = value, WHERE some_col = some_val");
PreparedStatement pstmt1 = con.prepareStatment(query1.toString());
int rowCount = pstmt1.executeUpdate();
tthere is another method for such statements:
s.execute("..");
Related
How can I update my SQL Table column with the value that is stored in a local variable.
In my program I have taken value from the HTML page using the following statement:
String idd=request.getParameter("id");
String report=request.getParameter("rprt");
So now I have to update the value of report in my database table named "ptest" and I am using the following query:
Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection con =
DriverManager.getConnection("jdbc:mysql://localhost:3306/tcs","root","root");
Statement st= con.createStatement();
ResultSet rs;
int i=st.executeUpdate("update ptest set result = #reprt where patient_id=
#idd");
out.println("Successfully Entered");
But the value is not being stored in the database instead NULL is being stored.
I have already seen this question and got no help.
Question
Please ignore my mistakes if any in this question as I am new to MYSQL.
You can use prepared statements in java.
setString or setInt can set different data types into your prepared statements.
The parameter 1, 2 are basically the positions of the question mark. setString(1,report) means that it would set the string report in the 1st question mark in your query.
Hope this code helps you in achieving what you want.
String query = "update ptest set result = ? where patient_id = ?";
PreparedStatement preparedStatement = con.prepareStatement(query);
preparedStatement.setString(1, report);
preparedStatement.setString(2, idd);
preparedStatement.executeUpdate();
In JDBC, you use ? as placeholders for where you want to inject values into a statement.
So you should do something like this ...
Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection con =
DriverManager.getConnection("jdbc:mysql://localhost:3306/tcs","root","root");
PreparedStatement st= con.prepareCall("update ptest set result = ? where patient_id=
?");
///now set the params in order
st.setString(1, report);
st.setString(2, idd);
//then execute
st.executeUpdate();
Doing a string concat with the values is dangerous due to sql injection possibilities, so I typically make statement text static and final, and also if your value has a ' in it that could blow up your sql syntax etc. Also, notice the use of executeUpdate rather than query.
Hope this helps
I am trying to add rows to a table. Initially, I had this code but it creates an error that there are 8 columns (additional columns were altered, initially I only had 2 columns) but I am only adding 2 values:
PreparedStatement addDate =
con.prepareStatement("insert into contributions values(?,?)");
addDate.setString(2, string);
addDate.execute();
}
And then I tried this:
public void addDateToContributionsTable(String string) throws ClassNotFoundException, SQLException {
if(con == null) {
// get connection
getConnection();
}
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("Select * from contributions");
ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
StringBuilder sb = new StringBuilder();
for(int i= 0; i < columnsNumber; i++){
sb.append("?");
sb.append(",");
}
System.out.println(sb.toString());
System.out.println("insert into contributions values('"+sb.toString()+"')");
PreparedStatement addDate = con
.prepareStatement("insert into contributions values('"+sb.toString()+"')");
addDate.setString(2, string);
addDate.execute();
}
But I am still having the same error:
[SQLITE_ERROR] SQL error or missing database (table contributions has 8 columns but 1 values were supplied)
Any help would be appreciated. :)
The values don't know where they should be inserted, so I suggest writing the column names for each value.
reparedStatement addDate =
con.prepareStatement("insert into contributions (COLUMN_NAMES) values (?,?)");
addDate.setString(2, string);
addDate.execute();
}
You added multiple bind parameters in the SQL, but you only ever bound one of them:
addDate.setString(2, string);
You need to call setXXX() per bind parameter.
If you are really sure you want to use the same value, you can instead use named parameters instead, then you won't have to call setXXX() multiple times. You can refer to this:
Named parameters in JDBC
Also, questionMarksList and StringBuilder sb are doing the same thing over two loops.
Edit
If your SQL has 2 question marks, you have 2 bind parameters, then you need to set two bind parameters.
e.g. For SQL with 3 bind parameters:
INSERT INTO MYTABLE VALUES(?, ?, ?)
You need to provide 3 values:
addDate.setString(1, "String1"); // Bind to first question mark
addDate.setString(2, "String2"); // etc.
addDate.setString(3, "String3");
Thanks to all that responded to my question. The problem was with the number of ? I had on my statement every time I increase or decrease the column numbers. The only problem with my statement is having this expression '' . When I changed it to "+questionMarks+" instead of '"+questionMarks+"', it worked. Does not matter how many setXXX() method I use as long as the number of ? are the same with the number of columns on the table, it will work. Having the code below, I did not encounter any errors anymore.
PreparedStatement addmembers = con
.prepareStatement("insert into membersdata values "+questionMarks+"");
addmembers.setString(2, name);
addmembers.setString(3, accounts);
addmembers.setString(4, email);
addmembers.execute();
I have an assignment where I need to update records using a PreparedStatement. Once the record have been updated as we know update query return count, i.e., number of row affected.
However, instead of the count I want the rows that were affected by update query in response, or at least a list of id values for the rows that were affected.
This my update query.
UPDATE User_Information uInfo SET address = uInfo.contact_number || uInfo.address where uInfo.user_id between ? AND ?;
Normally it will return count of row affected but in my case query should return the ids of row or all the row affected.
I have used the returning function of PostgreSQL it is working but is not useful for me in that case.
i have used returning function of PostgreSQL but is not useful for me
It should be. Perhaps you were just using it wrong. This code works for me:
sql = "UPDATE table1 SET customer = customer || 'X' WHERE customer LIKE 'ba%' RETURNING id";
try (PreparedStatement s = conn.prepareStatement(sql)) {
s.execute(); // perform the UPDATE
try (ResultSet rs = s.getResultSet()) {
// loop through rows from the RETURNING clause
while (rs.next()) {
System.out.println(rs.getInt("id")); // print the "id" value of the updated row
}
}
}
The documentation indicates that we can also use RETURNING * if we want the ResultSet to include the entire updated row.
Update:
As #CraigRinger suggests in his comment, the PostgreSQL JDBC driver does actually support .getGeneratedKeys() for UPDATE statements too, so this code worked for me as well:
sql = "UPDATE table1 SET customer = customer || 'X' WHERE customer LIKE 'ba%'";
try (PreparedStatement s = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
s.execute(); // perform the UPDATE
try (ResultSet rs = s.getGeneratedKeys()) {
while (rs.next()) {
System.out.println(rs.getInt(1)); // print the "id" value of the updated row
}
}
}
Thanks, Craig!
You might be able to use JDBC's support for getting generated keys. See the Connection.prepareStatement(String sql, int[] columnIndexes) API method, then use Statement.getGeneratedKeys() to access the results.
The spec says "the driver will ignore the array if the SQL statement is not an INSERT statement" but I think PostgreSQL's JDBC driver will actually honour your request with other statement types too.
e.g.
PreparedStatement s = conn.prepareStatement(sql, new String[] {'id'})
s.executeUpdate();
ResultSet rs = s.getGeneratedKeys();
Otherwise, use RETURNING, as Gord Thompson describes.
There are two way of doing it
1. by passing an array of column name or index of column prepareStatement
i.e conn.prepareStatement(sql, new String[] {'id','uname'})
and
2. by using Statement.RETURN_GENERATED_KEYS in prepareStatement.
My code is for this i.e as per my requirement i have developed my code you can have a look for better idea.
private static final String UPDATE_USER_QUERY= "UPDATE User_Information uInfo SET address = uInfo.contact_number || uInfo.address where uInfo.user_id between ? AND ?;";
//pst = connection.prepareStatement(UPDATE_USER_QUERY,columnNames);
pst = connection.prepareStatement(UPDATE_USER_QUERY,Statement.RETURN_GENERATED_KEYS);
ResultSet rst = pst.getGeneratedKeys();
List<UserInformation> userInformationList = new ArrayList<UserInformation>();
UserInformation userInformation;
while (rst.next()){
userInformation = new UserInformation();
userInformation.setUserId(rst.getLong("user_id"));
userInformation.setUserName(rst.getString("user_name"));
userInformation.setUserLName(rst.getString("user_lName"));
userInformation.setAddress(rst.getString("address"));
userInformation.setContactNumber(rst.getLong("contact_number"));
userInformationList.add(userInformation);
}
That think i need to achieve in this case.
Hope so this will help you a lot.
This is what I want to do:
PreparedStatement query2 =
conn.prepareStatement ("UPDATE report SET Name = ? WHERE Id = ?");
String blah = "Jane";
int id = 1;
query2.setString(1, blah);
query2.setInt(2, id);
query2.executeQuery();
But I'm getting this error:
The statement did not return a result set.
I am new to the whole jdbc world. Where am I going wrong here?
You should use executeUpdate.
"Executes the given SQL statement, which may be an INSERT, UPDATE, or DELETE statement or an SQL statement that returns nothing, such as an SQL DDL statement."
I'm new to using Oracle so I'm going off what has already been previously answered in this SO question. I just can't seem to get it to work. Here's the statement that I'm using:
declare
lastId number;
begin
INSERT INTO "DB_OWNER"."FOO"
(ID, DEPARTMENT, BUSINESS)
VALUES (FOO_ID_SEQ.NEXTVAL, 'Database Management', 'Oracle')
RETURNING ID INTO lastId;
end;
When I call executeQuery the PreparedStatement that I have made, it inserts everything into the database just fine. However, I cannot seem to figure out how to retrieve the ID. The returned ResultSet object will not work for me. Calling
if(resultSet.next()) ...
yields a nasty SQLException that reads:
Cannot perform fetch on a PLSQL statement: next
How do I get that lastId? Obviously I'm doing it wrong.
make it a function that returns it to you (instead of a procedure). Or, have a procedure with an OUT parameter.
Not sure if this will work, since I've purged all of my computers of anything Oracle, but...
Change your declare to:
declare
lastId OUT number;
Switch your statement from a PreparedStatement to a CallableStatement by using prepareCall() on your connection. Then register the output parameter before your call, and read it after the update:
cstmt.registerOutParameter(1, java.sql.Types.NUMERIC);
cstmt.executeUpdate();
int x = cstmt.getInt(1);
I tried with Oracle driver v11.2.0.3.0 (since there are some bugs in 10.x and 11.1.x, see other blog). Following code works fine:
final String sql = "insert into TABLE(SOME_COL, OTHER_COL) values (?, ?)";
PreparedStatement ps = con.prepareStatement(sql, new String[] {"ID"});
ps.setLong(1, 264);
ps.setLong(2, 1);
int executeUpdate = ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next() ) {
// The generated id
long id = rs.getLong(1);
System.out.println("executeUpdate: " + executeUpdate + ", id: " + id);
}
When you prepare the statement set the second parameter to RETURN_GENERATED_KEYS. Then you should be able to get a ResultSet off the statement object.
You can use Statement.getGeneratedKeys() to do this. You just need to make sure to tell JDBC what columns you want back using one of the method overloads for that, such as the Connection.prepareStatement overload here:
Connection conn = ...
PreparedStatement pS = conn.prepareStatement(sql, new String[]{"id"});
pS.executeUpdate();
ResultSet rS = pS.getGeneratedKeys();
if (rS.next()) {
long id = rS.getLong("id");
...
}
You don't need to do the RETURNING x INTO stuff with this, just use the basic SQL statement you want.
Are you doing that in a stored procedure ? According to this Oracle document, it won't work with the server-side driver.
The Oracle server-side internal driver does not support
the retrieval of auto-generated keys feature.