2013-07-12 207 views
0

存儲過程存在問題。 它失敗在以下情況下Oracle存儲過程失敗

cntmismatch NUMBER; 

SELECT COUNT(keyvalue) INTO cntmismatch 
FROM tbl_temp GROUP BY keyvalue HAVING count(keyvalue) > 1 

當存在上述標準沒有數據,它失敗

我甚至使用

SELECT NVL(COUNT(keyvalue),0) INTO cntmismatch 
FROM tbl_temp GROUP BY keyvalue HAVING count(keyvalue) > 1 

嘗試,但它仍然retuns我這裏空和PROC失敗

+0

請解釋一下你正在試圖解決什麼問題。正如你從答案中看到的那樣,有許多可能的解決方案,但它們解決了不同的問題。作爲一項規則,通常最好告訴我們您要實施的業務規則,而不是期望我們從一些失敗的代碼中猜測它們。 – APC

回答

1

如果要計算keyvalue出現的次數不止一次,則需要使用子選擇:

SELECT COUNT(*) INTO cntmismatch 
FROM 
(SELECT keyvalue, count(*) FROM tbl_temp GROUP BY keyvalue HAVING count(*) > 1) 
3

查詢:

SELECT COUNT(keyvalue) INTO cntmismatch FROM tbl_temp GROUP BY keyvalue 

...將嘗試返回一行到cntmismatch爲每keyvalue,如果有不止這將失敗,並no_data_found如果表是空的,並與too_many_rows一個keyvalue

添加:

HAVING count(keyvalue) > 1 

...意味着它只能與多個條目,明確返回任何keyvalue的值,所以現在你會得到no_data_found如果表是空的,或者沒有keyvalue出現兩次;和too_many_rows如果多個keyvalue有重複。它只會在您有一個keyvalue重複的情況下才有效。

您還沒有表現出你的邏輯的休息,但想必你正在做基於一個返回值的東西,在這種情況下 - 如果只有一個keyvalue,這是不可能的 - 你可以離開了HAVING條款而只是測試值:

SELECT COUNT(keyvalue) INTO cntmismatch FROM tbl_temp GROUP BY keyvalue; 
IF cntmismatch > 1 THEN 
    ... -- some processing 
END IF: 

但充其量,所有它告訴你的是是否存在多次出現任何keyvalue;它不會告訴你它們是什麼keyvalue,並且仍然不能應付多於一個。

如果你想檢索所有具有超過一個匹配行,做一些與他們那麼你可以使用遊標值:

FOR dup_keyvalues IN (SELECT keyvalue, COUNT(*) AS cnt 
    FROM tbl_temp GROUP BY keyvalue HAVING COUNT(*) > 1) LOOP 
    ... - some processing, e.g. 
    DBMS_OUTPUT.PUT_LINE('keyvalue ' || dup_keyvalues.keyvalue 
     || ' has ' || dup_keyvalues.cnt || ' matches'); 
    ... 
END LOOP; 
0

您應該簡單地捕獲並處理在代碼中的異常。 在你的情況下,你會得到一個NO_DATA_FOUND異常。

下面你會找到一個例子。

PROCEDURE count_mismatch AS 
    cntmismatch NUMBER; 
BEGIN 
    BEGIN 
    SELECT COUNT(keyvalue) INTO cntmismatch FROM tbl_temp GROUP BY keyvalue; 
    EXCEPTION 
    WHEN no_data_found THEN 
    cntmismatch := -1; 
    END; 
END 

我認爲,您不再需要HAVING子句。因此我已將其刪除。 如果您的語句將返回超過預期的1行,那麼您還必須處理TOO_MANY_ROWS異常!

0

試試這個

BEGIN 
    SELECT COUNT(keyvalue) INTO cntmismatch 
    FROM tbl_temp GROUP BY keyvalue HAVING count(keyvalue) > 1 
EXCEPTION 
    WHEN no_data_found THEN cntmismatch := 0; 
END;