2017-03-07 16 views
0

免責聲明:我還是這個網站的新手,所以我仍然在學習網站的禮儀,我對任何錯誤表示歉意。此外,我以前發佈過類似的問題,但一些非常棒的人推薦我將我的數據庫重新設計爲當前格式。這是一個很大的幫助,但是它向前邁進了一步。我有一個改進的數據庫,但我的問題現在繼續進行一些小的調整。如何編寫一個SQL查詢來檢查列是否爲零,它會更新它,如果不是,它將移動到下一行?

詳細說明,我目前正在構建一個應用程序,讓用戶創建一個帳戶並登錄。他們提供的信息保存到我的數據庫中。我的數據庫包含兩個表,一個保存用戶信息,一個保存用戶清單,兩者都是在完成創建帳戶GUI時生成的。對於這個問題,只有第二個表是必要的。該表有三列,第一列是用戶用戶名,第二列是他們的庫存插槽號,第三列是該插槽中項目的項目標識。當用戶創建一個帳戶時,該表中會創建四十行,每行中他們的用戶名保持不變。但是,插槽號從1增加到40,而項目ID列默認爲零。這裏是一個可視化表示:

Database Image

現在去我的代碼,當用戶點擊一個按鈕,隨機方法被調用它設置一個int變量,它是目前命名爲「i」的一個特定的編號。這個數字是我的應用程序中的一個項目的ID。此時用戶會被提示兩個按鈕,詢問他們是否想保留該項目或丟棄它。如果他們決定保留該項目,我需要將其添加到數據庫的庫存中。這是我的問題發揮的地方。我的應用程序知道哪個用戶已登錄,因爲當某人正確登錄應用程序時,他們的用戶名(這是主鍵)會設置爲應用程序其餘部分可以使用的全局字符串變量。所以它知道要更新哪個用戶,但我需要它按順序檢查每個行,並且如果它在ItemID列中找到一個零的行,它會將其更新爲當前變量「i」,並結束查詢。

這是我當前的代碼,我是很新的SQL,但我想教我,我道歉,如果這冒犯了你(因爲它是如此糟糕):

編輯:我已經更新了我代碼到這個新的查詢,但是我拿到指出java.sql.SQLException中的一個錯誤:您不能指定目標表「userinv」的更新在FROM子句

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

這個作品在Oracle和應該用MySQL:

update userinv set itemid = 815 
where username = 'test' 
and slot = (
    select min(slot) from userinv 
     where itemid = 0 
     and username = 'test' 
) 

對於更復雜的情況下,您需要根據一些排序第一行,但不能表達這種最小這種方法適用於甲骨文:

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 

此訪問表只有一次,這應該是更快的方式,當你的表是巨大的。

+0

哇這實際上有很多道理!此解決方案是否只會更新一個ItemID槽,然後查詢會結束? – CRSoftware33

+0

是的,假設插槽和用戶名的組合是唯一的,我沒有犯錯。 –

+0

好的太棒了!我將在明天將其實施到我的代碼中,然後再報告。 – CRSoftware33

相關問題