学习DBMS (二) 预览
纯个人笔记,只为个人记忆,所以表述很不严谨!
最近看书看的头痛,就随便翻了一下<<PL/SQL Packages and Types Reference 10g Release 2 (10.2)>>,随便的记了一下笔记,因为只是为了自己记忆方便,所以很多地方表述的都不严谨,如果是谁不小心看到了,望见谅!
其实一些个包比如DBMS_STATS,DBMS_JOB,dbms_profiler,DBMS_SPACE的若干过程,函数还是经常用到的,但却从来没有仔细的看过这些个包的使用文档,这次也算是小小的弥补了一下.
如果你只是一个DBA的话,其实一些个DBMS包是不需要你去记住的,比如说DBMS_DATAPUMP,其实EXPDP,IMPDP就是调用DBMS_DATAPUMP,DBMS_METADATA来实现的,所以其实你不需要去理解DBMS_DATAPUMP,只需要理解EXPDP,IMPDP这些个工具如何使用就可以了.再比如dbms_debug,dbms_trace是pl/sql developer,toad这些厂商调用的包,其实很多时候你只需要理解这些个工具如何使用就可以了!
dbms_application_info(看了)
dbms_job(看了) 不能停止一个正在运行的JOB,breaken就是DISABLE,但如何重新ENABLE呢?WHAT=>'zsj_test_proc();',注意最后的;是必须的.
dbms_lock(看了) dbms_lock.sleep(60) sleep 1 分钟
dbms_logmnr_d: V$logmnr_contents 包dbms_logmnr_d抽取LOGMNR数据字典信息用于将来的分析(因为可能分析时某个对象在DB中已经不存在了);在另一个表空间中重建LOGMNR表
dbms_metadata get_ddl('TABLE','EMP','SCOTT')只能得到一个单独的对象的定义
dbms_monitor
dbms_output: SQL*PLUS下set serveroutput on size 99999之后就不必调用dbms_output.enable(99999)了,但dbms_output.enable()不能代替set serveroutput on;
dbms_profiler(看了)
dbms_random(看了)
dbms_resumable(看了)
dbms_scheduler(看了) stop_job停止正在运行的JOB
dbms_server_alert(看了) :没有用户空间配额使用的dbms_server_alert设置吗?如果知道的,看到了麻烦回复一下,先谢谢了!
dbms_session(看了)
dbms_shared_pool(看了)
dbms_space:理解其中的含义,分配的盘区(TOTAL_BLOCKS),HWM(TOTAL_BLOCKS-UNUSED_BLOCKS),HWM下的空闲块(FREE_BLOCKS可用于插入数据的块).Last Used Ext BlockId:段头块(不能用来插入数据的),Last Used Block:总共使用的块数(包括段头块)
dbms_space_admin(大致看了看)
dbms_tts(看了)
dbms_workload_repository(看了)
dbms_xplan(看了)
dbms_utility(看了)
dbms_trace(看了)
dbms_rowid(看了),注意object_number指的是data_object_id,而不是object_id(刚开始时,两者是一样的,但truncate table时,data_object_id+1,object_id不变)
dbms_system,dbms_standard(不提供文档支持吗??????)
dbms_advisor,dbms_sqltune,dbms_stats:这三个主要的包倒没有看,因为实在是太多了,以后一定补上!
dbms_ddl的一个使用例子:
BEGIN
FOR X IN(SELECT OBJECT_NAME,OBJECT_TYPE FROM USER_OBJECTS WHERE STATUS='INVALID')
loop
BEGIN
Dbms_Ddl.alter_compile(x.object_type,NULL,x.object_name);
EXCEPTION
WHEN OTHERS THEN
Dbms_Output.PUT_LINE('无法编译'||x.object_type||':'||x.object_name);
END;
END LOOP;
END;
/
当然ORACLE不建议使用这个过程,如果要是编译整个模式对象的话,可以使用dbms_utility.compile_schema.
dbms_utility:
comma_to_table:将以逗号分割的列表转化为字符table
compile_schema:编译特定模式下的所有procedure,function,trigger,package body
get_cpu_time
get_dependency
get_hash_value
get_time
table_to_comma
declare
v_name dbms_utility.lname_array;
v_list varchar2(2560);
v_len number;
begin
select ename bulk collect into v_name from scott.emp where deptno=10;
dbms_utility.table_to_comma(v_name,v_len,v_list);
dbms_output.put_line(v_list);
end;
/
dbms_alert的使用一个例子:
alert是基于事务的,也许发出alert的会话发出的alert会很多,但等待会话只接受到发出alert的会话commit前最后发出的alert,以前的alert都被抛弃了;如果在signal之后事务被rollback了,那么没有alert发出.多个session可以并发的往同一个alert中signal,但它们是串行执行的,也就是说直到一个会话commit,另一个会话的signal才能成功!是多读者的.
DBMS_PIPE是独立于事务的.一个message一旦被接受,它就从pipe中被删除,所以一个message只能被接受一次.也就是说是一个单消耗者的.private pipe只有创建者用户和sysdba特权用户可以访问.
create or replace trigger zsj_alert_trigger
after insert or delete on test
declare
v_count number;
begin
select count(1) into v_count from test;
if(inserting) then
dbms_alert.signal('zsj_alert','inserting:'||v_count);
elsif(deleting) then
dbms_alert.signal('zsj_alert','deleting:'||v_count);
end if;
end;
/
CREATE TABLE zsj_alert_table(TIME DATE,message VARCHAR2(256));
declare
v_message varchar2(256);
v_status number;
begin
dbms_alert.register('zsj_alert');
while(1=1)
loop
dbms_alert.waitone('zsj_alert',v_message,v_status);
if(v_status=0) then
insert into zsj_alert_table values(sysdate,v_message);
commit;
SELECT LTrim(RTrim(translate(v_message,'insertingdeleting: ',' '))) into v_status FROM dual;
exit when(v_status=0);
end if;
end loop;
dbms_alert.remove('zsj_alert');
end;
/
dbms_pipe的一个使用例子:
declare
v_status number;
begin
v_status:=dbms_pipe.create_pipe('zsj_test_pipe');
if(v_status=0) then
dbms_pipe.reset_buffer();
dbms_pipe.pack_message('I Love Myself!');
dbms_pipe.pack_message(6688);
v_status:=dbms_pipe.send_message('zsj_test_pipe');
end if;
end;
/
declare
v_str varchar2(50);
v_num number;
v_status number;
begin
dbms_pipe.reset_buffer();
v_status:=dbms_pipe.receive_message('zsj_test_pipe');
if(v_status=0) then
dbms_pipe.unpack_message(v_str);
dbms_pipe.unpack_message(v_num);
v_status:=dbms_pipe.remove_pipe('zsj_test_pipe');
dbms_output.put_line(v_str||','||v_num);
end if;
end;
/
dbms_trace的使用:
首先必须以sys用户运行$ORACLE_HOME/rdbms/admin下的tracetab.sql,然后使用pl/sql developer等第三方工具就可以了,这里要注意 ENABLED的意思:
alter session set plsql_debug=true; create or replace ***; 这里的创建的程序单元算是Enabled的,是要被跟踪的.
或者alter [PROCEDURE | FUNCTION | PACKAGE BODY] <libunit-name> compile debug;这里的程序单元算是Enabled的,是要被跟踪的.而跟踪ALL的时候,生成的数据量太大了.注意它只跟踪本会话内set_plsql_trace和CLEAR_PLSQL_TRACE之间ENABLED或者是ALL的东西,并不是说可以在全局启动,然后跟踪ALL的会话或者说这些会话中ENABLE的东西,不是这样的.
exec dbms_trace.set_plsql_trace(dbms_trace.trace_enabled_sql);
exec dbms_trace.CLEAR_PLSQL_TRACE();
select sys.plsql_trace_runnumber.currval from dual;
dbms_profiler的使用:(也可以使用第三方工具)
首先运行$ORACLE_HOME/rdbms/admin下的profload.sql建立DBMS_PROFILER包,proftab.sql建立存储表,序列,公共同义词
脚本:
set heading off
set pagesize 0
--启动profiler
declare
v_status number;
v_runid number;
begin
v_status:=DBMS_PROFILER.START_PROFILER(sysdate,'',v_runid);
if(v_status!=0) then
dbms_output.put_line('启动失败!错误代码:'||v_status);
else
dbms_output.put_line('启动成功,RUNID:'||v_runid);
end if;
end;
/
--下面是你的测试代码,测试的应该是存储过程,函数等,不应该是匿名块
BEGIN
zsj_compile_proc();
END;
/
--关闭profiler:
select decode(DBMS_PROFILER.STOP_PROFILER,0,'关闭成功!','关闭失败!') from dual;
--flush_data:
select decode(DBMS_PROFILER.flush_data,0,'flush_data成功!','flush_data失败!') from dual;
undef runid
undef owner
undef name
set verify off
set linesize 200
set pagesize 0
spool d:zsj_profile_out.txt
select s.line "Line", p.total_occur "Occur", p.total_time "Msec", s.text "Text"
from all_source s,
(select u.unit_owner, u.unit_name, u.unit_type, d.line#,
d.total_occur, d.total_time/1000000 total_time
from plsql_profiler_data d, plsql_profiler_units u
where u.runid = &&runid
and u.runid = d.runid
and u.unit_number = d.unit_number) p
where s.owner = p.unit_owner (+)
and s.name = p.unit_name (+)
and s.type = p.unit_type (+)
and s.line = p.line# (+)
and s.name = upper('&&name')
and s.owner = upper('&&owner')
order by s.line;
select exec.cnt/total.cnt * 100 "Code% coverage"
from (select count(1) cnt
from plsql_profiler_data d, plsql_profiler_units u
where d.runid = &&runid
and u.runid = d.runid
and u.unit_number = d.unit_number
and u.unit_name = upper('&&name')
and u.unit_owner = upper('&&owner')) total,
(select count(1) cnt
from plsql_profiler_data d, plsql_profiler_units u
where d.runid = &&runid
and u.runid = d.runid
and u.unit_number = d.unit_number
and u.unit_name = upper('&&name')
and u.unit_owner = upper('&&owner')
and d.total_occur > 0) exec;
undef runid
undef owner
undef name