It Takes Too Long For Me To Create And Send PreparedStatement's or ResultSet.
How Can I Get MaxID From SQL in Java Method?
Writed this but not working...
private static int getLastId()
{
int returned=0;
try
{
PreparedStatement stat;
ResultSet rs;
String sql="select max(id) from home";
stat=conn.prepareStatement(sql);
rs=stat.executeQuery();
while(rs.next())
{
returned = rs.getInt("id")+1;// just want a new id for new person
}
}
catch (Exception e)
{
System.out.println(""+e);
}
return returned;
}
I Tried To Use It Like This...
//reseting every thing and get lastId+1;
System.out.println("added");
field_name.setText("");
field_pass.setText("");
int temp= getLastId();
field_id.setText(""+temp);
But It Returns 0!
I Don't Have any SQL error.
Did I Use It Wrong?
or ?
Thanks For Help.
You have a few problems here, one of which is that in your current code you aren't actually accessing the max(id) which you put in the query. One way around this is to assign an alias:
PreparedStatement stat;
ResultSet rs;
String sql = "SELECT MAX(id) AS max_id FROM home";
stat = conn.prepareStatement(sql);
rs = stat.executeQuery();
if (rs.next()) {
returned = rs.getInt("max_id") + 1;
}
This fixes the syntax problem, but there is still the problem of whether this is the best way to get the next id. I would recommend that you switch to using an auto increment column, which MySQL will manage for you. Then, you don't need to worry about keeping track of the latest ID value. In fact, you don't even need to specify a value when inserting; the database will handle this for you.
Related
I am facing a problem with retrieving a column from database
This is my code
public String ShowtimeQur(int MovieID)
{
rs3 = null;
String RoomID=null;
String ShowTime = null;
try
{
String qu ="Select Room_ID from Movie_Shows_in where Movie_ID="+MovieID;
//getRoomQur.setInt(1, MovieID);
rs3=getRoomQur.executeQuery(qu);
RoomID=rs3.getString("Room_ID");
getShowtimequr.setString(1, RoomID);
rs4=getShowtimequr.executeQuery();
ShowTime=rs4.getString("Show_Times");
}
catch (SQLException e)
{
e.printStackTrace();
}
return ShowTime;
}
I keep get this type of error
java.sql.SQLException: Invalid operation at current cursor position.
Use PreparedStatement.
PreparedStatement statement = con.prepareStatement("Select Room_ID from Movie_Shows_in where Movie_ID=?");
statement.setInt(1, MovieID);
ResultSet res = statement.executeQuery()
...
rest of your code
Never, never, never use string concatenation to build queries, as you put yourself at risk of SQL Injection
Like the answer before, you shoud declare a "ResulSet result" variable, and after the execute of the query, you should call "result.next()" method to point the cursor on the first row (initially is pointed to row 0 which does not exist) and then call a retrive data mehod like "result.getString(columnNumber)" by example.
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.
I've been trying to figure out what's wrong with the resultset for the past 2 hours. I'm trying to connect to a MS Access database, and I have a similar working method that is almost exactly the same except the sql statements are different. Since the sql statement highlights everything in the table, I assumed the resultset would work, but apparently not. Can anyone give me a pointer?
Here's my code:
public static Video[] searchdatabase(String videoname, String uploadername, int likes, int dislikes, int favorites, int subscribers,int views, String category) throws SQLException
{
String sql = "SELECT COUNT(VideoID) AS Num FROM tblYoutubeVideo";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
rs.next();
int numrows = rs.getInt("Num");
System.out.println("Numrows: "+numrows);
Video[] arr2 = new Video[numrows];
sql = ("SELECT * FROM tblVideo, tblUploader WHERE tblVideo.Video_Name LIKE '"+videoname+"' AND tblUploader.Uploader_Name LIKE '"+uploadername+"'AND tblVideo.Views>"+views+" AND tblVideo.Likes>"+likes+" AND tblVideo.Dislikes<"+dislikes+" AND tblVideo.Favorites>"+favorites+" AND tblUploader.Subscribers>"+subscribers+"ORDER BY (Likes+(Views*0.5)+(Favorites*2)+(Subscribers*2))-2");
System.out.println(sql);
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
for (int i=0;i<arr2.length;i++)
{
rs.next();
int uploaderid2 = rs.getInt("UploaderID");
String uploader_name2 = rs.getString("Uploader_name");
int subscribers2 = rs.getInt("Subscribers");
int videoid2 = rs.getInt("VideoID");
String video_name2 = rs.getString("Video_name");
int favorites2 = rs.getInt("Favorites");
String category2 = rs.getString("Category");
int views2 = rs.getInt("Views");
int likes2 = rs.getInt("Likes");
int dislikes2 = rs.getInt("Dislikes");
Video temp = new Video(uploaderid2, uploader_name2, subscribers2, videoid2, video_name2, favorites2, category2, views2, likes2, dislikes2);
System.out.println(arr2[i]);
arr2[i] = temp;
}
return arr2;
}
Thanks in advance :)
I suspect the problem is here:
rs.next();
You're ignoring the return value of next(), which tells you whether or not you've actually moved onto another valid row, or whether you've reached the end of the results. You're currently assuming that you have numrows results, even though numrows is the number of rows in tblYoutubeVideo and your actual query is filtered.
I would personally remove the first query completely - just use an ArrayList<Video> instead, and instead of your for loop, have:
List<Video> videos = new ArrayList<Video>();
while (rs.next())
{
... read data ...
videos.add(new Video(...));
}
Additionally, not that your current code is vulnerable to SQL injection attacks. Rather than include values directly in your SQL, you should use parameterized SQL with PreparedStatement. You specify placeholders in the SQL itself, and set the parameter values in the statement.
Additionally, you should be closing the statement and result set in finally blocks. (I'd personally close the connection, too - use a connection pool so that you can always open the connection, use it, and close it.)
I'm writing data from Java to an Access database on Windows 32 bit. When I write a record, I need to retrieve the row ID / primary key so that I can a) update the record easily if I want to and b) cross reference other data to that record.
When did something similar in C, I could make a updatable cursor which allowed me to write a new record and simultaneously retrieve the row ID. With Java, it looks as though I should be able to do this, but it throws an exception with the following code.
con = openAccessDatabase();
String selectString = "SELECT ID, RunCount FROM SpeedTable";
try {
PreparedStatement selectStatement = con.prepareStatement(selectString,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet idResult = selectStatement.executeQuery();
int id;
for (int i = 0; i < nWrites; i++) {
idResult.moveToInsertRow();
idResult.updateObject(1, null); // this line makes no difference whatsoever !
idResult.updateInt(2, i);
idResult.insertRow(); // throws java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]Error in row
id = idResult.getInt(1);
}
selectStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
The only thing I've been able to do is to write a new record and then run a different query to get the Row id back ...
String insertString = "INSERT INTO SpeedTable (RunCount) VALUES (?)";
String idString = "SELECT ID FROM SpeedTable ORDER BY ID DESC";
//
try {
ResultSet idResult = null;
PreparedStatement preparedStatement, idStatement;
preparedStatement = con.prepareStatement(insertString,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
idStatement = con.prepareStatement(idString,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
for (int i = 0; i < nWrites; i++) {
// write the data into the database
preparedStatement.setInt(1, i);
preparedStatement.execute();
// re-run the query to get the index back from the database.
idResult = idStatement.executeQuery();
idResult.next();
int lastIndex = idResult.getInt(1);
idResult.close();
}
This works but becomes impossibly slow when the table has more than a few 10's of 1000's of records in it. There is also a risk of returning the wrong ID if two parts of the program start writing at the same time (unlikely but not impossible).
I know that at least one suggestion will be to either not use Java or not use Access, but they are not options. It's also part of a free open source software package, so I'm reluctant to pay for anything. Writing my own C JNI interface which provides the basic functionality that I need for my application is even less appealing.
Not sure if this works for MS Access but you can try:
st.executeUpdate("INSERT INTO SpeedTable (RunCount) VALUES (1000)", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = st.getGeneratedKeys();
rs.next();
long id = rs.getLong(1);
I have following code:
public boolean updateDatabase(long houseValue, List<Users> userList)
{
boolean result = false;
Connection conn = null;
PreparedStatement stmtUpdateUsers = null;
PreparedStatement stmtQueryHouse = null;
PreparedStatement stmtUpdateHouse = null;
ResultSet rs = null;
String updateUsers = "UPDATE users SET money = ? WHERE username = ?";
String queryHouse = "SELECT * FROM house WHERE house_id = ?";
String updateHouse = "UPDATE house SET house_money = ? WHERE house_id = ?";
try
{
conn = getConnectionPool().getConnection();
conn.setAutoCommit(false);
stmtUpdateUsers = conn.prepareStatement(updateUsers);
...
// Here is some code that updates Users table in a short loop
...
stmtQueryHouse = conn.prepareStatement(queryHouse);
stmtQueryHouse.setInt(1, 1);
rs = stmtQueryHouse.executeQuery();
if(rs.next())
{
long houseMoney = rs.getLong("house_money");
houseMoney += houseValue;
stmtUpdateHouse = conn.prepareStatement(updateHouse);
stmtUpdateHouse.setLong(1, houseMoney);
stmtUpdateHouse.setInt(2, 1);
stmtUpdateHouse.executeUpdate();
}
else
{
throw new SQLException("Failed to update house: unable to query house table");
}
conn.commit();
result = true;
}
catch(SQLException e)
{
logger.warn(getStackTrace(e));
try{conn.rollback();}catch(SQLException excep)
{
logger.warn(getStackTrace(excep));
}
}
finally
{
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(stmtQueryHouse);
DbUtils.closeQuietly(stmtUpdateUsers);
DbUtils.closeQuietly(stmtUpdateHouse);
try { conn.setAutoCommit(true); } catch (SQLException e) { /* quiet */ }
DbUtils.closeQuietly(conn);
}
return result
}
This method can be called from multiple threads, house table is just a one row table which holds total earned money. It gets updated by different threads.
Problem is that stmtQueryHouse.executeQuery() returns empty set, and it should not happen, because house table always have (since database creation) one single row that gets updated (only house_money column is updated).
When I run this code on windows (JDBC driver + mysql 5.5.13) it works fine, but when I run it on CentOS (same JDBC driver + mysql 5.1.57) it returns empty result set very often (if not always). Any idea what is going wrong or how could I check where is the problem? Maybe I should use select for update, but then why it works on windows and not on linux? I appreciate any help. Thanks in advance.
Look in the mysql general query log for any errors?
I realize this isnt your question per se, but if you have another table with just a single row for each House, it sounds to me that it would make more sense to move house_money into your main house table
I'd say this one method is doing far too much.
I'd pass in the Connection to three separate methods and manage the transaction outside all of them.
I'd wonder if there's an optimization that would eliminate one of the UPDATES.
I'd want to batch all these so I didn't do a round trip for each and every user. It'll perform poorly as the # of users increases.