详细说明,我目前正在构建一个让用户创建帐户并登录的应用程序。他们提供的信息保存在我的数据库中。我的数据库包含两个表,一个保存用户信息,另一个保存用户清单,两者都是在创建帐户GUI完成时生成的。对于这个问题,只需要第二个表。此表有三列,第一列是用户名,第二列是库存槽号,第三列是该槽中项的项ID。当用户创建帐户时,在此表中创建了40行,在每行中,其用户名保持不变。但是,插槽号从1增加到40,而item id列默认为零。这是一个直观的表示:
现在,为了获取我的代码,当用户单击一个按钮时,会调用一个随机方法,该方法将一个int变量设置为特定数字,该变量当前名为“i”。此号码是我的应用中商品的ID。此时,系统会提示用户提供两个按钮,询问他们是要保留项目还是丢弃该项目。如果他们决定保留该项目,我需要将其添加到数据库中的库存中。这是我的问题发挥作用的地方。我的应用程序知道哪个用户已登录,因为当有人正确登录应用程序时,会将其用户名(这是主键)设置为应用程序其余部分可以使用的全局字符串变量。所以它知道要更新哪个用户,但我需要它按顺序检查每一行,如果它在ItemID列中找到一个零的行,它会将它更新为变量“i”当前是什么并结束查询。
这是我目前的代码,我对SQL很新,但我正在努力教自己,如果这会冒犯你(因为它太糟糕了),我道歉:
编辑:我已将我的代码更新为此新查询但是我收到一条错误,指出 java.sql.SQLException:您无法在FROM子句中指定目标表'userinv'进行更新
try{
//get connection to database
Connection con = DataBaseConnect.getConnection();
//create a statement
PreparedStatement addInfo = con.prepareStatement("UPDATE userinv SET "
+ "ItemID = "+i+" "
+ "WHERE Username = '"+LoginController.userLog+"' "
+ "AND Slot = ("
+ "SELECT MIN(Slot) FROM userinv "
+ "WHERE ItemID = 0 "
+ "AND Username = '"+LoginController.userLog+"')");
//process result set
addInfo.executeUpdate();
}
catch(Exception e){
e.printStackTrace();
}
此时我知道它需要更新userinv表,我知道它需要在用户用户名的情况下执行此操作,但我不确定如何在其间编写代码。有没有人有任何想法?
答案 0 :(得分:-1)
这适用于Oracle,适用于MySql:
update userinv set itemid = 815
where username = 'test'
and slot = (
select min(slot) from userinv
where itemid = 0
and username = 'test'
)
对于更复杂的情况,根据某些排序需要第一行,但不能将此表达为最低限度,此方法适用于Oracle:
update userinv set itemid = 815
where username = 'test'
and slot = (
select slot from (
select count(*) over (partition by username order by slot) cnt,
slot
from userinv
where itemid = 0
and username = 'test'
) where cnt = 1
)
它使用分析函数,因此它不适用于MySql,但有an article how to fake them in MySQL。
使用分析函数,这也应该有效(没试过,所以它确实包含错别字和东西)
update (
select count(*) over (partition by username order by slot) cnt,
u.*
from userinv u
where itemid = 0
and username = 'test'
order by slot
)
set itemid = 815
where cnt = 1
这只会访问一次表,当你的表很大时,这应该会更快。