Java 准备好的语句失败,但SQL控制台工作

Java 准备好的语句失败,但SQL控制台工作,java,sql,tomcat,prepared-statement,derby,Java,Sql,Tomcat,Prepared Statement,Derby,我正在为uni做一个项目(刚好14小时后到期),我正处于一个关键点。它是一个基于web的web商店,在ApacheTomcat和derby上的eclipse中运行 我有一个准备好的语句,用于检查用户名和密码哈希,无论我尝试什么,该语句都返回0行。相同的sql在sql草稿行中运行,并返回预期结果 我已经使用调试器检查了准备好的语句对象,查询似乎很好。文本中的“?”仍然存在,而不是充满了变量,但这似乎很正常。我还尝试从控制台运行完全相同的手写sql,但没有任何运气 我在sql控制台中运行的查询是 S

我正在为uni做一个项目(刚好14小时后到期),我正处于一个关键点。它是一个基于web的web商店,在ApacheTomcat和derby上的eclipse中运行

我有一个准备好的语句,用于检查用户名和密码哈希,无论我尝试什么,该语句都返回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);
我已经尝试了所有的方法,并且已经没有搜索了。我知道这是一个uni项目,标准的回答是给人们找个地方看看。在这一点上,我需要勺子饲料的路径下去

编辑下面是一些背景信息,我尝试在这个管道中运行一个已知的工作查询,但它也无法返回任何行

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;
}
公共静态用户getUser(字符串用户名、字符串密码哈希){
DBBean db=newdbbean();
System.out.println(“登录用户名”+username+“和密码”+passwordHash);
试一试{
结果集rs;
PreparedStatement pstmt=db.prepareStatement(“从reallynice.username中选择*”+
“其中emailaddress=?”+
“和passwordhash=?”;
pstmt.setString(1,用户名);
pstmt.setString(2,密码哈希);
//PreparedStatement pstmt=db.prepareStatement(“从reallynice.product中选择*);
//PreparedStatement pstmt=db.prepareStatement(“从reallynice.username中选择*,其中emailaddress=”user@me.com'和passwordhash='megahashstring'”;
rs=pstmt.executeQuery();
System.out.println(“返回的行\t”+rs.getRow());
如果(rs.getRow()<1)
返回null;
int id=rs.getInt(“uid”);
字符串名称=rs.getString(“名称”);
String emailaddress=rs.getString(“emailaddress”);
字符串密码=rs.getString(“密码哈希”);
布尔值isAdmin=false;
pstmt=db.prepareStatement(“从reallnice.admin中选择*其中uid=?”;
pstmt.setInt(1,id);
rs=pstmt.executeQuery();
如果(rs.getMetaData().getColumnCount()>0)
isAdmin=true;
返回新用户(id、isAdmin、姓名、电子邮件地址、密码);
}捕获(例外情况除外){
系统输出打印项次(ex);
}
返回null;
}

我还包括了我为此尝试过的其他查询。

每当我看到有人有这样的经历:“无论我尝试什么,此语句返回0行”,我都会立即想到两个可能的原因:

1) 你没有使用你认为自己在使用的数据库。Derby的连接URL,如果您说“create=true”,当您连接时,如果在您期望的位置找不到现有的数据库,它将非常乐意创建一个新的空数据库。这类问题源于对数据库创建位置的混淆;将在获取该连接URL的derby实例的derby.system.home目录中创建具有相对名称的数据库。因此,请检查您是否正在使用不同的当前工作目录,或者出于其他原因正在连接到与您想象中不同的数据库


2) 您没有使用您认为的模式。Derby很乐意创建多个模式,每个模式都有一组单独的表,因此,如果您最初以用户a的身份连接,然后以用户B的身份连接,并且不发布集合模式,那么用户a和用户B就有完全独立的表集,因此您不会访问您认为是的表。因此,在连接到数据库时,请检查您是否以相同的用户身份连接并使用相同的模式。

尝试更改日志记录语句的显示方式

System.out.println("Rows returned\t" + rs.getRow());
返回当前行号,而不是返回的记录数。为了使用getRow()计算结果集中的条目数,需要将结果集的指针移动到最后一个条目

您还没有打过电话,这意味着您没有指向任何东西(很可能是因为您总是将0视为数字)。试用

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

因此,总的来说,如果您将代码更改为以下内容,您可能会获得更好的结果

rs = pstmt.executeQuery();
if(rs.next()){
    System.out.println("Processing Row " + rs.getRow());
    //continue on
}else{
    System.out.println("No Records");
}
如果您已将表中的用户名设置为唯一键,则可以确定这将返回0或1行。否则,请使用while()选项而不是if()

编辑:: 另请注意,因为您没有调用next()

if(rs.getRow()<1)
返回null;

将始终为0,这将从您的方法返回null。

您意识到您正在根据用户名查询的sql语句和您正在根据电子邮件地址查询的准备好的语句吗?您可能需要回退变量,然后仅尝试“select*from reallynice.username”来验证您是否有有效的连接,等等。然后对值进行硬编码。一旦你回到那里,继续讨论替换问题。也许可以通过将你的语句提取到所需的最小值来开始调试这个问题。从reallynice中删除除选择*之外的所有内容;在返回结果之后,添加用户名参数,最后添加密码参数。(可能是一些输入错误,但您在准备的语句中的查询与控制台版本不匹配。)@Sam Yeah,这是我在这里输入的一个错误,它们在系统中匹配。其他针对数据库的查询工作正常,因此似乎存在连接。我将尝试在此管道中运行工作查询。编辑运行已知的工作查询
rs = pstmt.executeQuery();
if(rs.next()){
    System.out.println("Processing Row " + rs.getRow());
    //continue on
}else{
    System.out.println("No Records");
}
if(rs.getRow() < 1)
            return null;