2013-03-13 7 views
5

आरपीजी में एम्बेडेड एसक्यूएल के साथ काम करते समय, आप अक्सर अपने परिणाम में सभी पंक्तियों को संसाधित करने के लिए कर्सर और dow -loop के साथ समाप्त होते हैं। लूप में स्थिति SQLCOD और/या SQLSTT पर किसी भी तरह निर्भर है, SQLRPGLE-प्रोग्राम में कुछ वैश्विक रूप से उपलब्ध चर?आईएलई आरपीजी में एसक्यूएल मिली स्थिति की जांच करने का सही तरीका क्या है?

लेकिन इन मानों की जांच करने का सही तरीका क्या है? कुछ सुझाव SQLCOD = 0 अन्य not (SQLCOD = +100 or SQLSTT = '02000')। कोई भी सभी चेतावनियों पर विफल रहता है, दूसरा कुछ त्रुटियों में विफल नहीं होता है, इसलिए मैं संतुष्ट नहीं हूं।

इसे समझने के लिए क्या मैं कुछ कोड के साथ कार्य करें:

Pmain    B 
D     PI 
Dmy_ds   E DS     extname(SOME_TABLE) 
D          qualified 
/free 
    exec sql 
    DECLARE cur CURSOR FOR 
     SELECT * 
     FROM some_table; 
    exec sql 
    OPEN cur; 
    exec sql 
    FETCH cur 
    INTO :my_ds; 
    dow sql_found(); 
     exec sql 
     FETCH cur 
     INTO :my_ds; 
    enddo; 
    exec sql 
    CLOSE cur; 
/end-free 
Pmain    E 


Psql_found  B 
D     PI    N 
/free 
    // insert return statement here... 
/end-free 
Psql_found  E 

मैं यहाँ सही वापसी कथन के लिए देख रहा हूँ, कि मुझे कोई त्रुटि तब होती है, तो सभी पंक्तियों के माध्यम से जाना बनाने के लिए और मुझे छोड़ जब एक त्रुटि देता है जाएगा होता है। त्रुटियों की जांच करने के लिए कुछ सभ्य तरीके से बोनस अंक।

उत्तर

5

एसक्यूएलएसटीएटी बेहतर है, और आईबीएम द्वारा अनुशंसित है।

IBM के सूचना केंद्र से SQL Messages and Codes Reference: SQLCODE and SQLSTATE concepts

SQLSTATE पसंदीदा मानक वापसी कोड है।

SQLSTATE 5 वर्ण हैं, जिसमें पहले दो बाइट class of conditions की पहचान करते हैं।

  • '00' = अयोग्य सफल समापन
  • '01' = चेतावनी
  • '02' = कोई डेटा

और कुछ एक त्रुटि है। मैं आमतौर पर केवल '00' की जांच करता हूं।

सरल। आसान।अधिक पोर्टेबल।

SQLCODE का उपयोग करने में अक्सर कोड की सूचियां शामिल होती हैं, जो आईएमएचओ, डेवलपर अनुकूल से कम होती हैं।

उदाहरण:

व्यक्तिगत रूप से, मैं आम तौर पर परिभाषाएँ और कोड इस तरह शामिल हैं:

D [email protected]  s    * inz(%addr(SQLState)) 
D xSQLState  ds    5 based([email protected]) 
D xSQLState2     2a 
D 
D Success_On_SQL C     const('00') 
D Warning_On_SQL C     const('01') 
D NoData_On_SQL C     const('02') 

तो किसी भी एसक्यूएल ऑपरेशन के बाद, मैं आम तौर पर जाँच

if xSQLState2 <> Success_On_Sql; 
    someflag = true; 
    endif; 
+0

मामूली नोट ... यह है पूरी तरह से सच नहीं है कि SQLSTATE कक्षाओं के लिए "कुछ और त्रुटि है"। केवल डीबी 2 (और त्रुटियों के रूप में परिभाषित) के लिए आरक्षित कक्षाएं आवश्यक रूप से त्रुटियां हैं। उदाहरण के लिए 'K1001' सिग्नलिंग केवल एक त्रुटि होगी यदि एप्लिकेशन ने इसे एक त्रुटि के रूप में संभाला है। – user2338816

0

मैं विषय पर खोज कर कुछ और किया था और पाया something on IBM's site (उद्धरण):

The SQLCODE is also set by the database manager after each SQL 
statement is executed as follows: 
    - If SQLCODE = 0 and SQLWARN0 is blank, execution was successful. 
    - If SQLCODE = 100, no data was found. For example, a FETCH 
    statement returned no data, because the cursor was positioned 
    after the last row of the result table. 
    - If SQLCODE > 0 and not = 100, execution was successful with a 
    warning. 
    - If SQLCODE = 0 and SQLWARN0 = 'W', execution was successful 
    with a warning. 
    - If SQLCODE < 0, execution was not successful. 

कौन सा एक sql_found() इस तरह के लिए मुझे नेतृत्व करेंगे:

Pfound_sql  B 
D     PI    N 
/free 
    return (SQLCOD >= 0) and (SQLCOD<>100); 
/end-free 
Pfound_sql  E 

कि लेना चाहिए डेटा की स्थिति के अंत की देखभाल और सभी त्रुटियों में विफल। मुझे यकीन नहीं है कि क्या कुछ चेतावनियां हैं जिनकी मुझे देखभाल करनी चाहिए (अगर अंत में एक चेतावनी है जो पढ़ने की ओर जाता है तो अंतहीन पाश में फंसना नहीं चाहते हैं)।

+0

1) मैं था उप-प्रसंस्करण में वैश्विक चर (जैसे SQLCOD) का उपयोग करने के खिलाफ सलाह दें। क्या होता है जब आपको किसी अन्य के अंदर फ़ेच लूप घोंसला करने की आवश्यकता होती है? जब आंतरिक पाश ईओएफ तक पहुंच जाता है तो यह अनजाने में बाहरी लूप पर बाहर निकलने की यात्रा भी करेगा। एक पैरामीटर के रूप में SQLCOD पास करें और वह समस्या दूर हो जाती है। –

+0

2) निगलने वाली त्रुटियां (जैसे SQLCOD <> 100) अव्यवस्थित है। क्या होता है यदि यह एक CAST त्रुटि है और आप डेटा खो रहे हैं? –

+0

इस उद्देश्य के लिए एक प्रक्रिया को परिभाषित करने का एक कल्पनीय लाभ यह है कि यदि कोई अन्यथा उन्हें संभालने के लिए विशिष्ट तर्क प्रदान नहीं करता है, तो एक में संभावित रूप से अप्रत्याशित त्रुटियों को निपटाने के लिए जेनेरिक तर्क भी शामिल हो सकता है। एह? – WarrenT

2

सबसे अच्छा अभ्यास आपके द्वारा अपेक्षित SQLCODEs (अपेक्षित प्रसंस्करण के हिस्से के रूप में) को संसाधित करना और उन लोगों को संभालने के लिए अपवाद कोड जोड़ने के लिए है। एक कार्यान्वयन:

dow 1=1; // forever 
     exec sql 
     FETCH cur 
     INTO :my_ds; 
    // normal exit   
    if sqlstt = SQL_NODATA; 
    SFLEND = *on;   
    leave;    
    endif;     

    // can't CAST a value 
    if sqlstt = SQL_CAST;   // CAST error        
    ... tell user there's an error and read another 
    iter;                 
    endif;                 

    // decimal data error 
    if sqlstt = SQL_DDE; 
    tell user to call IT and stop reading 
    leave;          
    endif;           


    // whoops! not expected at all. Dump for post-mortem 
    if sqlstt <> SQL_NORMAL;        
    ... tell user to call IT and stop reading 
    dump(a);        
    leave;            
    endif;            

    // test for end of loop 
    // filled subfile page? 
    enddo; // forever 
कार्यान्वयन आप जानबूझकर पाश छोड़ना के इस प्रकार के साथ

; चाहे आपने उपफाइल पृष्ठ भर लिया हो, किसी सरणी में उच्चतम तत्व लोड किया हो या कोई त्रुटि दबाएं। मुझे यकीन नहीं है कि एक एकल, सामान्य कार्यान्वयन है जो सभी परिस्थितियों को संभालेगा। कभी-कभी यदि आप रिकॉर्ड लॉक रखते हैं और कभी-कभी आप एक संदेश जारी करना चाहते हैं और फिर से प्रयास करना चाहते हैं (उदाहरण के लिए) तो आप रीड लूप छोड़ना चाहेंगे।

+1

एसक्यूएल के साथ शुरू होने वाले नाम प्रीकंपेलर द्वारा आरक्षित हैं। देखें [आईएलई आरपीजी अनुप्रयोगों में नाम जो SQL का उपयोग करते हैं] (http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Frzajp%2Frzajprpiamco.htm) – WarrenT

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