Sunday, 15 April 2012

oracle - PL/SQL Who am I function similar to T-SQL's OBJECT_NAME(@@PROCID) -


टी-एसक्यूएल में, निम्न कमांड वर्तमान चल रहे संग्रहीत कार्यविधि का नाम वापस कर देगा:

  OBJECT_NAME (@@ PROCID)  

पीएल / एसक्यूएल में, जब मैं एक पैकेज की एक संग्रहीत कार्यविधि पर निम्न कोड डालता हूं, तो यह पैसों के बजाय मूल पैकेज का नाम देता है संग्रहित प्रक्रिया निष्पादित करना।

  $$ PLSQL_UNIT  

क्या पीएल / एसक्यूएल में निष्पादन प्रक्रिया का नाम प्राप्त करने का कोई तरीका है?

< / Div>

हाँ, 12 से पहले के संस्करणों में यह असंभव है। लेकिन आप कुछ हैक्स कोशिश कर सकते हैं।

  1. V $ सत्र दृश्य में PLSQL_ENTRY_SUBPROGRAM_ID और PLSQL_SUBPROGRAM_ID फ़ील्ड हैं जो आपको वर्तमान में कार्यान्वित करने की कार्यवाही कर सकती हैं।

वर्तमान सत्र है:

  वीएस $ सत्र से PLSQL_ENTRY_OBJECT_ID, PLSQL_ENTRY_SUBPROGRAM_ID, PLSQL_OBJECT_ID, PLSQL_SUBPROGRAM_ID का चयन करें जहां AUD SID = sys_context ('userenv', 'sessionid')  

और फिर एक दृश्य ALL_PROCEDURES :

 < कोड> ALL_PROCEDURES से PROCEDURE_NAME का चयन करें जहां OBJECT_ID =: objectId और SUBPROGRAM_ID =: subprogramId  

इस दृश्य में संकुल में घोषित फ़ंक्शन और प्रक्रियाएं होती हैं लेकिन उन में शामिल नहीं हैं जो पैकेज निकायों में घोषित हैं। / P>

  1. dbms_utility.format_call_stack लाइन नंबर और स्रोत का नाम दिखाता है पार्सेड आउटपुट को owa_util.who_called_me द्वारा प्राप्त किया जा सकता है। कच्चे आउटपुट में ऑब्जेक्ट हैंडल है जो आपको अनाम ब्लॉक के स्रोत कोड तक पहुंच प्रदान कर सकता है।

dbms_utility.format_call_stack नमूना आउटपुट:

  ----- PL / SQL कॉल स्टैक ----- ऑब्जेक्ट लाइन ऑब्जेक्ट संभाल संख्या नाम B87FEF1C 1 अनाम ब्लॉक  

और फिर: < / P>

  V $ SQL से SQL_FULLTEXT चुनें जहां CHILD_ADDRESS = 'B87FEF1C'  

संग्रहित प्रक्रियाओं का स्रोत कोड ALL_SOURCE से प्राप्त किया जा सकता है। ।

  1. एक बार जब आप कॉलिंग विधि का एक स्रोत कोड और उस कोड में एक लाइन नंबर प्राप्त करते हैं, तो आप इसे प्रक्रिया नाम प्राप्त करने के लिए पार्स कर सकते हैं।

केवल एक बुरा उदाहरण एक-लाइनर्स है लेकिन यह एक दुर्लभ स्थिति है।

  प्रक्रिया बाहरी प्रक्रिया है जो भीमी शुरू होती है; समाप्त; शुरू करें जोमामी; समाप्त;  

आपके पास ऐसी जानकारी है जो कि whoami को इस लाइन पर बुलाया गया था लेकिन आपको नहीं पता कि यह पहली घटना है या दूसरा है। इसलिए, सोर्स कोड को पार्स करने से आपको सटीक समाधान नहीं मिल सकता है।

अन्य स्थितियों को स्रोत कोड पार्स करके संसाधित किया जा सकता है। मेरा प्रयास है नमूना उपयोग:

<पूर्व> पैकेज बनाना APCKG प्रक्रिया PROC है; समाप्त; / पैकेज निकाय बनाओ APCKG प्रक्रिया प्रोसी है प्रक्रिया "INNER / proc" शुरू होता है dbms_output.put_line (p_stack.whoAmI); समाप्त; शुरू "INNER / proc"; समाप्त; समाप्त; / APCKG.PROC प्रारंभ करें; समाप्त;

आउटपुट:

  5: आपका साइका। पैकेज बॉडी APCKG.PROCEDURE PROC.PROCEDURE "INNER / proc"  

आउटपुट प्रारूप:

  रेखा संख्या + ':' + स्वामी + ['।' + टाइप + '' + नाम] *  

इसलिए यह केवल अंतिम कॉलर और इसके पदानुक्रम को देता है। एक प्रक्रिया के भीतर एक प्रक्रिया जो एक पैकेज के शरीर में स्थित है।

यदि आप एक सटीक समाधान की जरूरत है और Oracle 12 की आवश्यकता है तो यह समाधान पूर्व के लिए है। संस्करण (10.2 पर परीक्षण) यह ऊपर एक-लाइनर उदाहरण के लिए पहली घटना वापस करेगा।

UPD:

मैंने इस समाधान को कॉल के लिए पूर्ण पैमाने पर पैकेज में उन्नत किया है स्टैक कंट्रोल लाभ:

  • ओरेकल 9 (), 10 और 11 पर परीक्षण किया गया।
  • यह वास्तव में पर्स स्रोत (अर्थात् लेक्सिकल विश्लेषण, टोकन इत्यादि। )।
  • शुद्ध पीएल / एसक्यूएल।
  • अज्ञात ब्लॉक स्रोत कोड (वे भीतरी प्रक्रियाओं को शामिल कर सकते हैं) को पार्स करता है।
  • utl_call_stack
  • विधि whoAmI और whoCalledMe
  • डबल उद्धृत नामों का समर्थन करता है।
  • स्ट्रिंग्स के लिए q -notation का समर्थन करता है।
  • बहु-लाइन और एक-लाइन टिप्पणियों को छोड़ देता है।
  • परिभाषाओं के बिना कार्यविधि और फ़ंक्शन declarations को छोड़ देता है।

UPD 2:

  • सशर्त संकलन के लिए समर्थन जोड़ा गया।

UPD 3:

  • संस्करणों के लिए ओरेकल 12 पैकेज utl_call_stack का बैकपोर्ट कार्यान्वित किया गया।

No comments:

Post a Comment