0

I have the code to select msg_id and increment it from my database name final client from table msg but when I run, it says that Failed to Select from DBjava.sql.SQLException: Column 'msg_id' not found

int maxid;
try {
    Class.forName("com.mysql.jdbc.Driver");
    Class.forName("com.mysql.jdbc.Driver");

    Connection con = DriverManager.getConnection("jdbc:mysql://localhost/finalclient","root","");

    PreparedStatement st = con.prepareStatement("select *from msgs order by msg_id desc");
    ResultSet r1=st.executeQuery();

    maxid = r1.getInt("msg_id") + 1;

    System.out.println(r1.getInt("msg_id"));
    System.out.println(maxid);                  
}
catch (Exception e) {
    System.out.println("Failed to Select from DB"+e);
}

Any idea what is wrong?

Chris Hayes
  • 11,471
  • 4
  • 32
  • 47

4 Answers4

0

Initially the resultset's cursor is positioned before the first row. You need to move the cursor to the first record before you can get any values:

ResultSet r1 = st.executeQuery();
r1.first(); // or r1.next()
maxid = r1.getInt("msg_id") + 1;

On a slightly different note, your query is fairly inefficient. Probably would be better to do:

SELECT MAX(msg_id) as max_id FROM msgs
Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
0

Your attempt is absolutely not the correct idiom to generate numeric ids

What you are doing is a very naive attempt and will not work with more than one client or more than one thread accessing the database.

Primary keys should be immutable, as in you can't change them once they are created, otherwise data corruption becomes rampant as foreign keys become orphans for example.

Correct Idiom

  1. Use an auto-increment column for your primary key.
  2. Learn SQL properly and learn to use more efficient SQL statement: SELECT MAX(msg_id) as maxid FROM MSG as in the example below, but an auto-increment key is the correct way.
  3. There is no reason to use a PreparedStatement if there are no parameters you need to pass in.
  4. Don't use 10 year old books, tutorials or examples from the web that do things like your example.

That said, you are very close, here is what your code should look like to fix your code that is posted, but keep in mind this is the wrong to do what you are trying to accomplish:

Q26227752.java

import java.sql.*;

public class Q26227752
{
    public static void main(final String[] args)
    {
        try
        {
            final Connection cn = DriverManager.getConnection("jdbc:mysql://localhost/finalclient", "root", "");
            try
            {
                final Statement ps = cn.createStatement();
                try
                {
                    final ResultSet rs = ps.executeQuery("SELECT MAX(msg_id) as maxid FROM msgs");
                    try
                    {
                        // always check to see if something was actually returned
                        if (rs.next())
                        {
                            final int maxid = rs.getInt("maxid");
                            System.out.format("maxid = %d\n", maxid);
                            System.out.format("nextid = %d\n", maxid + 1);
                        }
                        else
                        {
                            throw new SQLException("No rows returned for \"SELECT MAX(msg_id) FROM msgs\"");
                        }
                    }
                    catch (final SQLException e)
                    {
                        throw new RuntimeException(e);
                    }
                    finally
                    {
                        try { rs.close(); } catch (final SQLException e) { System.err.print(e.getMessage()); }
                    }
                }
                catch (final SQLException e)
                {
                    throw new RuntimeException(e);
                }
                finally
                {
                    try { ps.close(); } catch (final SQLException e) { System.err.print(e.getMessage()); }
                }
            }
            catch (final SQLException e)
            {
                throw new RuntimeException(e);
            }
            finally
            {
                try { cn.close(); } catch (final SQLException e) { System.err.print(e.getMessage()); }
            }
        }
        catch (final SQLException e)
        {
            throw new RuntimeException(e);
        }
    }
}

Notes:

As per this answer.

The DriverManager methods getConnection and getDrivers have been enhanced to support the Java Standard Edition Service Provider mechanism. JDBC 4.0 Drivers must include the file META-INF/services/java.sql.Driver. This file contains the name of the JDBC drivers implementation of java.sql.Driver. For example, to load the my.sql.Driver class, the META-INF/services/java.sql.Driver file would contain the entry:

my.sql.Driver Applications no longer need to explicitly load JDBC drivers using Class.forName(). Existing programs which currently load JDBC drivers using Class.forName() will continue to work without modification.

Always close resources correctly:

You MUST always get in a habit of the hierarchy of try/catch/finally blocks when dealing with external resources like database connections, statements and what not. Java 7+ has enhanced syntactic sugary ways of dealing with them, but the principal is the same.

Use a proper primary key generator supported by your RDBMS

CREATE TABLE msgs
(
  msg_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);

SELECT * is never correct:

SELECT * is a very lazy and dangerous way to write SQL SELECT statements.

Especially if you use column numbers instead of names, if the table changes order of the columns and the types are the same you will silently corrupt your data.

Only selecting the columns you need is explicit, and explicit is always better than implicit!

It is also inefficient if there are lots of columns that are large and you don't need.

As always complete examples are available at my GitHub repository of answers and example code.

Community
  • 1
  • 1
  • 2
    This answer would be a lot easier to understand if you made it _use_ the try-with-resources feature of Java 7 that you referenced. That's _a lot_ of nested try/catch. – William Price Oct 07 '14 at 06:04
0

In mysql primary key should use autoincrement column where when you insert in table the it is automatically taken care of incrementing that column by 1 and there is no need to get max and increment by one and mysql does it for you.

http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html

Sandeep Vaid
  • 1,409
  • 11
  • 7
0
  • You can set msg_id as a auto increment in DB. Then no need to worry about msg_id. You have to pass only message related data excluding id. DBMS take care of msg_id.
  • If you want to handle auto increment by manually then use this query. SELECT MAX(msg_id) as next_id FROM msgs.
  • You also try any ORM package like Hibernate, JPA.
Damith Ganegoda
  • 4,100
  • 6
  • 37
  • 46