2013-04-24 7 views
6

का उपयोग कर गतिशील एसक्यूएल में किसी त्रुटि की स्थिति पाएं पीएल/एसक्यूएल या एसक्यूएल में डायनामिक एसक्यूएल कथन में त्रुटि की स्थिति मुझे कैसे मिल सकती है?ओरेकल: एसक्यूएल या पीएल/एसक्यूएल

एसक्यूएल से

* प्लस मैं में एक त्रुटि की स्थिति देखते हैं, उदाहरण के लिए, कोई अमान्य एसक्यूएल DML कथन:

[email protected]> SELECT 
     2 X 
     3 FROM 
     4 TABLEX 
     5/
    TABLEX 
    * 
ERROR at line 4: 
ORA-00942: table or view does not exist 

एसक्यूएल * प्लस लाइन संख्या के साथ त्रुटि दिखाता है, और प्रिंट और निशान है कि रेखा एक तारांकन के साथ जहां त्रुटि मिलती है।

गतिशील एसक्यूएल में कनवर्ट कर रहा है, मैं त्रुटि कोड (SQLCODE) और त्रुटि संदेश (SQLERRM) प्राप्त कर सकते हैं:

[email protected]> SET SERVEROUTPUT ON 
[email protected]> BEGIN 
     2 EXECUTE IMMEDIATE 'SELECT X FROM TABLEX'; 
     3 EXCEPTION 
     4 WHEN OTHERS THEN 
     5  DBMS_OUTPUT.PUT_LINE('SQLCODE:' || SQLCODE); 
     6  DBMS_OUTPUT.PUT_LINE('SQLERRM:' || SQLERRM); 
     7 END; 
     8/
SQLCODE:-942 
SQLERRM:ORA-00942: table or view does not exist 

लेकिन मैं गतिशील एसक्यूएल स्ट्रिंग में त्रुटि की स्थिति कैसे मिलता है?

मुझे लगता है कि ओरेकल एक एसक्यूएल संचार क्षेत्र (एसक्यूएलसीए) प्रदान करता है जिसमें त्रुटि के बारे में दिलचस्प जानकारी होती है। विशेष रूप से:

  • SQLCODE और SQLERRM क्षेत्रों,
  • SQLERRD क्षेत्र जहां SQLERRD (5) तत्व यह है कि देता है (कि डेटा संबंधित PL/SQL कार्यों के साथ पुनः प्राप्त का स्रोत हो सकता है) ' पार्स त्रुटि ऑफसेट '।

क्या पीएल/एसक्यूएल या एसक्यूएल से SQLERRD तक पहुंच बनाना संभव है? यदि हां, तो कैसे? यदि नहीं, तो पीएल/एसक्यूएल या एसक्यूएल से त्रुटि का स्थान कौन सी तकनीक दे सकता है?

(यहाँ http://docs.oracle.com/cd/B28359_01/appdev.111/b31231/chapter8.htm#BABIGBFF SQLCA प्रलेखित है और साथ प्रो * सी पहुँचा।)

(उत्तर यहाँ how to declare SQLCA.SQLERRD? संकेत मिलता है कि SQLERRD और इसलिए सुलभ नहीं PL/SQL में परिभाषित नहीं है लगता है।)

(यहां चर्चा Why doesn't Oracle tell you WHICH table or view does not exist? ट्रेस फाइलों का उपयोग करके खराब एसक्यूएल दिखाने के लिए कुछ सुझाव देती है और कुछ विकास उपकरणों में त्रुटियों का स्थान दिखाने के लिए कुछ सुझाव देती है।)

उत्तर

1

डायनामिक पीएल/एसक्यूएल के माध्यम से कथन चलाने से त्रुटि रेखा में प्रासंगिक रेखा संख्या संग्रहित होगी ।

उदाहरण के लिए, इस बयान लाइन 4 पर एक त्रुटि है:

declare 
    v_count number; 
    v_bad_sql varchar2(32767) := 
     'SELECT 
      X 
      FROM 
      TABLEX'; 
begin 
    execute immediate v_bad_sql into v_count; 
exception when others then 
    begin 
     execute immediate 
      'begin for i in ('||v_bad_sql||') loop null; end loop; end;'; 
    exception when others then 
     dbms_output.put_line(sqlerrm); 
    end; 
end; 
/

ORA-06550: line 4, column 4: 
PL/SQL: ORA-00942: table or view does not exist 
ORA-00942: table or view does not exist 
ORA-06550: line 1, column 18: 
PL/SQL: SQL Statement ignored 
ORA-00942: table or view does not exist 

वहाँ इस विधि में कुछ कमियां हैं:

  1. यह अपवाद और फिर से पकड़ने के लिए कुछ अतिरिक्त, बदसूरत कोड की आवश्यकता है एसक्यूएल का प्रयास करें।
  2. उदाहरण केवल चयन के लिए काम करता है। आपको डालने, अपडेट करने, हटाने, मर्ज करने, गतिशील पीएल/एसक्यूएल इत्यादि के लिए इसे ट्विक करने की आवश्यकता होगी। आम तौर पर आपको पता होना चाहिए कि यह किस तरह का SQL कथन है। यदि आप दुर्भाग्यपूर्ण हैं, तो आपको कथन का विश्लेषण करना होगा, जो बहुत मुश्किल हो सकता है।
  3. कॉलम संख्या गलत है यदि संपूर्ण पीएल/एसक्यूएल कथन एक पंक्ति पर है।
+0

मैं एसक्यूएल के व्यवहार * नकल करने के लिए कोशिश कर रहा हूँ में त्रुटि संदेश निकालने के लिए प्लस हमलावर लाइन और एक अन्य बात यह है कि निशान मुद्रण द्वारा एक पैकेज मिल गया के साथ समस्या की शुरुआत है एक तारांकन लाइनों और कॉलम की संख्या प्राप्त करने के लिए मुझे त्रुटि स्टैक को पार्स करके मुझे क्या चाहिए, लेकिन क्या कोई आसान तरीका है? –

+0

जहां तक ​​मुझे पता है कि कोई आसान तरीका नहीं है। उदाहरण के साथ –

3

आप dbms_utility

begin 
    .. generate error 
exception when others then 
    dbms_output.put_line(
     dbms_utility.format_call_stack()  || chr(10) || 
     dbms_utility.format_error_backtrace() || chr(10) || 
     dbms_utility.format_error_stack()) 
end; 
+2

एसक्यूएल फिडल: http://www.sqlfiddle.com/#!4/471dd/1 – ThinkJet

+1

डीबीएमएस_यूटीआईएलटीआई एक गतिशील एसक्यूएल स्टेटमेंट के अंदर लाइन नंबर * के अंदर पर्याप्त नहीं है। @ थिंकजेट का दूसरा ब्लॉक काम करेगा, हालांकि अभी भी एक गतिशील एसक्यूएल ब्लॉक में एसक्यूएल को लपेटने में कठिनाई है। (पहला ब्लॉक हमेशा काम नहीं करेगा - इसे पार्स त्रुटियों के लिए सही रेखा संख्या नहीं मिलेगी, उदाहरण के लिए यदि तालिका का नाम गलत है।) –

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