2010. 4. 6. 23:56
반응형
##########################################################################
### MASSIVE READ USING ARRAY AND BULK COLLECT
### - reading 1000 -> 2000 -> 3000 -> 4000 -> 5000 ros ROWS
### - this is executing 5 different sql statement within loop
### - PAGE 361
##########################################################################

declare
c sys_refcursor; /* SYS_REFCURSOR can be used from oracle9ir1 and up only. */
type array is
  table of big_table%rowtype
  index by binary_integer;
l_rec array;
begin
for i in 1 .. 5
loop
  open c for select * from big_table;
  fetch c bulk collect into l_rec limit i*1000;
  /* i*1000 sets the number of the rows */
  close c;
end loop;
end;
/



##########################################################################
### USING REF CURSOR
##########################################################################

variable a refcursor

variable b refcursor

variable c refcursor

begin
open :a for select empno form emp q1 where ename = 'blake';
open :b for select empno form emp q1 where ename = 'blake';
open :c for select empno form emp q1 where ename = 'blake';
end;
/



##########################################################################
### DYNAMIC SQL USING BULK COLLECT
### following coding dynamically decides
### - which table to be targeted on runtime, also the value to be inserted
### - DBMS_SQL USAGE
##########################################################################

create or replace package dyn_insert
as
procedure dbms_sql_method  /* target table name */
  (p_tname in varchar2, p_value in varchar2);
procedure dbms_imd_method  /* value to be inserted */
  (p_tname in varchar2, p_value in varchar2);
end;
/

create or replace package body dyn_insert
as
g_last_tname  varchar2(30);  /* stores table name for future soft parsing */
g_cursor number := dbms_sql.open_cursor; /* saves cursor handle information curding session */
procedure dbms_sql_method
  (p_tname in varchar2, p_value in varchar2)
is
l_rows number;
begin
if (g_last_tname <> p_tname or g_last_tname is null)
then
  dbms_sql.parse (g_cursor,
    'insert into ' || p_tname ||
    ' (x) values (:x)',
    dbms_sql.native);
  g_last_tname := p_tname;
end if;
dbms_sql.bind_variable(g_cursor, ':x', p_value);
l_rows := dbms_sql.execute (g_cursor);
end;
/



##########################################################################
### DYNAMIC SQL USING BULK INSERT
### - following coding dynamically decides
###   which table to be targeted on runtime, also the value to be inserted
### - USING ARRAY, BLUK COLLECT
### - DBMS_SQL USAGE
##########################################################################

create or replace vcArray as table of varchar2(5)
/


create or replace package dyn_insert2
as
procedure exec_imd_method
  (p_tname in varchar2, p_value in vcArray);
end;
/


create or replace package body dyn_insert2
as
procedure exec_imd_method
  (p_tname in varchar2, p_value in vcArray)
is
begin
forall in 1 .. p_value.count
execute immeidate 'insert into ' || p_tname ||
'(x) values (:x)' using p_value(i);
/***
*** this block is dynamic BULK inserts in Oracle 8i
execute immeidate
'begin
  forall i in 1 .. n
  insert into ' || p_tname || '(x) values (:x(i);
  end;'
using p_value.count, p_value;
***
***/

end;
end;
/


declare
l_array vcArray := vcArray();
begin
for i in 1 .. 5000 loop
  l_array.extend;
  l_array(l_array.count) := i;
  lf (mod(l_array.count,1000) = 0 or i=5000)
  then
   dyn_insert2.exec_imd_method('T', l_array);
   l_array := vcArray();
  end if;
end loop;
end;
/



##########################################################################
### DECREASING # OF PARSING IN JAVA
##########################################################################

static PreparedStatement saveTimesPs;

static void saveTiems (Connection con, String which, long elap) throws Exception
{
system.out.println( which + " ( " + elap + ")" );
if ( saveTimesPS == null )
saveTimesPs = con.prepareStatement
  ("insert into timings " +
   "( which, elap ) values "+
   "( ?, ? )" );

saveTimesPs.setString(1.which);
saveTimesPs.setLong(2,elap);
saveTimesPs.executeUpdate();



##########################################################################
### CREATING SAMPLE TABLES
##########################################################################

create table t1
as
select mod(rownum, 1000) id,
rpad('x', 300, 'x') data
from all_objects
where rownum <= 5*1000;



##########################################################################
### FOR OLTP & OLAP WORK-STYLE SIMULATION
### - DBMS_JOB, DBMS_STATS USAGE
##########################################################################

- oltp work-style procedure

create or replace procedure oltp_style
as
l_rec big_table%rowtype;
l_n number;
begin
for i in 1 .. 10000
loop
  l_n := trunc (dbms_random.value(2.1000000) );
  select * into l_rec from big_table where id = l_n;
end loop;
end;



- olap work-style procedure

create or replace procedure dw_style
as
l_n number;
begin
select count(*) into_n
from (
  select /*+  USE_HASH(t1, t2)
    FULL(T1) FULL(T2)
    NOPARALLEL(T1) NOPARALLEL(T2) */
   t1.data_object_id, t2.data_object_id
  from big_table t1, big_table t12
  where t1.id = t2.id
  );
end;
/


- oltp simulation pl/sql block

declare
n number;
begin
oltp_style;
dbms_job.submit(n, 'oltp_style;');
dbms_job.submit(n, 'oltp_style;');
dbms_job.submit(n, 'oltp_style;');
commit;

dbms_stats.gather_system_stats (gathering_mode => 'START',
     sttab => 'SYSTEM_STATS',
     statid => 'OLTP');

select count(*) into n from user_jobs where what = 'oltp_style;';
while (n>0)
loop
  dbms_lock.sleep(5);
  select count(*) into n form user_jobs where what = 'oltp_style;';
end loop;

dbms_stats.gather_system_stats (gathering_mode => 'STOP',
     sttab => 'SYSTEM_STATS',
     statid => 'OLTP');
end;
/

-- for olap simulation usage, add following codes and modify the rest

olap_style;
dbms_job.submit(n, 'dw_style;');
dbms_job.submit(n, 'dw_style;');
dbms_job.submit(n, 'dw_style;');
commit;

-- for mixed simulation usage, add following codes and modify the rest


dbms_job.submit(n, 'dw_style;');
dbms_job.submit(n, 'dw_style;');
dbms_job.submit(n, 'dw_style;');
dbms_job.submit(n, 'olap_style;');
dbms_job.submit(n, 'olap_style;');
dbms_job.submit(n, 'olap_style;');
commit;

-- also you might want to execute "alter system flush shared_pool" prior
   loading statistics into data dictionary from user statistics tables.



##########################################################################
### WEB-SITE PURPOSE APPLICATION
### - first_row-based using rownum
##########################################################################

select *
from (
select a.*, rownum r
from (your_query_goes_here) a
where rownum <= :max_row)
where r >= :min_row



##########################################################################
### WEB-SITE PURPOSE APPLICATION
### - searches for min_row/max_row within results
### - requires inputs for hint, search_user_name, min_row/max_row value
##########################################################################

create or replace procedure
get_result_set (
p_hint  in varchar2,
p_owner  in varchar2,
p_min_row in varchar2,
p_max_row in varchar2,
p_result_set in out sys_refcursor)
as
begin
open p_result_set
for ' select *
  from (select ' || p_hint || ' a.*.rownum r
    from (select t1.object_name a,
           t2.object_name b
          from big_table t1, big_table t2
          where t1.object_id = t2.object_id
          and t1.owner = :p_owner)a
    where rownum <= :p_max_row)
  where r >= :p_min_row;
using p_owner, p_max_row, p_min_row;
end;
/

exec get_result_set(null, 'WMSYS', 1, 3, :x)

exec get_result_set('/*+ FIRST_ROWS */', 'WMSYS', 10, 30, :x)



##########################################################################
### inserting 1000 rows at the same time
### - DBMS_SQL USAGE
### - PAGE 358
##########################################################################

declare
l_data dbms_sql.number_table;
l_empty dbms_sql.number_table;
begin
for i in 1 .. 1000
loop
  l_data(mod(i,100)) := i;
  if (mod(i,100) = 0)
  then
   forall j in 0 .. l_data.count-1
    insert into t values (l_data(j));
   l_data := l_empty;
  end if;
end loop;
end;
/



##########################################################################
### FOR INVESTIGATING THE CLUSTER'S BLOCK USAGE EFFICIENCY
### shows how many blocks are being used for each cluster index key value
### - DBMS_ROWID USAGE
### - PAGE 527
##########################################################################

select owner,
starting_file_# || '.' || starting_block_#,
ending_file_# || '.' || ending_block_#,
count(*) number_of_rows
(
select b.owner,
  dbms_rowid.rowid_relative_fno(b.rowid) starting_file_#,
  dbms_rowid.rowid_block_number(b.rowid) starting_block_#,
  dbms_rowid.rowid_relative_fno(a.rowid) ending_file_#,
  dbms_rowid.rowid_relative_fno(a.rowid) ending_block_#,
from user_info a, users_objects b
where a.user_name = b.owenr
)
group by owner, starting_file_#, starting_block_#, ending_file_#, ending_block_#



##########################################################################
### SIMULATING OLTP ENVIRONMENT ACCESS
### simulating access of 150,000 times
### - PAGE 537
##########################################################################

declare
l_rec  single_table_hash_cluster%rowtype;
begin
for iters in 1 .. 3
loop
  for i in i .. 50000
  loop
   select * into l_rec
   from single_table_hash_cluster
   where object_id = i;

   select * into l_rec
   from heap_table
   where object_id = i;
  end loop;
end loop;
end;
/



##########################################################################
### DIFF. BETWEEN SINGLE-ROW READ AND BULK-COLLECT READ
### simulating diff. between single-row and bulk collect read using array
### - PAGE 544
##########################################################################

declare
type array is table of varchar2(100);
l_array1 array;
l_array2 array;
l_array2 array;
begin
for i in 1 .. 10
loop
  for x in (select * from all_users)
  loop
   /* single-row read simulation */
   for y in (select col1, col2, col3 from heap single_row
      where username = x.username)
   loop
    null;
   end loop;
   for y in (select col1, col2, col3 from iot single_row
      where username = x.username)
   loop
    null;
   end loop;
   
   /* multi-row read simulation using array and bulk collect */
   select * bulk collect
   into  l_array1, l_array2, l_array3
   from heap bulk_collect
   where username = x.username;
   select * bulk collect
   into  l_array1, l_array2, l_array3
   from iot bulk_collect
   where username = x.username;
  end loop;
end loop;
end;
/

   

##########################################################################
### REF CURSOR and LONG datatype usage
### - PAGE 576
##########################################################################

variable x refcursor

declare
l_stmt long;
begin
for x in (
  select  '''' || column_name || '''' quoted,
   column_name
  from user_tab_columns
  ...)
end loop;
l_stmt := 'select ......';
open :x for l_stmt;
end;
/


##########################################################################
### PL/SQL CODING RUNS FOR 100 HRS
### DBMS_RANDOM USAGE
### - PAGE 644
##########################################################################

declare
l_load number;
begin
for l_hours in 1 .. 100
loop
  for i_hosts in 1 .. 100
  loop
   l_load : dbms_random.random;
   insert into hosts_heap
   (hostname, dt, load, other_stats)
   values
   ('hostnm' || l_hosts, sysdate-(100-l_hours)/24, l_load, 'x');
   insert into host_iot
   (hostname, dt, load, other_stats)
   values
   ('hostnm' || l_hosts, sysdate-(100-l_hours)/24, l_load, 'x');
  end loop;
  commit;
end loop;
end;
/


##########################################################################
### DBMS_APPLICATION_INFO USAGE
### shows the number of function 'f' were being executed within sql.
### - PAGE 654
##########################################################################

create or replace function f
(v_prod_key in number  default null,
v_prc_chk_key in number  default null,
v_return in   varchar2  default null,
v_want_sr in varchar2 defautl null,
v_version in number)
return varchar2
as
begin
dbms_application_info.set_client_info
(userenv('client_info')+1);
return 'x';
end;
/


exec dbms_application_info.set_client_info(0);

select .... f(column_name)

select userenv('client_info') data
from dual;



##########################################################################
### CREATING PAGE NUMBER USING ROWNUM
### - PAGE 659
##########################################################################

select *
from (select /*+ first_rows */ a.*, ROWNUM rnum
  from (your_query_goes_here) a
  where ROWNUM <= :MAX_ROW_TO_FETCH)
where rnum >= :MIN_ROW_TO_FETCH;


== following is bad sql using rownum

select *
from (select /*+ first_rows */ a.* ROWNUM rnum
  from (your_query_goes_here) a )
where rnum between :min_row_to_fetch and :max_row_to_fetch;


##########################################################################
### BULK COLLECT AND DYNAMIC SQL AND ROWNUM SAMPLE
### DBMS_SQL USAGE
### - PAGE 666
##########################################################################

declare
l_owner  dbms_sql.varchar2_table;
l_object_name dbms_sql.varchar2_table;
l_object_type dbms_sql.varchar2_table;
l_created dbms_sql.varchar2_table;

cursor c is
select owner, object_name, object_type, created
from big_table
order by created DESC;

begin
select owner, object_name, object_type, created
bulk collect into l_owner, l_object_name, l_object_type, l_created
from (
  select owner, object_name, object_type, created
  from big_table
  order by created DESC)
where ROWNUM <= 10;

open c;
fetch c bulk collect
into l_owner, l_object_name, l_object_type, l_created
limit 10;
close c;
end;
/


##########################################################################
### SQL TUNING(OUTER JOIN) SAMPLE USING SCALAR SUBQUERY
### - PAGE 675
##########################################################################

- bad sample
select a.username, a.user_id, a.created,
nvl(b.cons_cnt, 0), nvl(c.tables_cnt, 0) tables

from all_users a,

(select owner, count(*) cons_cnt
  from all_constraints
  group by owner) b,

(select owner, count(*) tables_cnt
  from all_tables
  group by owner) c

where a.username = b.owner(+)
and a.username = c.owner(+)
and a.created > sysdate-50
/


- the good one

select a.username, a.user_id, a.created,
nvl(b.cons_cnt, 0) cons, nvl(c.tables_cnt, 0) tables
from all_users a,

(select all_constraints.owner,
  count(*) cons_cnt
  from all_constraints, all_users
  where all_users.created > sysdate - 50
  and all_users.username = all_constraints.owner
  group by owner) b,

(select all_tables.owner,
  count(*) tables_cnt
  from all_tables, all_users
  where all_users.created > sysdate - 50
  and all_suers.username = all_tables.owner
  group by owner) c

where a.username = b.owner(+)
and a.username = c.owner(+)
and a.created > sysdate - 50
/


##########################################################################
### function OVER PARTITION BY ... USAGE SAMPLES
### - from PAGE 680 ~
##########################################################################

select deptno, ename, sal,
sum(sal) over () Total_Salary,
/* shows sum of every employees' salary in every rows */

sum(sal) over (order by deptno, sal) Cum_Total,
/* shows every employee's sequential sum in every rows in order of deptno->sal. */

sum(sal) over (partition by deptno) Salary_By_Dept,
/* shows each dept's salary sum in corrosponding rows. partitioned by deptno */

sum(sal) over (partition by deptno order by sal) Cum_Dept_Total
/* shows each dept's salary sequential sum in order of sal. partitioned by deptno

from emp
order by deptno, sal
/

select owner, last_ddl_time, object_name, object_type
from (
select t1.*,
  max(last_ddl_time) over (partition by owner) max_time
from big_table t1
)
where last_ddl_time = max_time
/


select deptno, ename, sal,
row_number() over (partition by deptno order by sal desc) rn,
rank() over (partition by deptno order by sal desc) rank,
dense_rank() over (partition by deptno order by sal desc) dense_rank
from emp
order by depnto, sal DESC
/


select deptno,
max(decode (dense_rank, 1, sal )) sal1,
max(decode (dense_rank, 2, sal )) sal2,
max(decode (dense_rank, 3, sal )) sal3
from (
select deptno, sal,
  dense_rank() over(partiton by deptno order by sal desc) dense_rank
from emp
)
where dense_rank <= 3
group by deptno
/


select port, activity, nxt_activity,
avg(nxt_activity_date - activity_date) days_between
from (
select port, activity,
  lead(activity) over (partition by order by activity_date) nxt_activity,
  activity_date,
  lead(activity_date) over (partition by port order by activity_date) nxt_activity_date
from t
)
where nxt_activity is not null
group by port, activity, nxt_activity
ordre by 1, 2
/



##########################################################################
### BULK COLELCT USAGE SAMPLES
### DBMS_SQL USAGE
###- PAGE 742
##########################################################################

declare
l_ename  dbms_sql.varchar2_table;
l_empno  dbms_sql.number_table;
l_hiredate dbms_sql.date_table;
begin
for i in 1 .. 5000
loop
  select ename, empno, hiredate
  bulk collect into l_ename, l_empno, l_hiredate
  from emp;
end loop;
end;
/



##########################################################################
### BULK COLELCT and ARRAY USAGE SAMPLES
### - comparing one-at-time and bulk collect
### - shows how to control the array size
### - for oracle 9i r2 and above only
### - PAGE 742
##########################################################################

- bad sample

create or replace procedure row_at_a_time
as
begin
for x in (select * from dba_objects)
loop
  insert into t1 values x;
end loop;
end;
/



/* following code is for oracle9i r2 and above only */

create or replace procedure nrows_at_a_time
(p_array_size in number)
as
type array is table of dba_objects%rowtype;
l_data array;
cursor c is select * from dba_objects;
begin
open c;
loop
  fetch c bulk collect into l_data LIMIT p_array_size;
  forall i in 1 .. l_data.count
   insert into t2 values l_data(i);
  exit when c%notfound;
end loop;
end;
/


##########################################################################
### BULK COLELCT using ARRAY VS REF CURSOR
### - ref cursor is better then bulk collect in client environment
### - PAGE 752
##########################################################################

create or replace package demo_pkg
as
type varchar2_array is table of varchar2(30)
index by binary_integer;

type rc is ref cursor;

procedure index_by (
  p_owner  in varchar2,
  p_object_name  out varchar2_array,
  p_object_type out varchar2_array,
  p_timestamp out varchar2_array);

procedure ref_cursor (
  p_owner  in varchar2,
  p_cursor in out rc);
end;
/


create or replace package body demo_pkg
as

procedure index_by (
  procedure index_by (
  p_owner  in varchar2,
  p_object_name  out varchar2_array,
  p_object_type out varchar2_array,
  p_timestamp out varchar2_array);
is
begin
select object_name, object_type, timestamp
bulk collect into
  p_object_name, p_object_type, p_timestamp
from t
where owner = p_owner;
end;

procedure ref_cursor (
  p_owner  in varchar2,
  p_cursor  in out rc)
is
open p_cursor for
select object_name, object_type, timestamp
from tS
where owner = p_owner;
end;

end;
/
   


##########################################################################
### BULK COLELCT using ARRAY SAMPLE
### - PAGE 777
##########################################################################

create or replace procedure
array_fetch_heap_insert
(p_arraysize in number default 100)
as
type array is table of all_objects.object_name%type
  index by binary_integer;
l_key_col array;
cursor c is select object_name from all_objects;
begin
open c;
loop
  fetch c bulk colelct into l_key_col limit p_arraysize;

  forall i in 1 .. l_key_col.count
   insert into built_by_us (key_col, key_val)
   values (l_key_col(i),
    (select key)val
     from lookup_heap
     where key_col = l_key_col (i))
    )
  exit when c%notfound;
end loop;
close c;
end;
반응형

'Db > Oracle' 카테고리의 다른 글

Oracle cursor 간단 sample  (1) 2010.04.06
Oracle row_number() sample  (2) 2010.04.06
Oracle View Sample  (2) 2010.04.06
Oracle Trigger Sample  (1) 2010.04.06
Oracle Sequence Sample  (2) 2010.04.06
Posted by seongsland