I am trying to pull a first name and last name from a table in my SQL database. The queries work fine in SQL without the "as First" part and I know the db connection is fine since it works in every other part of the code.
The error I receive is that table "First" does not exist, but it should be looking at firstName and lastName for the table names, not First and Last.
Its inside of a for loop with "i", but those values are correct, playerid = i exists.
try {
String query2 = " SELECT firstName as First from player "
+ "WHERE playerid = ?";
PreparedStatement st2 = db.conn.prepareStatement(query);
st2.setInt(1, i);
ResultSet rs2 = st2.executeQuery();
if (rs2.next()) {
setFirstName(rs2.getString("First"));
}
String query3 = " SELECT lastName as Last from player "
+ "WHERE playerid = ?";
PreparedStatement st3 = db.conn.prepareStatement(query);
st3.setInt(1, i);
ResultSet rs3 = st3.executeQuery();
if (rs3.next()) {
setLastName(rs3.getString("Last"));
}
}
catch (SQLException e) {
e.printStackTrace();
}
Change your code into something like this:
PreparedStatement ps = null;
try {
ps = db.conn.prepareStatement("SELECT firstName, lastName from player "
+ "WHERE playerid = ?");
for (int i = 0; i < MAX_PLAYERS /*<- or what is the loop condition?*/; i++) {
ps.setInt(1, i);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
// should these methods really be called within a loop?
setFirstName(rs.getString("firstName"));
setLastName(rs.getString("lastName"));
}
rs.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (ps != null) {
ps.close();
}
}
Some considerations:
When you're using a PreparedStatement within a loop, you should create the statement once, outside of the loop and then only re-assign the bind variable(s) during each iteration.
You should minimize the number of queries you run against the DB; in your case you should select both the first and last name column in a single query.
It is important to close the resources you open up (the PreparedStatement in this case). My example shows how this is usually done (in the finally block) pre Java 7. Use the try-with-resources statement if you're using a newer Java version.
Related
I am attempting to write a method that selects 2 entries into an employee database and removes them (Based on a salary field), I am currently using a counter to accomplish this, however I tried using setMaxRows() so my result set would only have two entries, thus eliminating the need for the counter. I am using try-with-resources to create my statement and that seems to be causing an issue.
public void downSize(Connection con) {
String sql = "SELECT * FROM " + schemaName + "."+tableName+" WHERE EMPLOYEE_SALARY>200000";
try (
PreparedStatement statement = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = statement.executeQuery();
)
{
int counter = 0;
System.out.println("Now pruning workforce...");
while(rs.next() && counter<2) {
String name = rs.getString("EMPLOYEE_NAME");
rs.deleteRow();
counter++;
System.out.println(name+" was laid off.");
}
} catch(Exception e) {
e.printStackTrace();
System.out.print("Sql exception happened");
}
}
I am trying to retrieve a data (ID No.) from a database (MySQL) and add it by one. However, when I try to put this code below, when I try to build it, the form doesn't show up. But when I try to remove the Connection cn line, the form with finally show up. I had another project with this code it it worked perfectly fine. I'm not sure why its not working on this one.
public Abstract() throws Exception {
Connection cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user?zeroDateTimeBehavior=convertToNull","root","");
initComponents();
Statement st = null;
ResultSet rs;
try {
String sql = "SELECT ID from bidding_abstractofprices";
st = cn.prepareStatement(sql);
rs = st.executeQuery(sql);
while(rs.next()){
int id = Integer.parseInt(rs.getString("ID")) + 1;
lblTransacID.setText(String.valueOf(id));
}
}catch (Exception ex){
}
}
What it looks like you are trying to do is to get the ID field value from the last record contained within the bidding_abstractofprices Table contained within your Database and then increment that ID value by one (please correct me if I'm wrong). I don't care why but I can easily assume. Here is how I might do it:
public Abstract() throws Exception {
// Allow all your components to initialize first.
initComponents();
Connection cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user?zeroDateTimeBehavior=convertToNull","root","");
Statement st = null;
ResultSet rs;
try {
String sql = "SELECT * FROM bidding_abstractofprices ORDER BY ID DESC LIMIT 1;";
st = cn.prepareStatement(sql);
rs = st.executeQuery(sql);
int id = 0;
while(rs.next()){
id = rs.getInt("ID") + 1;
}
lblTransacID.setText(String.valueOf(id));
rs.close();
st.close();
cn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
I have a strange problem. I have a database and I want to change the values of a column. The values are safed in an Arraylist (timelist).
In order to write the values in the right row, I have a second Arrylist (namelist). So I want to read the first row in my Database, than I check the namelist and find the name. Than i take the matching value out of the timelist and write it into the database into the column "follows_date" in the row, matching to the name.
And than I read the next row of the Database, until there are no more entries.
So the strange thing is, if I change nothing in the database, the while(rs.next()) part works.
For example:
ResultSet rs = statement.executeQuery("SELECT username FROM users");
while(rs.next()){
// read the result set
String name = rs.getString("username");
System.out.println("username = " + name); //liest die namen
}
}
This would print me every name after name. But when I change the table, the while loop ends after that. (no error, the program just finishes)
ResultSet rs = statement.executeQuery("SELECT username FROM users");
while(rs.next()){
// read the result set
String name = rs.getString("username");
System.out.println("username = " + name); //writes the name
//look, if name is in Arraylist "namelist"). if yes, than write the matching date from "timelist" into the database.
if (namelist.contains(name)){
System.out.println("name found: "+ name);
int listIndizi = namelist.indexOf(name); //get index
Long indiziDatum = (long) timelist.get(listIndizi); //get date from same Index
System.out.println(indiziDatum); // print date so i can see it is correct (which it is)
statement.executeUpdate("UPDATE users SET follows_date ="+ indiziDatum +" WHERE username = '"+name+"'"); //updates the follows_date column
}
}
Everything works fine, except that now, the while loop doesn't continues after the first passage, but ends.
The resultSet of a statement is closed and will not return further results if you execute another statement. Create a new separate statement object for the update and everything should work as excepted.
Statement statement1 = connection.createStatement();
Statement statement2 = connection.createStatement();
ResultSet resultSet1 = statement1.executeQuery("SELECT username FROM users");
while(resultSet1.next()){
...
statement2.executeUpdate("UPDATE users ..."));
}
As to Why it happens:
Here is the explanation from the official documentation:
A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
Alternative Approach:
From your sample, it seems you are trying to update the "same" row in your resultSet, you should consider using an Updatable ResultSet.
Sample code from the official documentation:
public void modifyPrices(float percentage) throws SQLException {
Statement stmt = null;
try {
stmt = con.createStatement();
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet uprs = stmt.executeQuery(
"SELECT * FROM " + dbName + ".COFFEES");
while (uprs.next()) {
float f = uprs.getFloat("PRICE");
uprs.updateFloat( "PRICE", f * percentage);
uprs.updateRow();
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
if (stmt != null) { stmt.close(); }
}
}
I have this method to load the objects, however when I am running the sql code it is giving me a Syntax error.
public void loadObjects() {
Statement s = setConnection();
// Add Administrators
try {
ResultSet r = s.executeQuery("SELECT * FROM Administrator;");
while (r.next()) {
Administrator getUser = new Administrator();
getUser.ID = r.getString(2);
ResultSet r2 = s.executeQuery("SELECT * FROM Userx WHERE ID= {" + getUser.ID + "};");
getUser.name = r2.getString(2);
getUser.surname = r2.getString(3);
getUser.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(getUser);
}
} catch (Exception e) {
System.out.println(e);
}
}
I have tried inserting the curly braces as stated in other questions, but I am either doing it wrong or it doesn't work.
This method should be able to load all administrators but I believe it is only inserting half of the ID.
The ID that it gets, consists of numbers and char; example "26315G"
the Error -
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '26315'.
Edit -
private java.sql.Connection setConnection(){
java.sql.Connection con = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url = "jdbc:sqlserver://" + host + ";DatabaseName=" + database + ";integratedSecurity=true;";
con = DriverManager.getConnection(url, username, password);
} catch(Exception e) {
System.out.println(e);
}
return con;
}
public void loadObjects() {
java.sql.Connection con = setConnection();
// Add Administrators
try {
PreparedStatement sql = con.prepareStatement("SELECT * FROM Administrator");
ResultSet rs = sql.executeQuery();
while (rs.next()) {
Administrator getUser = new Administrator();
getUser.ID = rs.getString(2);
PreparedStatement sql2 = con.prepareStatement("SELECT * FROM Userx WHERE ID=?");
sql2.setString(1, getUser.ID);
ResultSet r2 = sql2.executeQuery();
getUser.name = r2.getString(2);
getUser.surname = r2.getString(3);
getUser.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(getUser);
}
} catch (Exception e) {
System.out.println(e);
}
}
Actually it is not the way to do that in JDBC. That way, even if you sort your syntax error, your code is prone to sql injection attacks.
The right way would be:
// Let's say your user id is an integer
PreparedStatement stmt = connection.prepareStatement("select * from userx where id=?");
stmt.setInt(1, getUser.ID);
ResultSet rs = stmt.executeQuery();
This way you are guarded against any attempt to inject SQL in your application request parameters
First of all: if you use concurrently result-sets, you must use separate statements for each one of them (you can not share Statement s between two r and r2). And more, you lack r2.next() before reading from it.
On the other hand: it would be much more effective to use PreparedStatement in the loop that to rewrite the query all the time.
So I'd go for something like this:
public void loadObjects() {
try (
Statement st = getConnection().createStatement();
//- As you read (later) only id, then why to use '*' in this query? It only takes up resources.
ResultSet rs = st.executeQuery("SELECT id FROM Administrator");
PreparedStatement ps = getConnection().prepareStatement("SELECT * FROM Userx WHERE ID = ?");
ResultSet r2 = null;
) {
while (rs.next()) {
Administrator user = new Administrator();
user.ID = rs.getString("id");
ps.setInt(1, user.ID);
r2 = ps.executeQuery();
if (r2.next()) {
user.name = r2.getString(2);
user.surname = r2.getString(3);
user.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(user);
}
else {
System.out.println("User with ID=" + user.ID + " was not found.");
}
}
}
catch (Exception x) {
x.printStacktrace();
}
}
Please note use of Java7 auto-close feature (you didn't close resources in you code). And last note: until you are not separating statements in your queries, as to JDBC documentation, you should not place ';' at the end of statements (in all cases you shouldn't place ';' as the last character in you query string).
You should not use {} and you should not append parameters into a SQL query like this.
Remove the curly braces and use PreparedStatement instead.
see http://www.unixwiz.net/techtips/sql-injection.html
I am having many rows in table and I ran the same query on my database which is MySql but java ResultSet is only giving the first row of the table. Here is my code.
public ArrayList<String> getAllAlbumsName(Integer uid) {
ArrayList<String>allAlbumsName = new ArrayList<String>();
try {
String qstring = "SELECT albumname FROM picvik_picture_album WHERE " +
"uid = '" + uid + "';";
System.out.println(qstring);
connection = com.picvik.util.MySqlConnection.getInstance().getConnection();
ptmt = connection.prepareStatement(qstring);
resultSet = ptmt.executeQuery();
if(resultSet.next()) {
System.out.println(resultSet.getString("albumname"));
allAlbumsName.add(resultSet.getString("albumname"));
}
resultSet.close();
ptmt.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
return allAlbumsName;
}
if(resultSet.next()) {
System.out.println(resultSet.getString("albumname"));
allAlbumsName.add(resultSet.getString("albumname"));
}
If you would like to get all rows, it should be:
while(resultSet.next()) {
System.out.println(resultSet.getString("albumname"));
allAlbumsName.add(resultSet.getString("albumname"));
}
The while statement continually executes a block of statements while a particular condition is true
Note: As #BalusC commented, your code would introduce SQL Injection attack, it is better to use ptmt.set... Instead of constructing SQL String manually.
try while(resultSet.next()) {
instead of if (resultSet.next()) {
Change if (resultSet.next()) { to while (resultSet.next()) {