Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

rekharaghuram
from rekharaghuram More from this publisher
05.11.2015 Views

CHAPTER 9 ■ REDO AND UNDO 303 ops$tkyte@ORA10G> create or replace procedure do_work( p_what in varchar2 ) 2 as 3 l_redo_size number; 4 l_cnt number := 200; 5 6 procedure report( l_op in varchar2 ) 7 is 8 begin 9 select v$mystat.value-l_redo_size 10 into l_redo_size 11 from v$mystat, v$statname 12 where v$mystat.statistic# = v$statname.statistic# 13 and v$statname.name = 'redo size'; 14 15 dbms_output.put_line(l_op || ' redo size = ' || l_redo_size || 16 ' rows = ' || l_cnt || ' ' || 17 to_char(l_redo_size/l_cnt,'99,999.9') || 18 ' bytes/row' ); 19 insert into log 20 select p_what, l_op, data_length, l_redo_size, l_cnt 21 from user_tab_columns 22 where table_name = 'T' 23 and column_name = 'Y'; 24 end; The local procedure SET_REDO_SIZE queries V$MYSTAT and V$STATNAME to retrieve the current amount of redo our session has generated thus far. It sets the variable L_REDO_SIZE in the procedure to that value: 25 procedure set_redo_size 26 as 27 begin 28 select v$mystat.value 29 into l_redo_size 30 from v$mystat, v$statname 31 where v$mystat.statistic# = v$statname.statistic# 32 and v$statname.name = 'redo size'; 33 end; And then there is the main routine. It collects the current redo size, runs an INSERT/ UPDATE/DELETE, and then saves the redo generated by that operation to the LOG table: 34 begin 35 set_redo_size; 36 insert into t 37 select object_id, object_name, created 38 from all_objects 39 where rownum

304 CHAPTER 9 ■ REDO AND UNDO 41 commit; 42 report('insert'); 43 44 set_redo_size; 45 update t set y=lower(y); 46 l_cnt := sql%rowcount; 47 commit; 48 report('update'); 49 50 set_redo_size; 51 delete from t; 52 l_cnt := sql%rowcount; 53 commit; 54 report('delete'); 55 end; 56 / Now, once we have this in place, we set the width of column Y to 2,000. We then run the following script to test the three scenarios, namely no trigger, BEFORE trigger, and AFTER trigger: ops$tkyte@ORA10G> exec do_work('no trigger'); insert redo size = 505960 rows = 200 2,529.8 bytes/row update redo size = 837744 rows = 200 4,188.7 bytes/row delete redo size = 474164 rows = 200 2,370.8 bytes/row PL/SQL procedure successfully completed. ops$tkyte@ORA10G> create or replace trigger before_insert_update_delete 2 before insert or update or delete on T for each row 3 begin 4 null; 5 end; 6 / Trigger created. ops$tkyte@ORA10G> truncate table t; Table truncated. ops$tkyte@ORA10G> exec do_work('before trigger'); insert redo size = 506096 rows = 200 2,530.5 bytes/row update redo size = 897768 rows = 200 4,488.8 bytes/row delete redo size = 474216 rows = 200 2,371.1 bytes/row PL/SQL procedure successfully completed. ops$tkyte@ORA10G> drop trigger before_insert_update_delete; Trigger dropped.

CHAPTER 9 ■ REDO AND UNDO 303<br />

ops$tkyte@ORA10G> create or replace procedure do_work( p_what in varchar2 )<br />

2 as<br />

3 l_redo_size number;<br />

4 l_cnt number := 200;<br />

5<br />

6 procedure report( l_op in varchar2 )<br />

7 is<br />

8 begin<br />

9 select v$mystat.value-l_redo_size<br />

10 into l_redo_size<br />

11 from v$mystat, v$statname<br />

12 where v$mystat.statistic# = v$statname.statistic#<br />

13 <strong>and</strong> v$statname.name = 'redo size';<br />

14<br />

15 dbms_output.put_line(l_op || ' redo size = ' || l_redo_size ||<br />

16 ' rows = ' || l_cnt || ' ' ||<br />

17 to_char(l_redo_size/l_cnt,'99,999.9') ||<br />

18 ' bytes/row' );<br />

19 insert into log<br />

20 select p_what, l_op, data_length, l_redo_size, l_cnt<br />

21 from user_tab_columns<br />

22 where table_name = 'T'<br />

23 <strong>and</strong> column_name = 'Y';<br />

24 end;<br />

The local procedure SET_REDO_SIZE queries V$MYSTAT <strong>and</strong> V$STATNAME to retrieve the current<br />

amount of redo our session has generated thus far. It sets the variable L_REDO_SIZE in the<br />

procedure to that value:<br />

25 procedure set_redo_size<br />

26 as<br />

27 begin<br />

28 select v$mystat.value<br />

29 into l_redo_size<br />

30 from v$mystat, v$statname<br />

31 where v$mystat.statistic# = v$statname.statistic#<br />

32 <strong>and</strong> v$statname.name = 'redo size';<br />

33 end;<br />

And then there is the main routine. It collects the current redo size, runs an INSERT/<br />

UPDATE/DELETE, <strong>and</strong> then saves the redo generated by that operation to the LOG table:<br />

34 begin<br />

35 set_redo_size;<br />

36 insert into t<br />

37 select object_id, object_name, created<br />

38 from all_objects<br />

39 where rownum

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!