Я делаю программу посещаемости с java и mySQL, и она не работает со мной. Вот код: - PullRequest
0 голосов
/ 08 января 2020

Есть две таблицы, EntryTable и ExitTable. Оба имеют похожие столбцы: id, date, time. Когда сотрудник нажимает на карту, эта функция вызывается. Если он уже пробил в этот день, его запись заносится в таблицу выхода. В противном случае он вводится в таблицу ввода.

public int addEntryRecord(String id) {

    try{
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/Attend","rt","rt");
        Statement stmt = con.createStatement();

        long millis=System.currentTimeMillis();
        java.sql.Date date=new java.sql.Date(millis);
        Date today = new Date();
        Date currentTime = new java.sql.Time(today.getTime());

        stmt.executeQuery("SELECT id from Attend.EntryTable WHERE EntryTable.id ='"+id+"'and   
        EntryTable.DayOf='"+date+"'");                       
        ResultSet rs = stmt.getResultSet();
        System.out.println(rs.next());

        if(rs.next()== true){
            String sql = "INSERT Attend.ExitTable VALUES('"+id+"','"+date+"','"+currentTime+" ')";
            stmt.executeUpdate(sql);
            System.out.println("Good job");
           }

        else{
            String sql ="INSERT Attend.EntryTable VALUES('"+id+"','"+date+"','"+currentTime+"')";
            stmt.executeUpdate(sql);
            System.out.println("Entry noted");
           }
       }catch (Exception e) {
            System.out.println(e);
        }
        return 0;
    }

Ошибка в том, что запись всегда в ExitTable, и я не знаю почему. Пожалуйста помоги.

Ответы [ 2 ]

6 голосов
/ 08 января 2020

У вас есть несколько проблем в вашем коде.

Fist of all ResultSet.next () не повторяется. Если вы напишите:

System.out.println(rs.next());

Следующий вызов rs.next () может быть ложным (если запись была только одна, как в вашем случае)

Если вам нужно это сделать, лучше сделать:

boolean next = rs.next();
System.out.println( next );
if ( next ) {  

Тогда я бы предложил использовать подготовленное утверждение, а не утверждение, когда вам нужно заменить параметры:

Подготовленное утверждение Javado c

Плюс в следующий раз, когда публикуется sh схема таблицы, сравнение времени может быть непростым, проверяли ли вы, что используете правильные типы дат? (например, дата, а не отметка времени?) В любом случае comaprison будет работать лучше, если вы используете подготовленное утверждение.

Я бы добавил, что вы никогда не закрывали ресурсы (что неверно в большинстве случаев).

Вот краткий пример, который я попробовал локально и работаю в моей системе:

    /*

Схема базы данных:

СОЗДАЙТЕ БАЗУ ДАННЫХ;

ПРЕДОСТАВЛЯЙТЕ ВСЕ ПРИВИЛЕГИИ НА ПОСЕТИТЬ. * TO rt, идентифицированный 'Tester_2020';

CREATE TABLE EntryTable (id VARCHAR (100) NOT NULL, DayOf DATE NOT NULL, TimeOf TIME NOT NULL);

CREATE TABLE ExitTable (id VARCHAR (100) NOT NULL, DayOf DATE NOT NULL, TimeOf TIME NOT NULL);

 */

/*
 * Use an external method to access the connection, better in an external data source or factory.
 */
public Connection getConnection() throws Exception {
    Class.forName("com.mysql.jdbc.Driver");
    return DriverManager.getConnection("jdbc:mysql://localhost:3306/Attend", "rt", "Tester_2020");
}

/*
 * Usually is better to use a logging facility (slf4j, log4j, java.util.logging etc.)
 */
public void log( String message ) {
    System.out.println( message );
}

/*
 * Better not to suppress exception usually
 */
public int addEntryRecordPS(String id) throws Exception {
    // using try with resources to delegate closing connection.
    try ( Connection con = getConnection() ) {
        long millis = System.currentTimeMillis();
        java.sql.Date date = new java.sql.Date(millis);
        Date today = new Date();
        Time currentTime = new java.sql.Time(today.getTime());
        try ( PreparedStatement checkPstm = con.prepareStatement( "SELECT id from Attend.EntryTable WHERE EntryTable.id = ? and EntryTable.DayOf = ?") ) {
            checkPstm.setString( 1 , id );
            checkPstm.setDate( 2 , date );
            try ( ResultSet rs = checkPstm.executeQuery() ) {
                boolean next = rs.next();
                log( "hasNext? : "+next );
                if ( next ) {
                    // again try with resource (no need to close pstm)
                    try ( PreparedStatement pstm = con.prepareStatement( "INSERT INTO Attend.ExitTable ( id, DayOf, TimeOf ) VALUES ( ?, ? ,? ) " )  ) {
                        pstm.setString( 1 , id );
                        pstm.setDate( 2 , date );
                        pstm.setTime( 3 , currentTime );
                        int res = pstm.executeUpdate();
                        log("Good job "+res);
                    }
                } else {
                    // again try with resource (no need to close pstm)
                    try ( PreparedStatement pstm = con.prepareStatement( "INSERT INTO Attend.EntryTable ( id, DayOf, TimeOf ) VALUES ( ?, ? ,? ) " )  ) {
                        pstm.setString( 1 , id );
                        pstm.setDate( 2 , date );
                        pstm.setTime( 3 , currentTime );
                        int res = pstm.executeUpdate();
                        log("Entry noted "+res);
                    }
                }
            }
        }
    }
    return 0;
}

Надеюсь, что это поможет.

4 голосов
/ 08 января 2020

Вам нужно несколько пробелов

yTable.id ='"+id+"'and

, в противном случае and будет добавлено как часть id

НО

Вы в действительности следует использовать PreparedStatments и set* методы

Также

System.out.println(rs.next());

фактически продвигает ваш курсор. Если бы у вас была только одна строка, следующая rs.next вернула бы false

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...