2010-01-05 12 views
5

मैं यह जानना चाहता हूं कि पैकेज में कौन सा पैकेज या प्रक्रिया तालिका अपडेट कर रही है या नहीं?यह पता लगाने के लिए कि कौन सा पैकेज/प्रक्रिया तालिका को अद्यतन कर रही है?

उचित दस्तावेज के बिना सौंपी गई एक परियोजना (जिस व्यक्ति ने परियोजना को सौंप दिया है) के कारण, डेटा जो हम जानते हैं कि हमने हमेशा कुछ अजीब स्रोत बिंदु पर वापस जाना है।

हम अनुमान लगा रहे हैं कि यह एक डेटाबेस नौकरी या शेड्यूलर हो सकता है जो हमारे ज्ञान के बिना अद्यतन कमांड चला रहा है। मैं उम्मीद कर रहा हूं कि यह पता लगाने का एक तरीका है कि स्रोत कोड कहां से कॉल कर रहा है, तालिका को अपडेट कर रहा है और उस तालिका पर ट्रिगर के रूप में स्रोत डालने पर हम निगरानी कर रहे हैं।

कोई विचार?

धन्यवाद।

उत्तर

3

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

  • निर्भरता दृश्यों को देखें उदा। ALL_DEPENDENCIES यह देखने के लिए कि कौन से संकुल/ट्रिगर आदि उस तालिका का उपयोग करते हैं। आपके सिस्टम के आकार के आधार पर जो बहुत से ऑब्जेक्ट्स को ट्रैवल करने के लिए वापस कर सकता है।
  • खोजें सभी डेटाबेस स्रोत इस तरह की मेज के लिए संदर्भ के लिए कोड:

    all_source से अलग प्रकार, नाम का चयन करें जहां कम (पाठ) कम ('% mytable%') की तरह;

फिर है कि वस्तुओं का एक बहुत वापस आ सकते हैं, और निश्चित रूप से वहाँ कुछ "गलत परिणामों की" जहां खोज स्ट्रिंग प्रकट होता है, लेकिन वास्तव में उस तालिका के लिए एक संदर्भ नहीं है हो जाएगा। आप कुछ और अधिक विशिष्ट कोशिश कर सकते हैं जैसे:

select distinct type, name 
from all_source 
where lower(text) like lower('%insert into mytable%'); 

लेकिन निश्चित रूप से उन मामलों को याद करेंगे जहां कमांड को अलग-अलग स्वरूपित किया गया था।

इसके अतिरिक्त, सर्वर पर "cron" नौकरियों के माध्यम से SQL स्क्रिप्ट चल रही हो सकती है?

+0

हाय टोनी, अद्यतन के लिए धन्यवाद। मैंने क्रॉन में सभी उपयोगकर्ताओं की जांच की है और संदेह है कि यदि कोई शेड्यूलर अपडेट कर रहा है .. मैं सुझाए गए एसक्यूएल कथन को चलाने का प्रयास करूंगा ... धन्यवाद। – N2EE

7

अद्यतन: मैं चारों ओर poked और पता चला कैसे एक बयान वापस अपने मालिक PL/SQL वस्तु को ट्रेस करने के लिए।

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

CREATE TABLE statement_tracker 
(SID NUMBER 
, serial# NUMBER 
, date_run DATE 
, program VARCHAR2(48) null 
, module VARCHAR2(48) null 
, machine VARCHAR2(64) null 
, osuser VARCHAR2(30) null 
, sql_text CLOB null 
, program_id number 
); 

CREATE OR REPLACE TRIGGER smb_t_t 
    AFTER UPDATE 
    ON smb_test 
BEGIN 
    INSERT 
    INTO statement_tracker 
    SELECT ss.SID 
     , ss.serial# 
     , sysdate 
     , ss.program 
     , ss.module 
     , ss.machine 
     , ss.osuser 
     , sq.sql_fulltext 
     , sq.program_id 
    FROM v$session ss 
     , v$sql sq 
    WHERE ss.sql_address = sq.address 
     AND ss.SID = USERENV('sid'); 
END; 
/

आदेश में ऊपर ट्रिगर संकलन करने के लिए, आप प्रदान करनी होगी ट्रिगर इन अनुमतियों को, जब SYS उपयोगकर्ता के रूप में लॉग इन के मालिक:

grant select on V_$SESSION to <user>; 
grant select on V_$SQL to <user>; 

आप की संभावना कुछ शर्त यह है कि केवल यह लॉग इन करें जब परिवर्तन आप हितों रहे हैं बनाता है के साथ ट्रिगर में डालने के बयान की रक्षा करना चाहते हैं sted में हो रहा है - मेरे परीक्षण सर्वर पर यह कथन धीरे-धीरे चलता है (1 सेकंड), इसलिए मैं इन सभी अद्यतनों को लॉग इन नहीं करना चाहता हूं। बेशक, उस स्थिति में, आपको ट्रिगर को एक पंक्ति-स्तर के रूप में बदलने की आवश्यकता होगी ताकि आप नए या पुराने मानों का निरीक्षण कर सकें।यदि आप चयन के ऊपरी हिस्से के बारे में वास्तव में चिंतित हैं, तो आप इसे v $ sql के खिलाफ शामिल नहीं होने के लिए बदल सकते हैं, और इसके बजाय बस SQL_ADDRESS कॉलम को सहेज सकते हैं, फिर डीबीएमएस_जेओबी के साथ नौकरी निर्धारित करें और दूसरे अपडेट के साथ sql_text कॉलम को अपडेट करें कथन, इस प्रकार किसी अन्य सत्र में अद्यतन को ऑफ़लोड करना और आपके मूल अपडेट को अवरुद्ध नहीं करना।

दुर्भाग्यवश, यह केवल आपको आधा कहानी बताएगा। जिस कथन को आप लॉग इन करने जा रहे हैं वह सबसे निकटतम कथन होगा - इस मामले में, एक अद्यतन - भले ही उस प्रक्रिया द्वारा निष्पादित मूल कथन एक संग्रहीत प्रक्रिया है। । यह जहां program_id स्तंभ में आता है, तो अद्यतन बयान एक प्रक्रिया या ट्रिगर का हिस्सा है, program_id प्रश्न में कोड की object_id को इंगित करेंगे - आप इसे thusly को हल कर सकते हैं:

SELECT * FROM all_objects where object_id = <program_id>; 

मामला है जब में अद्यतन कथन सीधे क्लाइंट से निष्पादित किया गया था, मुझे नहीं पता कि प्रोग्राम_आईडी कौन सा प्रतिनिधित्व करता है, लेकिन आपको इसकी आवश्यकता नहीं होगी - आपके पास कथन_ट्रैकर के "प्रोग्राम" कॉलम में निष्पादन योग्य का नाम होगा। यदि अद्यतन किसी अज्ञात पीएल/एसक्यूएल ब्लॉक से निष्पादित किया गया था, तो मैं इसे वापस ट्रैक करने का तरीका नहीं हूं - आपको आगे प्रयोग करने की आवश्यकता होगी।

हालांकि, यह सही हो सकता है कि ऑस्सर/मशीन/प्रोग्राम/मॉड्यूल जानकारी आपको सही दिशा में इंगित करने के लिए पर्याप्त हो सकती है।

1

बस "अपडेट के बाद" ट्रिगर लिखें और, इस ट्रिगर में, समर्पित तालिका में "DBMS_UTILITY.FORMAT_CALL_STACK" के परिणाम लॉग करें।

इस फ़ंक्शन का उद्देश्य आपको संग्रहीत प्रक्रियाओं और ट्रिगरों का पूरा कॉल स्टैक देना है जो आपके कोड तक पहुंचने के लिए निकाल दिए गए हैं। मैं मोबाइल ऐप से लिख रहा हूं, इसलिए मैं आपको अधिक विस्तृत उदाहरण नहीं दे सकता, लेकिन यदि आप इसके लिए Google हैं तो आप उनमें से कई पाएंगे।

0

यदि आप स्थानीय रूप से काम कर रहे हैं तो त्वरित और गंदे विकल्प हैं, और केवल डेटा को बदलने वाली पहली चीज़ में रुचि रखते हैं, लॉगिंग के बजाय ट्रिगर में त्रुटि फेंकना है। इस तरह, आप हमेशा की तरह स्टैक ट्रेस हो और यह एक बहुत कम लिखना है और आप एक नया तालिका बनाने के लिए की जरूरत नहीं है:

AFTER UPDATE ON table_of_interest 
BEGIN 
    RAISE_APPLICATION_ERROR(-20001, 'something changed it'); 
END; 
/
संबंधित मुद्दे

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