2016-02-11 62 views
1

很抱歉,如果這是一種欺騙 - 我搜索了類似的問題,但他們都似乎是沿着有條件更新的路線,你可以使用CASE語句將列設置爲多個值之一。的Oracle SQL:UPDATE,但扔「錯誤」,如果不能滿足條件

我有一個SQL UPDATE語句,但有兩個原因,我希望它不更新:

  1. 該項目沒有找到(導致rowsUpdated爲0)
  2. 如果滿足一個條件

我想區別這兩個狀態,這就是爲什麼我不能只把條件放在WHERE子句中。

目前,它看起來是這樣的:

UPDATE MY_TABLE t 
    SET t.TITLE = :TITLE, 
     t.TYPE = :TYPE, 
     t.STATE = :STATE, 
     t.UPDTIME = :UPDTIME 
WHERE t.ITEM_ID = :ITEM_ID 
    AND exists (SELECT t.ITEM_ID 
       FROM MY_TABLE t, USERINFO ui 
       WHERE ui.USERID = t.USERID 
       AND ui.USERNAME = :USERNAME 
       AND t.ITEM_ID = :ITEM_ID); 

這將在MY_TABLE是給定用戶名和ITEM_ID,或0,如果它不匹配返回1,如果發現(和更新)的項目。

我想添加一些東西,使其不會更新,如果t.STATE = 'READ_ONLY',但它做了一些區別的條件,從「該項目不存在」的條件。也許會拋出某種錯誤?

我能我的更新之前運行SELECT語句,以確保該項目的狀態不是READ_ONLY,但似乎浪費。有沒有更好的辦法?

+2

你可以添加一個虛擬計算,比如't.UPDTIME = CASE WHEN t.STATE = 'READ_ONLY',那麼1/0 ELSE:UPDTIME END'。 '1/0'應該會拋出一個*除數*,你可以捕獲。 – dnoeth

+0

這是聰明的,但有點哈克,你說不是嗎?我喜歡你的頭在哪裏:)我希望發生某種自定義錯誤 - 但我甚至不確定這在SQL中是可行的。這樣,我們會避免忽略零錯誤的合法分歧,正如Felipe所說。這並不是說我們目前的架構設置可能會發生這種情況,但誰知道未來會怎樣? – Disgruntor

回答

1

我不認爲這是浪費之前的SQL。這將是混亂引發錯誤正好趕上一個條件(如果你的真正更新扔了同樣的零錯誤劃分的?)。你可以選擇更新,後來改由ROWID更新,以加快速度,如果你使用的是堆表:

SELECT t.ITEM_ID, t.condition, t.rowid 
FROM MY_TABLE t, USERINFO ui 
WHERE ui.USERID = t.USERID 
AND ui.USERNAME = :USERNAME 
AND t.ITEM_ID = :ITEM_ID for update; 

如果條件滿足,你只需通過ROWID更新表

update MY_TABLE 
set ... 
where rowid = :rowid