मैंने ओरेकल 7 के साथ अतीत में कुछ ऐसा किया है, जहां मुझे हजारों तालिकाओं से लाखों पंक्तियां हटानी पड़ीं। सभी दौर प्रदर्शन और विशेष रूप से बड़े डेलेट (लाखों पंक्तियों में एक टेबल में प्लस) के लिए इस स्क्रिप्ट ने अच्छी तरह से काम किया।
आपको इसे थोड़ा संशोधित करना होगा (यानी: उपयोगकर्ताओं/पासवर्ड की जांच करें, साथ ही अपने रोलबैक सेगमेंट सही प्राप्त करें)। इसके अलावा आपको वास्तव में अपने डीबीए के साथ इस पर चर्चा करने और इसे पहले टेस्ट पर्यावरण में चलाने की आवश्यकता है। यह सब कहकर, यह बहुत आसान है। फ़ंक्शन delete_sql() आपके द्वारा निर्दिष्ट तालिका में पंक्तियों का बैच देखता है, फिर उन्हें बैच द्वारा बैच हटा देता है।उदाहरण के लिए;
exec delete_sql('MSF710', 'select rowid from msf710 s where (s.equip_no, s.eq_tran_date, s.comp_data, s.rec_710_type, s.seq_710_no) not in (select c.equip_no, c.eq_tran_date, c.comp_data, c.rec_710_type, c.seq_710_no from msf710_sched_comm c)', 500);
ऊपर के उदाहरण एक एसक्यूएल बयान के आधार पर तालिका MSF170 से एक बार में 500 रिकॉर्ड हटा रहा है।
आप एक से अधिक तालिका से डेटा हटाने की आवश्यकता है, बस फाइल में अतिरिक्त exec delete_sql(...)
पंक्तियों को हटा दें-tables.sql
ओह और वापस ऑनलाइन अपने रोलबैक क्षेत्रों डाल करने के लिए याद में शामिल हैं, यह लिपि में नहीं है।
spool delete-tables.log;
connect system/SYSTEM_PASSWORD
alter rollback segment r01 offline;
alter rollback segment r02 offline;
alter rollback segment r03 offline;
alter rollback segment r04 offline;
connect mims_3015/USER_PASSWORD
CREATE OR REPLACE PROCEDURE delete_sql (myTable in VARCHAR2, mySql in VARCHAR2, commit_size in number) is
i INTEGER;
sel_id INTEGER;
del_id INTEGER;
exec_sel INTEGER;
exec_del INTEGER;
del_rowid ROWID;
start_date DATE;
end_date DATE;
s_date VARCHAR2(1000);
e_date VARCHAR2(1000);
tt FLOAT;
lrc integer;
BEGIN
--dbms_output.put_line('SQL is ' || mySql);
i := 0;
start_date:= SYSDATE;
s_date:=TO_CHAR(start_date,'DD/MM/YY HH24:MI:SS');
--dbms_output.put_line('Deleting ' || myTable);
sel_id := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(sel_id,mySql,dbms_sql.v7);
DBMS_SQL.DEFINE_COLUMN_ROWID(sel_id,1,del_rowid);
exec_sel := DBMS_SQL.EXECUTE(sel_id);
del_id := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(del_id,'delete from ' || myTable || ' where rowid = :del_rowid',dbms_sql.v7);
LOOP
IF DBMS_SQL.FETCH_ROWS(sel_id) >0 THEN
DBMS_SQL.COLUMN_VALUE(sel_id,1,del_rowid);
lrc := dbms_sql.last_row_count;
DBMS_SQL.BIND_VARIABLE(del_id,'del_rowid',del_rowid);
exec_del := DBMS_SQL.EXECUTE(del_id);
-- you need to get the last_row_count earlier as it changes.
if mod(lrc,commit_size) = 0 then
i := i + 1;
--dbms_output.put_line(myTable || ' Commiting Delete no ' || i || ', Rowcount : ' || lrc);
COMMIT;
end if;
ELSE
exit;
END IF;
END LOOP;
i := i + 1;
--dbms_output.put_line(myTable || ' Final Commiting Delete no ' || i || ', Rowcount : ' || dbms_sql.last_row_count);
COMMIT;
DBMS_SQL.CLOSE_CURSOR(sel_id);
DBMS_SQL.CLOSE_CURSOR(del_id);
end_date := SYSDATE;
e_date := TO_CHAR(end_date,'DD/MM/YY HH24:MI:SS');
tt:= trunc((end_date - start_date) * 24 * 60 * 60,2);
dbms_output.put_line('Deleted ' || myTable || ' Time taken is ' || tt || 's from ' || s_date || ' to ' || e_date || ' in ' || i || ' deletes and Rows = ' || dbms_sql.last_row_count);
END;
/
CREATE OR REPLACE PROCEDURE delete_test (myTable in VARCHAR2, mySql in VARCHAR2, commit_size in number) is
i integer;
start_date DATE;
end_date DATE;
s_date VARCHAR2(1000);
e_date VARCHAR2(1000);
tt FLOAT;
BEGIN
start_date:= SYSDATE;
s_date:=TO_CHAR(start_date,'DD/MM/YY HH24:MI:SS');
i := 0;
i := i + 1;
dbms_output.put_line(i || ' SQL is ' || mySql);
end_date := SYSDATE;
e_date := TO_CHAR(end_date,'DD/MM/YY HH24:MI:SS');
tt:= round((end_date - start_date) * 24 * 60 * 60,2);
dbms_output.put_line(i || ' Time taken is ' || tt || 's from ' || s_date || ' to ' || e_date);
END;
/
show errors procedure delete_sql
show errors procedure delete_test
SET SERVEROUTPUT ON FORMAT WRAP SIZE 200000;
exec delete_sql('MSF710', 'select rowid from msf710 s where (s.equip_no, s.eq_tran_date, s.comp_data, s.rec_710_type, s.seq_710_no) not in (select c.equip_no, c.eq_tran_date, c.comp_data, c.rec_710_type, c.seq_710_no from msf710_sched_comm c)', 500);
spool off;
ओह और एक आखिरी युक्ति। यह धीमा होने जा रहा है और तालिका के आधार पर कुछ डाउनटाइम की आवश्यकता हो सकती है। परीक्षण, समय और ट्यूनिंग यहां आपका सबसे अच्छा दोस्त है।
डेटा को हटाने के लिए आपको पहले उदाहरण का उपयोग करने में सक्षम होना चाहिए क्योंकि यह एक तालिका में है। – Joshua