Подготовленный оператор не выполняется, но консоль SQL работает - PullRequest
0 голосов
/ 06 мая 2011

Я работаю над проектом для универа (это должно произойти через 14 часов), и я нахожусь в тупике. Это веб-магазин, работающий в eclipse на Apache Tomcat и Derby.

У меня есть подготовленный оператор, который проверяет имя пользователя и хэш пароля, независимо от того, что я пробую, этот оператор возвращает 0 строк. Тот же sql запускается в блокноте sql и возвращает ожидаемое.

Я использовал отладчик для проверки подготовленного объекта оператора, и запрос выглядит нормально. Символы? В тексте все еще на месте, а не заполнены переменными, но это кажется нормальным. Я также пытался запустить точно такой же рукописный sql из консоли, но безуспешно.

Запрос, который я запускаю в консоли sql:

SELECT * FROM username WHERE username='user@system.com' AND passwordhash='passwordhash'

Подготовленные отчеты выглядят так.

            PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username " +
                "WHERE emailaddress=?" +
                " AND passwordhash=?");

        pstmt.setString(1,username);
        pstmt.setString(2, username + ":" + passwordLogin);

Я нахожусь в точке, где я перепробовал все, и у меня закончились поиски. Я знаю, что это уникальный проект, и стандартный ответ - дать людям где-нибудь посмотреть. На данный момент мне нужно кормить ложкой путь вниз.

РЕДАКТИРОВАТЬ Вот еще кое-что, я попытался выполнить известный рабочий запрос в этом конвейере, и он также не может вернуть строки.

public static User getUser(String username, String passwordHash) {
    DBBean db = new DBBean();
    System.out.println("Logging in for username " + username + " and password " + passwordHash);
    try {
        ResultSet rs;

        PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username " +
                "WHERE emailaddress=?" +
                " AND passwordhash=?");

        pstmt.setString(1,username);
        pstmt.setString(2,passwordHash);
        //PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.product");

        //PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username WHERE emailaddress='user@me.com' AND passwordhash='megahashstring'");

        rs = pstmt.executeQuery();
        System.out.println("Rows returned\t" + rs.getRow());

        if(rs.getRow() < 1)
            return null;

        int id = rs.getInt("uid");              
        String name = rs.getString("name");
        String emailaddress = rs.getString("emailaddress");
        String password = rs.getString("passwordhash"); 
        boolean isAdmin = false;

        pstmt = db.prepareStatement("SELECT * FROM reallnice.admin WHERE uid= ?");
        pstmt.setInt(1, id);
        rs = pstmt.executeQuery();

        if(rs.getMetaData().getColumnCount() > 0)
            isAdmin = true;
        return new User(id,isAdmin,name,emailaddress,password);

    } catch(Exception ex) {
        System.out.println(ex);
    }


    return null;
}

Я также включил другие запросы, которые я пробовал для этого.

Ответы [ 2 ]

1 голос
/ 06 мая 2011

Всякий раз, когда я вижу, что кто-то испытывает подобное: «независимо от того, что я пытаюсь, это утверждение возвращает 0 строк», сразу приходят на ум две возможные причины:

1) Вы не используетебаза данных, которую вы думаете, что вы есть.URL-адрес подключения Derby, если вы скажете «; create = true», будет очень рад создать новую пустую базу данных при вашем подключении, если он не найдет существующую базу данных в ожидаемом вами месте.Такая проблема возникает из-за путаницы в том, где создаются базы данных;база данных с относительным именем будет создана в любом каталоге, являющемся be derby.system.home экземпляра Derby, который получает этот URL-адрес соединения.Поэтому проверьте, используете ли вы другой текущий рабочий каталог или по какой-то другой причине подключаетесь к другой базе данных, чем вы думаете.

2) Вы не используете схему, которой, как вы думаете, вы пользуетесь,Derby с радостью создаст несколько схем, и каждая схема имеет отдельный набор таблиц, поэтому, если вы изначально подключаетесь как пользователь A, а затем подключаетесь как пользователь B, и не запускаете SET SCHEMA, тогда пользователь A и пользователь BУ вас есть совершенно разные наборы таблиц, и вы не будете получать доступ к тем таблицам, которые вам нужны.Поэтому проверьте, подключаетесь ли вы с тем же пользователем и используете ту же схему при подключении к базе данных.

0 голосов
/ 06 мая 2011

Попробуйте изменить способ отображения оператора ведения журнала.

System.out.println("Rows returned\t" + rs.getRow());

getRow () возвращает номер текущей строки, а не количество возвращенных записей.Чтобы пользователь getRow () мог подсчитать количество записей в наборе результатов, вам нужно переместить указатель набора результатов на последнюю запись.

Вы также не вызвали next () пока, что означает, что вы ни на что не указываете (и, скорее всего, причина, по которой вы всегда видите 0 в качестве числа).Попробуйте использовать

while(rs.next()){ //go through the entire ResultSet} 

или

if(rs.next()) { //access the first record in the ResultSet}

Таким образом, если вы измените свой код на что-то вроде следующего, у вас могут быть лучшие результаты.Если вы установили таблицу, в которой имя пользователя является уникальным ключом, вы можете быть уверены, что это вернет 0 или 1 строку.В противном случае используйте параметр while () вместо if ()

EDIT :: Также как примечание, поскольку вы не вызываете next ()

if(rs.getRow() < 1)
            return null;

всегда будет 0, что возвращает ноль из вашего метода.

...