(JAVA/SQL) ResultSet 只从 MySQL 中检索一行,而它应该检索更多行
(JAVA/SQL) ResultSet only retrieving one row from MySQL when it should retrieve more
我在 Java servlet 中从 MySQL 数据库检索数据时遇到了一些问题。作为参考,我的 Web 应用程序的构造就像一个图书馆 - 您可以签出项目,然后重新签入。
当您第一次点击 "check out" 时,您的请求将发送给管理员,我们称此人为图书管理员,他必须批准或不批准您的请求。假设我登录,挑选一些物品,然后点击 "checkout"。事情是这样的:
- 项目已添加到我的 "cart"
- 在数据库的项目主列表中,每个项目都有一个名为
STATUS
的 VARCHAR
,用于标识该项目是否为 "In Stock"
。对于我选择的每个项目,该变量都会更改为与我的用户帐户关联的唯一标识符。
- 我的请求被添加到名为
requests_list
的 table
批准、一般签到等工作正常。单击 "disapprove" 效果不佳。这是应该发生的事情:
- 请求已从
requests_list
中删除
- 请求者的 "cart" 项目被截断
- 项目本身得到声明
"In Stock"
这是正在发生的事情:
- 请求已从
requests_list
中删除
- 请求者的 "cart" 项目被截断
- 只有购物车中的第一件商品会被重新签入
这是我目前使用的代码:
stmt.execute("DELETE FROM requests_list WHERE UNIQUE_ID = '"
+ selected_ID + "'"); // this seems to work
stmt.execute("TRUNCATE TABLE checkout_" + selected_ID); // also seems to work
ResultSet all_gear = stmt
.executeQuery("SELECT * FROM gear_master_list");
while (all_gear.next()) {
if (all_gear.getString(5).equals(selected_ID)) {
stmt.execute("UPDATE gear_master_list SET STATUS = 'In Stock' WHERE ID_NUM = "
+ all_gear.getInt(6));
}
}
all_gear.close();
一些注释,用于解释一些变量:
selected_ID
- 图书管理员单击下拉菜单以访问已提出请求的用户列表。在他或她选择一个之后,该用户的唯一标识符变为 selected_ID
checkout_selected_ID
- 您的 "cart" 是数据库中的 table。这个 table 是以你的唯一 ID 命名的,所以如果我的唯一 ID 是兔子,我的 table 就是 checkout_bunnies
stmt
和它从中提取 Statement
的 Connection
都是有效且有效的
gear_master_list
是所有装备的table,all_gear.getInt(6)
引用每个装备的唯一库存编号,all_gear.getString(5)
是STATUS
我提到的变量
我尝试过不同的做法,这样代码会遍历购物车中的所有商品,更新状态,然后截断 table。这也没有用 - 它对更新状态仍然很挑剔,而且 table 不会截断。
TL;DR: 即使我使用while
循环,不止一行。这是怎么回事?有没有更好、更有效的方法来做到这一点?
这可能是一个并发修改问题 - 您的第一个查询在数据库上保持打开的游标,并且在遍历该游标时您正在对相同的数据执行更新,所有这些都在同一事务中。
你能试试这个吗?
stmt.execute("DELETE FROM requests_list WHERE UNIQUE_ID = '"
+ selected_ID + "'"); // this seems to work
stmt.execute("TRUNCATE TABLE checkout_" + selected_ID); // also seems to
// work
ResultSet all_gear = stmt
.executeQuery("SELECT * FROM gear_master_list");
List<String> gear_items = new ArrayList<>();
while (all_gear.next()) {
gear_items.add(all_gear.getString(5));
}
all_gear.close();
for (String gear_item: gear_items){
if (all_gear.getString(5).equals(selected_ID)) {
stmt.execute("UPDATE gear_master_list SET STATUS = 'In Stock' WHERE ID_NUM = "
+ all_gear.getInt(6));
}
}
stmt.close();
非常感谢 hugh 对这个问题的大力帮助 - 他的回答是正确的。我只需要做一些修改来帮助他的响应适合我的代码。
以防其他人遇到这个问题,Hugh 是对的,这是一个 并发修改 问题。但是,他的回复中有一个轻微的错字(ResultSet 在某些语句被调用之前关闭),所以我想我会 post 我修改的代码以防万一它对任何人都有帮助:
stmt.execute("DELETE FROM requests_list WHERE UNIQUE_ID = '" + selected_ID + "'"); // this seems to work
stmt.execute("TRUNCATE TABLE checkout_" + selected_ID); // also seems to work
ResultSet all_gear = stmt.executeQuery("SELECT * FROM gear_master_list");
ArrayList<Object[]> gear_items = new ArrayList<Object[]>();
while (all_gear.next()) {
Object[] added = new Object[2];
added[0] = all_gear.getString(5);
added[1] = all_gear.getInt(6);
gear_items.add(added);
}
all_gear.close();
for (Object[] gear_item : gear_items) {
if (gear_item[0].equals(selected_ID)) {
stmt.execute("UPDATE gear_master_list SET STATUS = 'In Stock' WHERE ID_NUM = " + gear_item[1]);
}
}
stmt.close();
// thanks again to hugh!
我在 Java servlet 中从 MySQL 数据库检索数据时遇到了一些问题。作为参考,我的 Web 应用程序的构造就像一个图书馆 - 您可以签出项目,然后重新签入。
当您第一次点击 "check out" 时,您的请求将发送给管理员,我们称此人为图书管理员,他必须批准或不批准您的请求。假设我登录,挑选一些物品,然后点击 "checkout"。事情是这样的:
- 项目已添加到我的 "cart"
- 在数据库的项目主列表中,每个项目都有一个名为
STATUS
的VARCHAR
,用于标识该项目是否为"In Stock"
。对于我选择的每个项目,该变量都会更改为与我的用户帐户关联的唯一标识符。 - 我的请求被添加到名为
requests_list
的 table
批准、一般签到等工作正常。单击 "disapprove" 效果不佳。这是应该发生的事情:
- 请求已从
requests_list
中删除
- 请求者的 "cart" 项目被截断
- 项目本身得到声明
"In Stock"
这是正在发生的事情:
- 请求已从
requests_list
中删除
- 请求者的 "cart" 项目被截断
- 只有购物车中的第一件商品会被重新签入
这是我目前使用的代码:
stmt.execute("DELETE FROM requests_list WHERE UNIQUE_ID = '"
+ selected_ID + "'"); // this seems to work
stmt.execute("TRUNCATE TABLE checkout_" + selected_ID); // also seems to work
ResultSet all_gear = stmt
.executeQuery("SELECT * FROM gear_master_list");
while (all_gear.next()) {
if (all_gear.getString(5).equals(selected_ID)) {
stmt.execute("UPDATE gear_master_list SET STATUS = 'In Stock' WHERE ID_NUM = "
+ all_gear.getInt(6));
}
}
all_gear.close();
一些注释,用于解释一些变量:
selected_ID
- 图书管理员单击下拉菜单以访问已提出请求的用户列表。在他或她选择一个之后,该用户的唯一标识符变为selected_ID
checkout_selected_ID
- 您的 "cart" 是数据库中的 table。这个 table 是以你的唯一 ID 命名的,所以如果我的唯一 ID 是兔子,我的 table 就是checkout_bunnies
stmt
和它从中提取Statement
的Connection
都是有效且有效的gear_master_list
是所有装备的table,all_gear.getInt(6)
引用每个装备的唯一库存编号,all_gear.getString(5)
是STATUS
我提到的变量
我尝试过不同的做法,这样代码会遍历购物车中的所有商品,更新状态,然后截断 table。这也没有用 - 它对更新状态仍然很挑剔,而且 table 不会截断。
TL;DR: 即使我使用while
循环,不止一行。这是怎么回事?有没有更好、更有效的方法来做到这一点?
这可能是一个并发修改问题 - 您的第一个查询在数据库上保持打开的游标,并且在遍历该游标时您正在对相同的数据执行更新,所有这些都在同一事务中。
你能试试这个吗?
stmt.execute("DELETE FROM requests_list WHERE UNIQUE_ID = '"
+ selected_ID + "'"); // this seems to work
stmt.execute("TRUNCATE TABLE checkout_" + selected_ID); // also seems to
// work
ResultSet all_gear = stmt
.executeQuery("SELECT * FROM gear_master_list");
List<String> gear_items = new ArrayList<>();
while (all_gear.next()) {
gear_items.add(all_gear.getString(5));
}
all_gear.close();
for (String gear_item: gear_items){
if (all_gear.getString(5).equals(selected_ID)) {
stmt.execute("UPDATE gear_master_list SET STATUS = 'In Stock' WHERE ID_NUM = "
+ all_gear.getInt(6));
}
}
stmt.close();
非常感谢 hugh 对这个问题的大力帮助 - 他的回答是正确的。我只需要做一些修改来帮助他的响应适合我的代码。
以防其他人遇到这个问题,Hugh 是对的,这是一个 并发修改 问题。但是,他的回复中有一个轻微的错字(ResultSet 在某些语句被调用之前关闭),所以我想我会 post 我修改的代码以防万一它对任何人都有帮助:
stmt.execute("DELETE FROM requests_list WHERE UNIQUE_ID = '" + selected_ID + "'"); // this seems to work
stmt.execute("TRUNCATE TABLE checkout_" + selected_ID); // also seems to work
ResultSet all_gear = stmt.executeQuery("SELECT * FROM gear_master_list");
ArrayList<Object[]> gear_items = new ArrayList<Object[]>();
while (all_gear.next()) {
Object[] added = new Object[2];
added[0] = all_gear.getString(5);
added[1] = all_gear.getInt(6);
gear_items.add(added);
}
all_gear.close();
for (Object[] gear_item : gear_items) {
if (gear_item[0].equals(selected_ID)) {
stmt.execute("UPDATE gear_master_list SET STATUS = 'In Stock' WHERE ID_NUM = " + gear_item[1]);
}
}
stmt.close();
// thanks again to hugh!