2008-11-04 15 views
8

ऑरैकल में, मैं एक डिलीट स्पोक बनाना चाहता हूं जो हटाने के परिणाम के आधार पर एक पूर्णांक देता है।ऑरैकल प्रक्रिया पूर्णांक

यह मेरे पास अब तक है।

create or replace 
PROCEDURE Testing 
( 
iKey IN VARCHAR2 
) 
AS 

BEGIN 
    delete from MyTable WHERE 
    TheKey = iKey; 

END Testing; 

मैंने एक रिटर्न इंटेंजर डालने का प्रयास किया है लेकिन स्पोक संकलित नहीं होगा।

उत्तर

2

पंक्तियों की संख्या निर्धारित करने के लिए उपयोग एक समारोह और निहित एसक्यूएल कर्सर नष्ट कर दिया

create or replace 
FUNCTION Testing 
( 
iKey IN VARCHAR2 
) RETURN INTEGER 
AS 

BEGIN 
    delete from MyTable WHERE 
    TheKey = iKey; 

    RETURN SQL%ROWCOUNT; 

END Testing; 

यही काम करना चाहिए

+0

ओआरए -14551: एक क्वेरी – Benoit

+0

@ बेनोइट के अंदर एक डीएमएल ऑपरेशन नहीं कर सकता है जैसा कि यह होना चाहिए, फ़ंक्शन का उद्देश्य पीएल/एसक्यूएल से सादा एसक्यूएल से नहीं किया जाना है – stjohnroe

16

एक प्रक्रिया एक मूल्य वापस नहीं करती है। एक फ़ंक्शन एक मान देता है, लेकिन आपको किसी फ़ंक्शन में डीएमएल नहीं करना चाहिए (अन्यथा आप SQL कथन में फ़ंक्शन को संदर्भित करने जैसी चीजें नहीं कर सकते हैं, आप अनुमति अनुदान को भ्रमित करते हैं क्योंकि सामान्यतः डीबीए केवल-पढ़ने वाले उपयोगकर्ताओं तक पहुंच प्रदान करने में सक्षम होना चाहते हैं सभी कार्यों के लिए ताकि उपयोगकर्ता लगातार कंप्यूटेशंस कर रहे हों, आदि)।

आप स्थिति को वापस करने के लिए प्रक्रिया में एक आउट पैरामीटर जोड़ सकते हैं। यदि "सफलता" का मतलब है कि एक या अधिक पंक्तियों को अद्यतन किया गया है, तो आप पहले SQL विवरण द्वारा संशोधित पंक्तियों की संख्या की गिनती प्राप्त करने के लिए एसक्यूएल% ROWCOUNT का उपयोग करें और उपयोग कर सकते हैं वापसी पैरामीटर पॉप्युलेट करने के लिए, यानी

CREATE OR REPLACE PROCEDURE test_proc (
    p_iKey IN VARCHAR2, 
    p_retVal OUT INTEGER 
) 
AS 
BEGIN 
    DELETE FROM myTable 
    WHERE theKey = p_iKey; 

    IF(SQL%ROWCOUNT >= 1) 
    THEN 
    p_retVal := 1; 
    ELSE 
    p_retVal := 0; 
    END IF; 
END test_proc; 

बेशक, एक सामान्य कोड स्पष्टता दृष्टिकोण से, मैं आउटपुट पैरामीटर के बारे में संदिग्ध हूं जो एक स्थिति कोड वापस करने की कोशिश कर रहे हैं। आप सफलता प्राप्त करने और त्रुटि की स्थिति में अपवाद फेंक कर आम तौर पर बहुत बेहतर सेवा प्रदान करते हैं।

0

आप शायद इसके बजाय एक फ़ंक्शन ढूंढ रहे हैं।

FUNCTION TESTING (iKEY IN VARCHAR2) RETURN NUMBER 
IS 
    v_count NUMBER; 
    yourNumber NUMBER; 
BEGIN 

    SELECT COUNT(*) INTO v_count 
    FROM MyTable 
    WHERE TheKey = iKey; 

    IF v_count > 0 
    THEN 
     DELETE FROM MyTable 
     WHERE TheKey = iKey; 

     SELECT COUNT(*) INTO v_count 
     FROM MyTable 
     WHERE TheKey = iKey; 

     IF (v_count = 0) 
     THEN 
      yourNumber := 1; --means successful deletion 
     END IF; 
    ELSE 
     yourNumber := 0; --means no items to delete 
    END IF; 
    return yourNumber; 

    EXCEPTION 
     WHEN OTHERS THEN 
     RETURN -1; --means error was encountered 
END TESTING; 

नोट: मैं कहाँ काम हम आम तौर पर एक एसक्यूएल पैकेज के अंदर कार्यों डाल दिया।

+0

2 चयन के साथ साथ हटाना चाहते हैं? इसके बजाय stjohnrow द्वारा सुझाए गए SQL% ROWCOUNT विधि का उपयोग करें। –

+0

यह बहुत अच्छा है। इसके बारे में नहीं पता था। यह निश्चित रूप से बेहतर है। –

5

आप परिणाम देने के एक संग्रहीत प्रक्रिया का उपयोग कर सकते हैं।

DECLARE 
    pRes NUMBER; 
BEGIN 
    testing ('myspecialkey', pRes); 
    DBMS_OUTPUT.put_line (pRes); 
END; 
0

SQL%ROWCOUNT केवल कोई DML अपने मूल्य के तुरंत बाद मान प्रदान करेगा कि क्या किसी अन्य DML निष्पादित किया जाता है रीसेट हो जाएंगी:

CREATE OR REPLACE PROCEDURE testing (iKey IN VARCHAR2, oRes OUT NUMBER) 
AS 
BEGIN 
    DELETE FROM MyTable 
     WHERE TheKey = iKey; 

    oRes := SQL%ROWCOUNT; 
END; 

प्रक्रिया उपयोग कुछ की तरह कॉल करने के लिए।

समस्या को हल प्राप्त करने के लिए के रूप में मैं एक पाश मैं dml के बाद निम्न आदेश जारी किए गए में हटाए गए क्रियान्वित किया गया था:

row_count := row_count + SQL%ROWCOUNT; 

कृपया सुनिश्चित करें कि आप यह घोषणा करते हैं और प्रारंभ row_count := 0;

संबंधित मुद्दे