如何编写一个SQL查询来检查列是否为零,它将更新它,如果不是,它将移动到下一行?

时间:2017-03-07 02:53:37

标签: mysql sql database oracle

免责声明:我还是这个网站的新手所以我还在学习该网站的礼节,对于任何错误,我道歉。此外,我之前发布了类似的问题,但一些很棒的人建议我将我的数据库重做当前格式。这是一个很大的帮助,但它向前迈出了一步,后退了一步。我有一个改进的数据库,但我的问题现在继续进行一些小调整。

详细说明,我目前正在构建一个让用户创建帐户并登录的应用程序。他们提供的信息保存在我的数据库中。我的数据库包含两个表,一个保存用户信息,另一个保存用户清单,两者都是在创建帐户GUI完成时生成的。对于这个问题,只需要第二个表。此表有三列,第一列是用户名,第二列是库存槽号,第三列是该槽中项的项ID。当用户创建帐户时,在此表中创建了40行,在每行中,其用户名保持不变。但是,插槽号从1增加到40,而item id列默认为零。这是一个直观的表示:

Database Image

现在,为了获取我的代码,当用户单击一个按钮时,会调用一个随机方法,该方法将一个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表,我知道它需要在用户用户名的情况下执行此操作,但我不确定如何在其间编写代码。有没有人有任何想法?

1 个答案:

答案 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   

这只会访问一次表,当你的表很大时,这应该会更快。