2012-07-27 76 views
0

如果在這種情況下使用MERGE INTO,則忽略。我只是想知道我是否可以檢查該行是否存在。如果不是,則將返回碼設置爲1並立即返回。如果是,則繼續執行其餘代碼並最終將返回碼設置爲0。下面的代碼不工作,因爲它總是執行到最後。我應該如何解決它?PL/SQL如何檢查是否存在並返回錯誤代碼

BEGIN 

    -- check 
    SELECT CASE 
     WHEN NOT EXISTS (SELECT 1 FROM s WHERE s.col1 = 1 AND s.col2 = 2) 
     THEN 1 
    END 
    INTO ret FROM dual; 

    -- update 
    UPDATE s 
    SET s.col3 = 3 
    WHERE s.col1 = 1 AND s.col2 = 2; 

    COMMIT; 

    SELECT 0 INTO ret FROM dual; 
    RETURN ret; 

    END foo; 

如果我想能夠區分,如果是s.col1 = 1不存在或s.col2 = 2不存在。並有2個不同的返回碼。在這種情況下我應該怎麼做?

回答

3

您沒有對存儲的值ret執行任何操作。

周圍有,檢查是否RET爲1或者爲空(在其他替代)UPDATE語句沒有IF。而且因爲沒有IF,程序的其餘部分總是被執行。需要

事情是這樣的:

SELECT sum(case when col1 = 1 then 1 else 0 end) as col1_count, 
     sum(case when col2 = 2 then 1 else 0 end) as col2_count 
    into ret1, ret2 
FROM s 
WHERE s.col1 = 1 
    or s.col2 = 2; 

if ret1 > 0 and ret2 > 0 then 
    update ...; 
    commit; 
    ret := 0; 
elsif (ret1 > 0 and ret2 = 0) then 
    ret := 1; 
elsif (ret1 = 0 and ret2 > 0) then 
    ret := 2; 
end if; 

return ret; 

一個更有效的方法是簡單地做了更新,並檢查是否在修改過的任何行。如果行存在,則在執行更新之前運行選擇只需將工作加倍。當行不存在時僅運行更新與執行select相同。

+0

感謝。我用更復雜的案例更新了我的問題。這是我最初的目標。有沒有一種乾淨的方式來做到這一點? – Stan 2012-07-27 09:08:50

+0

@Stan:在「飛行中」改變問題的範圍並不是很好。你應該從一開始就補充說。看我的編輯可能的解決方案。 – 2012-07-27 09:13:20

4

我想知道如果THRE是,如果擺在首位存在該行的任何點檢查,爲什麼你就是不發出UPDATE通俗易懂?

你不能做這樣的事嗎?

BEGIN 

    -- update 
    UPDATE s 
    SET s.col3 = 3 
    WHERE s.col1 = 1 AND s.col2 = 2; 

    COMMIT; 

    IF SQL%ROWCOUNT = 0 THEN 
     RETURN 0; 
    ELSE 
     RETURN 1; 
    END IF; 

END foo; 
+0

謝謝。我用更復雜的案例更新了我的問題。這是我最初的目標。有沒有一種乾淨的方式來做到這一點? – Stan 2012-07-27 09:09:04

+0

這個答案比問題更有意義。該測試是無用的,只能複製where子句。 – wildplasser 2012-07-27 10:32:10

1

如果我想能夠區分,如果是s.col1 = 1不存在或 s.col2 = 2不存在。並有2個不同的返回碼。我應該如何在這種情況下做 ?

我可能有BULK過於複雜這付 - 特別是如果更新是針對只有一行在任何一個時間 - 但當然你也可以相應地修改代碼 - 的原理是相同的。 代碼旨在返回1,2或3,具體取決於哪些更新條件符合col1和col2。

DECLARE 

    TYPE test_rec is record (....); 

    TYPE result_tab IS TABLE OF test_rt%ROWTYPE; 

    lt_results result_tab; 

    lv_ret NUMBER(1) := 0; 

BEGIN 

    SELECT x.* FROM (
    SELECT s.*, 1 as ret 
    FROM s 
    WHERE s.col1 = 1 and s.col2 != 2 
    UNION ALL 
    (SELECT s.*, 2 
    FROM s 
    WHERE s.col1 =! 1 and s.col2 = 2) 
    UNION ALL 
    (SELECT s.*, 3 
    FROM s 
    WHERE s.col1 = 1 and s.col2 = 2)) 
    BULK COLLECT INTO lt_results; 

    FOR i in lt_results.first .. lt_results.last LOOP 
     <<DO YOUR UPDATE>> 
     lv_ret := lt_results(i).ret; 
    END LOOP; 

    COMMIT; 

    RETURN lv_ret; 

END; 
相關問題