अद्यतन: मैं चारों ओर 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>;
मामला है जब में अद्यतन कथन सीधे क्लाइंट से निष्पादित किया गया था, मुझे नहीं पता कि प्रोग्राम_आईडी कौन सा प्रतिनिधित्व करता है, लेकिन आपको इसकी आवश्यकता नहीं होगी - आपके पास कथन_ट्रैकर के "प्रोग्राम" कॉलम में निष्पादन योग्य का नाम होगा। यदि अद्यतन किसी अज्ञात पीएल/एसक्यूएल ब्लॉक से निष्पादित किया गया था, तो मैं इसे वापस ट्रैक करने का तरीका नहीं हूं - आपको आगे प्रयोग करने की आवश्यकता होगी।
हालांकि, यह सही हो सकता है कि ऑस्सर/मशीन/प्रोग्राम/मॉड्यूल जानकारी आपको सही दिशा में इंगित करने के लिए पर्याप्त हो सकती है।
हाय टोनी, अद्यतन के लिए धन्यवाद। मैंने क्रॉन में सभी उपयोगकर्ताओं की जांच की है और संदेह है कि यदि कोई शेड्यूलर अपडेट कर रहा है .. मैं सुझाए गए एसक्यूएल कथन को चलाने का प्रयास करूंगा ... धन्यवाद। – N2EE