2012-11-15 19 views
5

नीचे दिया गया कोड एक से अधिक पंक्ति वापस कर सकता है। sql%rowcount लाए गए पंक्तियों की संख्या वापस कर देगा?क्या चयन के लिए एसक्यूएल% पंक्ति गणना का उपयोग करना संभव है?

select * from emp where empname = 'Justin' and dept='IT' 
if sql%rowcount>0 
    ... 

यह मेरा नमूना proc है; क्या मैं सही तरीके से sql%rowcount का उपयोग कर रहा हूं?

CREATE PROCEDURE Procn(in_Hid IN VARCHAR2,outInststatus OUT VARCHAR2,outSockid IN NUMBER,outport OUT VARCHAR2,outIP OUT VARCHAR2,outretvalue OUT NUMBER) 
AS 
BEGIN 
select INST_STATUS into outInststatus from TINST_child where INST_ID = in_Hid and INST_STATUS = 'Y'; 
if outInststatus = 'Y' then 
    select PORT_NUMBER,STATIC_IP into outport,outIP from TINST where INST_ID = in_Hid and IP_PORT_STATUS = 'Y'; 
    if sql%rowcount >= 1 then 
     select SOCK_ID into outSockid from TINST where PORT_NUMBER = outport AND STATIC_IP = outIP; 
     outretvalue := 0; 
    else 
     outretvalue := -12; 
    end if; 
    EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    outretvalue := -13; 
end if; 
END; 
+1

यदि यह पीएल/एसक्यूएल टैग किए गए हैं तो आपको कुछ में चयन करने की आवश्यकता है, यदि स्थिति गिनती शून्य हो, तो 'अगर आप पंक्ति संख्या शून्य थी, या' बहुत अधिक पंक्तियां 'अगर यह 1 से अधिक थी तो आपको' no_data_found' अपवाद 'मिलेगा , इसलिए आप इससे निपटने के लिए अपवाद हैंडलिंग का उपयोग कर सकते हैं; या एक स्पष्ट कर्सर का उपयोग कर रहे हैं। मुझे लगता है कि अधिक संदर्भ की जरूरत है। –

+0

@alex i hav ने अपना कोड अपडेट किया है मैंने एक नमूना कोड पोस्ट किया है, क्या मैं सही तरीके से एसक्यूएल% गिनती का उपयोग कर रहा हूं? – user1

+0

नहीं; 'चुनें ... में' (जब तक कि आपके पास 'कोडो सुझाव के रूप में' थोक संग्रह नहीं होता है) हमेशा एक पंक्ति को वापस कर देगा, या अपवाद उठाएगा। कल्पना कीजिए कि दो मिलान पंक्तियां थीं; 'static_ip' के लिए दो मानों में से कौन सा 'आउटआईपी' होगा? आपका कोड तब तक काम करेगा जब तक एक पंक्ति हो, लेकिन जब ऐसा न हो तो असफल हो जाएंगे। क्या यह एक से अधिक पंक्ति होने के लिए * वैध * है, और यदि वहां है तो क्या होना चाहिए? –

उत्तर

1

अपनी टिप्पणी के आधार पर

2 'का चयन करें' क्वेरी एक से अधिक पंक्तियां देता है, तो मैं ले जाना चाहते हैं पहला वाला और इसके साथ प्रक्रिया

... यह काम करना चाहिए, लेकिन संभवतः आप अपेक्षा नहीं करते हैं, क्योंकि आपने यह परिभाषित नहीं किया है कि 'पहला' का अर्थ क्या है।

CREATE PROCEDURE Procn(in_Hid IN VARCHAR2, outInststatus OUT VARCHAR2, 
    outSockid IN NUMBER, outport OUT VARCHAR2, outIP OUT VARCHAR2, 
    outretvalue OUT NUMBER) 
AS 
BEGIN 
    select INST_STATUS into outInststatus 
    from TINST_child 
    where INST_ID = in_Hid and INST_STATUS = 'Y'; 

    -- no need to check if outInstatus is Y, that's all it can be here 

    -- restricting with `rownum` means you'll get at most one row, so you will 
    -- not get too_many_rows. But it will be an arbitrary row - you have no 
    -- criteria to determine which of the multiple rows you want. And you can 
    -- still get no_data_found which will go to the same exception and set -12 
    select PORT_NUMBER, STATIC_IP into outport, outIP 
    from TINST 
    where INST_ID = in_Hid and IP_PORT_STATUS = 'Y' 
    and rownum < 2; 

    -- no need to check sql%rowcount; it can only be 1 here 

    -- not clear if this can return multiple rows too, and what should happen 
    -- if it can; could use rownum restriction but with the same caveats 
    select SOCK_ID into outSockid 
    from TINST 
    where PORT_NUMBER = outport AND STATIC_IP = outIP; 

    outretvalue := 0; 
EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     outretvalue := -12; 
END; 

exception हैंडलर पूरे block पर लागू होता है।यदि select कथनों में से कोई भी पंक्ति नहीं ढूंढता है, तो no_data_found अपवाद उस ब्लॉक द्वारा संभाला जाएगा और outretvalue-12 पर सेट करेगा।

आप प्रत्येक select के लिए एक अलग outretvalue चाहते हैं तो आपको, उप ब्लॉक में उन्हें लपेट कर सकते हैं अपने खुद के अपवाद संचालन अनुभाग के साथ प्रत्येक:

CREATE PROCEDURE Procn(in_Hid IN VARCHAR2, outInststatus OUT VARCHAR2, 
    outSockid IN NUMBER, outport OUT VARCHAR2, outIP OUT VARCHAR2, 
    outretvalue OUT NUMBER) 
AS 
BEGIN 
    BEGIN 
     select INST_STATUS into outInststatus 
     from TINST_child 
     where INST_ID = in_Hid and INST_STATUS = 'Y'; 
    EXCEPTION 
     WHEN NO_DATA_FOUND THEN 
      outretvalue := -12; 
    END; 

    BEGIN 
     select PORT_NUMBER, STATIC_IP into outport, outIP 
     from TINST 
     where INST_ID = in_Hid and IP_PORT_STATUS = 'Y' 
     and rownum < 2; 
    EXCEPTION 
     WHEN NO_DATA_FOUND THEN 
      outretvalue := -13; 
    END; 

    BEGIN 
     select SOCK_ID into outSockid 
     from TINST 
     where PORT_NUMBER = outport AND STATIC_IP = outIP; 
    EXCEPTION 
     WHEN NO_DATA_FOUND THEN 
      outretvalue := -14; 
    END; 

    outretvalue := 0; 
END; 

आप केवल करने की ज़रूरत है कि फोन करने वाले को पता करने की जरूरत है जो select असफल रहा, और यदि आप वास्तव में कभी भी विफल होने की उम्मीद नहीं करते हैं तो शायद यह अधिक आम है कि अपवाद को पकड़ न लें और कॉलर को कच्चे no_data_found देखें और तय करें कि क्या करना है। निर्भर करता है कि अपवाद की स्थिति आपके और आपके आवेदन के लिए क्या है।

+0

लेकिन मेरी आवश्यकताओं पूरी तरह से आपके द्वारा समझाए गए वाट से अलग है 1. अगर जांच कर रहा है तो इंस्टॉलेशन Y को coz है, तो मुझे 'वाई' होने पर अगले चरण ओली की अनुमति देने की आवश्यकता है, यह 'एन' भी वापस कर सकता है 2. मैं अपने जैसे रोउनम कोज़ के साथ प्रतिबंधित नहीं कर सकता कई पंक्तियों की आवश्यकता दूसरी चयन QUERY में आ जाएगी और मुझे परिणाम सेट में पहली पंक्ति का चयन करने की आवश्यकता है, यहां किसी भी मानदंड के आधार पर चयन करने की आवश्यकता नहीं है। – user1

+0

@ उपयोगकर्ता 1 - 1) यह 'कहां' खंड की वजह से केवल 'वाई' हो सकता है; 'INST_STATUS' एक ही समय में' Y' और 'N' दोनों नहीं हो सकता है। 2) मैं पालन नहीं करता मैं डर रहा हूँ; 'एकाधिक पंक्तियों की आवश्यकता है' और 'यादृच्छिक रूप से पहली पंक्ति का चयन करें' (जो यह करता है) विरोधाभासी हैं? –

+0

महोदय, मेरा प्रश्न मेरे उपरोक्त कोड में है यदि पहली चयन क्वेरी 'वाई' लौटाती है तो stmnt अगर कोई pblm itll प्रक्रिया नहीं करता है। अगर यह 'कोई डेटा' नहीं देता है तो यह अपवाद पर जाएगा। अगर यह 'एन' देता है तो स्थिति क्या होगी proc i worte के अनुसार अगले जाओ? – user1

6

हां, आप SQL%ROWCOUNT का उपयोग कर सकते हैं। यह पीएल/एसक्यूएल में मान्य है।

हालांकि, पीएल/एसक्यूएल में आपकी क्वेरी के परिणाम कहीं कहीं जाने की आवश्यकता है उदा। एक पीएल/एसक्यूएल तालिका में। पीएल/एसक्यूएल परिणाम कभी भी आउटपुट (टर्मिनल, विंडो इत्यादि) को न भेजें। तो SELECT * FROM काम नहीं करेगा।

आपका कोड ऐसा दिखाई दे सकता:

DECLARE 
    TYPE emp_t ...; 
    emp_tab emp_t; 

BEGIN 
    SELECT * 
    BULK COLLECT INTO emp_tab 
    FROM emp 
    WHERE empname = 'Justin' AND dept='IT'; 

    IF sql%rowcount > 0 THEN 
    .. do something ... 
    END IF; 
END; 
/

अद्यतन:

अद्यतन सवाल पता चलता है कि आप कुछ और की तलाश में हैं।

विकल्प 1: अपवाद उपयोग

0 पंक्तियों या 1 से अधिक पंक्ति देखते हैं, तो इन मामलों (त्रुटियों के रूप में) अलग से नियंत्रित किया जाता है:

BEGIN 
    select PORT_NUMBER,STATIC_IP into outport, outIP 
    from TINST 
    where INST_ID = in_Hid AND IP_PORT_STATUS = 'Y'; 

EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    outretvalue := -12; 
    RETURN; 

    WHEN TOO_MANY_ROWS THEN 
    outretvalue := -13; 
    RETURN; 
END; 

विकल्प 2: उपयोग एकत्रित

समेकन का उपयोग करके, क्वेरी हमेशा एक पंक्ति वापस आ जाएगी। यदि अब स्रोत पंक्ति WHERE खंड से मेल खाती है, तो दोनों परिणाम मान शून्य होंगे। यदि वहां एक से अधिक पंक्तियों का मिलान किया गया है, तो अधिकतम लिया जाएगा।

ध्यान दें कि यह क्वेरी एक पोर्ट नंबर और एक आईपी पता लौटा सकती है जो मूल रूप से एक ही पंक्ति पर नहीं थी।

select MAX(PORT_NUMBER), MAX(STATIC_IP) into outport, outIP 
from TINST 
where INST_ID = in_Hid AND IP_PORT_STATUS = 'Y'; 

IF outport IS NULL OR outIP IS NULL THEN 
    outretvalue := -12; 
    RETURN; 
END IF; 

विकल्प 3: का प्रयोग करें ROWNUM

इस क्वेरी सबसे पहले एक पंक्ति में वापस आती है। कोई पंक्ति कहां खंड का मिलान नहीं हुआ, तो एक अपवाद फेंका और नियंत्रित किया जा करने के लिए की जरूरत है:

BEGIN 
    select PORT_NUMBER, STATIC_IP into outport, outIP 
    from TINST 
    where INST_ID = in_Hid AND IP_PORT_STATUS = 'Y' 
    AND ROWNUM = 1; 

EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    outretvalue := -12; 
    RETURN; 

END; 
+0

sql% rowcount वापसी> 1 यदि एक से अधिक पंक्तियां प्राप्त की जाती हैं या यह बहुत अधिक पंक्तियां कहती है – user1

+1

@ user1 - 'थोक संग्रह' खंड का अर्थ है 'emp_tab' PL/SQL तालिका में एकाधिक पंक्तियां संग्रहीत की जाती हैं। आपको इससे 'too_many_rows' या 'no_data_found' नहीं मिलेगा। जब आप थोक संग्रह करते हैं तो 'sql% rowcount' में पंक्तियों की संख्या होगी; हालांकि मैं सामान्य रूप से 'emp_tab.count' को संदर्भित करता हूं कि इसमें कितने शामिल हैं - चूंकि 'sql% count' अंतिम क्वेरी को संदर्भित करता है, यह केवल संक्षेप में उपयोगी होगा, जबकि' emp_tab.count' सही रहेगा। –