准备好的语句失败,但 SQL 控制台可以工作
我正在为大学做一个项目(恰好要在 14 小时内截止),但我正处于困境。它是一个基于 Web 的网络商店,在 apache tomcat 和 derby 上的 eclipse 中运行。
我有一个准备好的语句来检查用户名和密码哈希,无论我尝试什么,该语句都会返回 0 行。相同的 sql 在 sql 暂存器中运行并返回预期的结果。
我已使用调试器检查准备好的语句对象,查询看起来很好。文本中的 ? 仍然存在,而不是填充变量,但这似乎很正常。我还尝试从控制台运行完全相同的手写 SQL,但没有任何运气。
我在 sql 控制台中运行的查询是
SELECT * FROM username WHERE username='[email protected]' 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='[email protected]' 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;
}
我还包括了我为此尝试过的其他查询。
I am working on a project for uni (happens to be due in 14 hours) and I am at a sticking point. It is a web based web store running in eclipse on apache tomcat and derby.
I have a prepared statement that checks for a user name and passwordhash, no matter what I try this statement returns 0 rows. The same sql runs in the sql scratch pad and returns what is expected.
I have used the debugger to inspect the prepared statement object and the query seems fine. The ?'s in the text are still in place rather than filled with the variables, but that seems normal. I have also tried to run the exact same hand written sql from the console, but without any luck.
The query I run in the sql console is
SELECT * FROM username WHERE username='[email protected]' AND passwordhash='passwordhash'
The prepared statments look like this.
PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username " +
"WHERE emailaddress=?" +
" AND passwordhash=?");
pstmt.setString(1,username);
pstmt.setString(2, username + ":" + passwordLogin);
I am at the point where I have tried everything, and have run out of searches to make. I know this is a uni project and the standard reply is to give people somewhere to look. At this point I need spoon feed a path to go down.
EDIT Here is some more background, I have tried running a known working query in this pipeline and it also fails to return any rows.
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='[email protected]' 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;
}
I have also included the other queries I have tried for this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
每当我看到有人有这样的经历:“无论我尝试什么,这条语句都会返回 0 行”,我会立即想到两个可能的原因:
1)您没有使用您认为的数据库。如果您说“;create=true”,Derby 的连接 URL 会在您连接时非常高兴地创建一个新的空数据库(如果它在您期望的位置找不到现有数据库)。此类问题源于对数据库创建位置的混淆;具有相对名称的数据库将在获取该连接 URL 的 Derby 实例的 derby.system.home 目录中创建。因此,请检查您是否正在使用不同的当前工作目录,或者是否由于其他原因连接到了与您想象的不同的数据库。
2)您没有使用您认为的模式。 Derby 会很乐意创建多个模式,并且每个模式都有一组单独的表,因此如果您最初以用户 A 的身份连接,然后以用户 B 的身份连接,并且不发出 SET SCHEMA,则用户 A 和用户 B有完全独立的表集,因此您将无法访问您认为是的表。因此,请检查您在连接到数据库时是否以同一用户身份进行连接并使用相同的架构。
Whenever I see someone having an experience like this: "no matter what I try this statement returns 0 rows," there are two possible reasons that come immediately to mind:
1) You aren't using the database you think you are. Derby's connection URL, if you say ";create=true", will quite happily make a new, empty database when you connect, if it doesn't find an existing database in the location you expect. This sort of problem arises from a confusion over where the databases are created; a database with a relative name will be created in whatever directory turns out to the be derby.system.home of the Derby instance that gets that connection URL. So check to see if you are using a different current working directory, or for some other reason are connecting to a different database than you think you are.
2) You aren't using the schema you think you are. Derby will quite happily create multiple schemas, and each schema has a separate set of tables, so if you are initially connecting as user A, and then later connect as user B, and don't issue SET SCHEMA, then user A and user B have completely separate sets of tables and so you won't be accessing the tables that you think you are. So check to see if you are connecting as the same user and using the same schema when you connect to the database.
尝试更改日志记录语句的显示方式
getRow() 返回当前行号,而不是返回了多少条记录。为了使用 getRow() 来计算结果集中的条目数,您需要将结果集的指针移动到最后一个条目。
您还没有调用 next () 但是,这意味着您没有指向任何东西(这很可能是您总是将 0 视为数字的原因)。尝试使用
or
所以总的来说,如果您将代码更改为如下所示,您可能会得到更好的结果。
如果您已将表设置为用户名作为唯一键,则可以放心这将返回 0 或 1 行。否则使用 while() 选项而不是 if()
编辑::
另请注意,因为您没有调用 next()
将始终为 0,这会从您的方法返回 null。
Try changing how you display your logging statement
getRow() returns the current row number, not how many records were returned. In order to user getRow() to count the number of entries in the result set you would need to move the pointer of the result set to the last entry.
You have also, not called next() yet, which means you aren't pointing at anything (and most likely the reason you always see 0 as the number). Try using
or
So over all, if you change your code to something like the following you may have better results.
If you have set your table where the username is a unique key, you can be assured this will return 0 or 1 row. Otherwise use the while() option instead of if()
EDIT::
Also as a side note, because you are not calling next()
will always be 0, which returns null from your method.