/* *使用ORACLE系统包 */ --1.DBMS_OUTPUT --ENABLE:用于激活过程PUT,PUT_LINE,NEW_LINE,GET_LINE和GET_LINES的调用 --语法:DBMS_OUTPUT.enable(buffer_size in integer default 20000); --DISABLE:用于禁止对过程PUT,PUT_LINE,NEW_LINE,GET_LINE和GET_LINES的调用 --语法:DBMS_OUTPUT.disable; --PUT和PUT_LINE:用于将一个完整行的信息写入到缓冲区中,过程PUT则用于分块建立行信息 --当使用过程PUT_LINE时,会自动在行的尾部追加行结束符,当使用过程PUT时,需要使用过程NEW_LINE追加行结束符 --语法:DBMS_OUTPUT.PUT(item in number); --DBMS_OUTPUT.put_line(item in number); --当在SQLPLUS中使用过程PUT和PUT_LINE,需要设置SERVEROUTPUT选项 SET SERVEROUTPUT ON BEGIN DBMS_OUTPUT.put_line('伟大的中华民族'); dbms_output.put('中国'); dbms_output.put(',伟大的祖国'); dbms_output.new_line; END; --NEW_LINE:用于在行的尾部追加行结束符 --GET_LINE和GET_LINES --GET_LINE用于取得缓冲区的单行信息,过程GET_LINES用于取得缓冲区的多行信息 --示例1 --在SQLPLUS中运行 declare line varchar2(100); status number; begin dbms_output.enable; dbms_output.put_line('伟大的中华民族'); dbms_output.put('中国'); dbms_output.put(',伟大的祖国'); dbms_output.new_line; dbms_output.get_line(line,status); end; --使用GET_LINES DECLARE type line_table_type is table of varchar2(255) index by binary_integer; line_table line_table_type; lines number(38):=3; begin dbms_output.enable; dbms_output.put_line('伟大的中华民族'); dbms_output.put('中国'); dbms_output.put(',伟大的祖国'); dbms_output.new_line; dbms_output.get_lines(line_table,lines); end; --2.DBMS_JOB --SUBMIT:用于建立一个新作业,当建立作业时,需要给出作业要执行的操作、作业的下次运行日期以及运行时间间隔 --创建emp表 create table emp ( empno NUMBER(10), ename NVARCHAR2(255), sal NUMBER(10,2), hiredate Timestamp, comm NUMBER(10,2), job NVARCHAR2(255), deptno NUMBER(10) ) insert into emp(empno,ename,sal,hiredate,comm,job,deptno) values(100,'Test',30.5,sysdate,10,'president',1); insert into emp(empno,ename,sal,hiredate,comm,job,deptno) values(7788,'Test2',100.23,sysdate,10.2,'manager',2); commit; begin dbms_ddl.analyze_object('TABLE','HAIYA','EMP','COMPUTE'); end; begin dbms_ddl.analyze_object('TABLE','HAIYA',upper('emp'),'ESTIMATE',NULL,20,'for table'); end; --以建立用于分析HAIYA.EMP表的作业为例,说明建立作业的方法 declare jobno number; begin dbms_job.submit(jobno,'dbms_ddl.analyze_object(''TABLE'',''HAIYA'',''EMP'',''COMPUTE'');',sysdate,'SYSDATE+1'); dbms_output.put_line(jobno); commit; end; --REMOVE:用于删除作业队列中的特定作业 begin dbms_job.remove(22); end; --change:用于改变与作业相关的所有信息 begin dbms_job.change(21,null,null,'SYSDATE+2'); end; --WHAT:用于改变作业要执行的操作 --下面改变作业21的运行操作为例,说明使用WHAT过程的方法 begin dbms_job.what(21,'dbms_stats.gather_table_stats(''HAIYA'',''EMP'');'); end; --NEXT_DATE:用于改变作业的下次运行日期 begin dbms_job.next_date(21,SYSDATE+1); end; --INSTANCE:用于改变运行作业的例程 begin dbms_job.instance(21,1); end; --INTERVAL:用于改变作业的运行时间间隔 begin dbms_job.interval(21,'SYSDATE+1/24/60'); end; --BROKEN:用于设置作业的中断标记 begin dbms_job.broken(21,true,SYSDATE+1); end; begin dbms_job.broken(21,true); end; begin dbms_job.broken(21,false); end; --RUN:用于运行已存在的作业 begin dbms_job.run(21); end; --作业使用示例 --建立作业 declare jobno number; begin dbms_job.submit(jobno,'dbms_stats.gather_schema_stats(''SCOTT'');',sysdate,'SYSDATE+1'); dbms_output.put_line(jobno); commit; end; --运行作业 begin dbms_job.run(21); end; --3.DBMS_PIPE --包DBMS_PIPE用于在同一例程的不同会话之间进行管道通信,Oracle管道类似于UNIX系统的管道,但它不是采用操作系统机制实现的,其管道信息被缓存在SGA中,当关闭例程时会丢失管道信息 --如果用户要执行包DBMS_PIPE中的过程和函数,则必须要为用户授权 conn sys/kingdee as sysdba grant execute on dbms_pipe to haiya; --CREATE_PIPE:用于建立公用管道或私有管道,如果将参数private设置为TRUE,则建立私有管道,如果设置为FALSE,则建立公用管道 --下面以建立公用管道public_pipe为例,说明使用该函数的方法 declare flag int; begin flag:=dbms_pipe.create_pipe('public_pipe',8192,FALSE); if flag=0 then dbms_output.put_line('建立公用管道成功'); end if; end; --PACK_MESSAGE:用于将消息写入到本地消息缓冲区 --为了给管道发送消息,首先需要使用过程PACK_MESSAGE将消息写入到本地消息缓冲区,然后使用过程SEND_MESSAGE将本地消息缓冲区中的消息发送到管道 --下面以将雇员写入本地消息缓冲区为例,说明使用该过程的方法 DECLARE v_ename emp.ename%TYPE; v_sal emp.sal%TYPE; v_rowid rowid; begin select ename,sal,rowid into v_ename,v_sal,v_rowid from emp where empno=&no; dbms_pipe.pack_message('雇员名:'||v_ename); dbms_pipe.pack_message('工资:'||v_sal); dbms_pipe.pack_message('ROWID:'||v_rowid); end; select * from emp; --SEND_MESSAGE:用于将本地消息缓冲区中的内容发送到管道 --下面以将本地缓冲区消息发送到PUBLIC_PIPE为例,说明使用函数SEND_MESSAGE的方法 DECLARE flag int; begin flag:=dbms_pipe.send_message('PUBLIC_PIPE'); if flag=0 then dbms_output.put_line('消息成功发送到管道'); end if; end; --RECEIVE_MESSAGE --用于接收管道消息,并将接收到的消息写入到本地消息缓冲区 --当接收到管道消息后,会删除管道消息。注意,管道消息只能被接收一次。 --如果函数返回0,则表示接收消息成功,如果函数返回1,则表示出现超时,如果函数返回2,则表示本地缓冲区不能容纳管道消息,如果函数返回3,则表示发生中断 --下面以接收管道public_pipe的消息为例,说明接收管道消息的方法 declare flag int; begin flag:=dbms_pipe.receive_message('PUBLIC_PIPE'); if flag = 0 then dbms_output.put_line('接收公用管道消息成功'); end if; end; --NEXT_ITEM_TYPE:用于确定本地消息缓冲区下一项的数据类型,在调用了RECEIVE_MESSAGE之后调用该函数 --如果该函数返回0,则表示管道没有任何消息,如果返回6,则表示下一项的数据类型为NUMBER,如果返回9,则表示下一项的数据类型为VARCHAR2 --如果返回11,则表示下一项的数据类型为ROWID,如果返回12,则表示下一项的数据类型为DATE,如果返回23,则表示下一项的数据类型为RAW declare item_no int; begin item_no:=dbms_pipe.next_item_type; dbms_output.put_line('项编号:'||item_no); end; --UNPACK_MESSAGE:用于将消息缓冲区中的内容写入到变量中。 --在使用函数RECEIVE_MESSAGE接收到管道消息之后,应该使用过程UNPACK_MESSAGE取得消息缓冲区的消息 --当使用过程UNPACK_MESSAGE取出消息缓冲区的消息时,每次只能取出一条消息,如果要取出多条消息,则需要多次调用过程UNPACK_MESSAGE declare message varchar2(100); begin dbms_pipe.unpack_message(message); dbms_output.put_line(message); end; --REMOVE_PIPE:用于删除已经建立的管道 --如果返回0,则表示删除管道成功,否则会显示错误信息。 --下面以删除公用管道PUBLIC_PIPE为例,说明使用该函数的方法 DECLARE flag int; begin flag:=dbms_pipe.remove_pipe('PUBLIC_PIPE'); if flag = 0 then dbms_output.put_line('删除公用管道成功'); end if; end; --PURGE:用于消除管道中的内容 --语法:dbms_pipe.purge(pipename in varchar2); --RESET_BUFFER:用于复位管道缓冲区 --因为所有管道都共享单个管道缓冲区,所以在使用新管道之前应该复位管道缓冲区 --语法:dbms_pipe.reset_buffer; --UNIQUE_SESSION_NAME:用于为特定会话返回惟一的名称,并且名称的最大长度为30字节,对于同一会话来说,其值不会改变 declare v_session varchar2(200); begin v_session:=dbms_pipe.unique_session_name; dbms_output.put_line(v_session); end; --管理使用示例 --当使用管道时,一个会话需要将消息发送到管道中,而另一个会话则需要接收管道消息,当发送消息到管道时,需要首先将消息写入本地消息缓冲区, --然后将本地消息缓冲区内容发送到管道,当接收管道消息时,需要首先使用本地消息缓冲区接收管道消息,然后从消息缓冲区中取得具体消息 --下面以建立过程send_message和receive_message,并使用这两个过程发送和接收消息为例,说明使用管道的方法 --示例一:建立过程send_message,用于建立管道并发送消息 CREATE OR REPLACE PROCEDURE send_message( pipename varchar2,message varchar2) is flag int; begin flag:=dbms_pipe.create_pipe(pipename); if flag=0 then dbms_pipe.pack_message(message); flag:=dbms_pipe.send_message(pipename); end if; end; --示例二:建立过程receive_message,用于接收并输出管道消息 create or replace procedure receive_message( pipename varchar2,message out varchar2) is flag int; begin flag:=dbms_pipe.receive_message(pipename); if flag = 0 then dbms_pipe.unpack_message(message); flag:=dbms_pipe.remove_pipe(pipename); end if; end; --示例三:使用过程send_message --在SQLPLUS中执行 --会话一: exec send_message('pipe1','你好吗') --会话二: var message varchar2(100) exec haiya.receive_message('pipe1',:message) print message --4.DBMS_ALERT --包DBMS_ALERT用于生成并传递数据库预警信息,合理地使用包和数据库触发器,可以使得在发生特定数据库事件时将信息传递给应用程序 --但是,如果某个数据库用户要使用包DBMS_ALERT,则必须要以SYS登录,为该用户授予执行权限 conn sys/kingdee as sysdba grant execute on dbms_alert to haiya; --REGISTER:用于注册预警事件 begin dbms_alert.register('alert1'); end; --REMOVE:用于删除会话不需要的预警事件 begin dbms_alert.remove('alert1'); end; --REMOVEALL:用于删除当前会话所有已经注册的预警事件 begin dbms_alert.removeall; end; --SET_DEFAULTS:用于设置检测预警事件的时间间隔,默认时间间隔为5秒 begin dbms_alert.set_defaults(20); end; --SIGNAL:用于指定预警事件所对应的预警消息,只有在提交事务时才会发出预警信号,而当回退事务时不会发出预警信号 begin dbms_alert.signal('alert1','hello'); end; --WAITANY:用于等待当前会话的任何预警事件,并且在预警事件发生时输出相应信息。在执行该过程之前,会隐含地发出COMMIT --WAITONE:用于等待当前会话的特定预警事件,并且在发生预警事件时输出预警消息。在执行该过程之前,会隐含地发出COMMIT --预警事件使用示例 --以修改雇员工资发出预警事件为例,说明如何在应用程序中使用预警事件 --示例一:建立触发器tr_update_sal create or replace trigger tr_upd_sal after update of sal on emp begin dbms_alert.signal('sal_upd_alert','修改了雇员工资'); end; --示例二:建立过程wait_event create or replace procedure wait_event(name varchar2) is message varchar2(200); status int; begin dbms_alert.register(name); dbms_alert.waitone(name,message,status); if status = 0 then dbms_output.put_line('预警消息:'||message); end if; dbms_alert.remove(name); end; --示例三:使用预警事件 --如下所示,当执行了以下PL/SQL块之后,会话就会处于等待状态,当其他会话修改了雇员工资之后,就会显示预警消息。 --在显示了5次预警消息之后,会退出循环 declare i number; begin for i in 1..5 loop wait_event('sal_upd_alert'); end loop; end; --5.DBMS_TRANSACTION --用于在过程、函数和包中执行SQL事务处理语句 --READ_ONLY:用于开始只读事务,其作用于SQL语句SET TRANSACTION READ ONLY完全相同 --注意,该过程必须是事务开始的第一条语句 --语法:DBMS_TRANSACTION.READ_ONLY; --READ_WRITE:用于开始读写事务,其作用与SQL语句SET TRANSACTION READ WRITE完全相同 --注意,该过程必须是事务开始的第一条语句 --语法:DBMS_TRANSACTION.READ_WRITE; --ADVISE_ROLLBACK:用于建议回退远程数据库的分布式事务,其作用与SQL语句ALTER SESSION ADVISE ROLLBACK完全相同 --语法:DBMS_TRANSACTION.ADVISE_ROLLBACK; --ADVISE_NOTHING:用于建议远程数据库的分布式事务不进行任何处理,其作用与SQL语句ALTER SESSION ADVISE NOTHING完全相同 --语法:DBMS_TRANSACTION.ADVISE_NOTHING; --ADVISE_COMMIT:用于建议提交远程数据库的分布式事务,其作用与SQL语句ALTER SESSION ADVISE COMMIT完全相同 --语法:DBMS_TRANSACTION.ADVISE_COMMIT; --USE_ROLLBACK_SEGMENT:用于指定事务所要使用的回滚段,其作用与SQL语句SET TRANSACTION USE ROLLBACK SEGMENT回滚段名作用完全相同 --语法:DBMS_TRANSACTION.USE_ROLLBACK_SEGMENT(rb_name VARCHAR2); --如上所示,rb_name用于指定事务所要使用的回滚段名称 --COMMIT_COMMENT:用于在提交事务时指定注释,其作用与SQL语句COMMIT COMMENT<text>完全相同 --语法:DBMS_TRANSACTION.COMMIT_COMMENT(cmnt VARCHAR2); --如上所示,cmnt用于指定与事务相关的注释信息 --COMMIT_FORCE:用于强制提交分布式事务,其作用与SQL语句COMMIT FORCE text,number完全相同。 --语法:DBMS_TRANSACTION.COMMIT_FORCE(xid VARCHAR2,scn VARCHAR2 DEFAULT NULL); --如上所示,xid用于指定事务ID号,scn用于指定系统改变号 --COMMIT:用于提交当前事务,其作用与SQL语句COMMIT完全相同 --语法:DBMS_TRANSACTION.COMMIT; --SAVEPOINT:用于设置保存点,其作用与SQL语句SAVEPOINT savepoint完全相同 --语法:DBMS_TRANSACTION.SAVEPOINT(savept VARCHAR2); --如上所示,savept用于指定保存点名称 --ROLLBACK:用于回退当前事务,其作用与SQL语句ROLLBACK完全相同 --语法:DBMS_TRANSACTION.ROLLBACK; --ROLLBACK_SAVEPOINT:用于回退到保存点,并取消部分事务,其作用与SQL语句ROLLBACK TO SAVEPOINT<savepoint_name>完全相同 --语法:DBMS_TRANSACTION.ROLLBACK_SAVEPOINT(savept VARCHAR2); --如上所示,savept用于指定要回退到的保存点名称 --ROLLBACK_FORCE:用于强制回退分布式事务,其作用与SQL语句ROLLBACK FORCE<text>完全相同 --语法:DBMS_TRANACTION.ROLLBACK_FORCE(xid VARCHAR2); --如上所示,xid用于指定事务ID号 --BEGIN_DISCRETE_TRANSACTION:用于开始独立事务模式 --语法:DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION; --PURGE_MIXED:用于清除分布式事务的混合事务结果 --语法:DBMS_TRANSACTION.PURGE_MIXED(xid VARCHAR2); --如上所示,xid用于指定事务ID号 --PURGE_LOST_DB_ENTRY:用于清除本地数据库所记载的远程事务入口,该事务入口操作因为远程数据库问题未能在远程数据库完成 --语法:DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(xid VARCHAR2); --如上所示,xid用于指定事务入口号 --LOCAL_TRANSACTION_ID:用于返回当前事务的事务标识号 --语法:DBMS_TRANSACTION.LOCAL_TRANSACTION_ID(create_transaction BOOLEAN:=FALSE) return VARCHAR2; --如上所示,create_transaction用于指定是否要启动新事务,如果设置为TRUE,则会启动新事务 --STEP_ID:用于返回排序DML事务的惟一正整数 --语法:DBMS_TRANSACTION.STEP_ID RETURN NUMBER; --6.DBMS_SESSION --该包提供了使用PL/SQL实现ALTER SESSION命令,SET ROLE命令和其他会话信息的方法 --SET_IDENTIFIER:用于设置会话的客户ID号 --语法:DBMS_SESSION.SET_IDENTIFIER(client_id VARCHAR2); --如上所示,client_id用于指定当前会话的应用标识符 --SET_CONTEXT:用于设置应用上下文属性 --语法:DBMS_SESSION.SET_CONTEXT(namespace VARCHAR2,attribute VARCHAR2,value VARCHAR2); --DBMS_SESSION.SET_CONTEXT(namespace VARCHAR2,attribute VARCHAR2,value VARCHAR2,username VARCHAR2,client_id VARCHAR2); --如上所示,namespace用于指定应用上下文的命名空间,attribute用于指定应用上下文的属性,value用于指定属性值,username用于指定应用上下文的用户名属性 --CLEAR_CONTEXT:用于清除应用上下文的属性设置 --语法:DBMS_SESSION.CLEAR_CONTEXT(namespace VARCHAR2,client_identifier VARCHAR2,attribute VARCHAR2); --如上所示,client_identifier只适用于全局上下文 --CLEAR_IDENTIFIER:用于删除会话的set_client_id --语法:DBMS_SESSION.CLEAR_IDENTIFIER(); --SET_ROLE:用于激活或禁止会话角色,与SQL语句SET ROLE作用完全相同 --语法:DBMS_SESSION.SET_ROLE(role_cmd VARCHAR2); --如上所示,role_cmd会追加到set role命令之后 --例: begin dbms_session.set_role('DBA'); end; --SET_SQL_TRACE:用于激活或禁止当前会话的SQL跟踪,其作用与SQL语句ALTER SESSION SET SQL_TRACE=..完全相同 --语法:DBMS_SESSION.SET_SQL_TRACE(sql_trace boolean); --如上所示,sql_trace用于指定布尔值,当设置为TRUE时,表示激活SQL跟踪,当设置为FALSE时,表示禁止SQL跟踪 --例: begin dbms_session.set_sql_trace(true); end; --SET_NLS:用于设置NLS特征,其作用与SQL语句ALTER SESSION SET<nls_param>=<value>完全相同 --语法:DBMS_SESSION.SET_NLS(param VARCHAR2,value VARCHAR2); --如上所示,param用于指定NLS参数,value用于指定NLS参数的值 --在SQLPLUS中使用该过程设置NLS参数的示例如下 exec dbms_session.set_nls('nls_date_format','''YYYY-MM-DD'''); select sysdate from dual; --CLOSE_DATABASE_LINK:用于关闭已经打开的数据库链,其作用与SQL语句ALTER SESSION CLOSE DATABASE LINK<name>完全相同 --语法:DBMS_SESSION.CLOSE_DATABASE_LINK(dblink VARCHAR2); --如上所示,dblink用于指定要关闭的数据库链名 --RESET_PACKAGE:用于复位当前会话的所有包,并且会释放包状态 --语法:DBMS_SESSION.RESET_PACKAGE; --MODIFY_PACKAGE_STATE:用于修改当前会话的PL/SQL程序单元的状态 --语法:DBMS_SESSION.MODIFY_PACKAGE_STATE(action_flags IN PLS_INTEGER); --如上所示,action_flags用于指定PL/SQL程序单元位标记,当设置为1时,会释放PL/SQL程序单元所占用的内存,当设置为2时,会重新初始化PL/SQL包 --UNIQUE_SESSION_ID:用于返回当前会话的惟一ID标识符,在SQLPLUS中使用该函数的示例如下: select dbms_session.unique_session_id from dual; --IS_ROLE_ENABLED:用于确定当前会话是否激活了特定角色 --语法:DBMS_SESSION.IS_ROLE_ENABLED(rolename VARCHAR2) RETURN BOOLEAN; --如上所示,rolename用于指定角色名,如果返回TRUE,则表示角色被激活,如果返回FALSE,则表示角色未被激活 begin if dbms_session.is_role_enabled('CONNECT') then dbms_output.put_line('CONNECT角色被激活'); end if; end; --IS_SESSION_ALIVE:用于确定特定会话是否处于活动状态 --语法:DBMS_SESSION.IS_SESSION_ALIVE(uniqueid VARCHAR2) RETURN BOOLEAN; --SET_CLOSE_CACHED_OPEN_CURSORS:用于打开或关闭close_cached_open_cursors,其作用与ALTER SESSION SET_CLOSE_CACHED_OPEN_CURSORS完全相同 --语法:DBMS_SESSION.SET_CLOSE_CACHED_OPEN_CURSORS(close_cursors BOOLEAN); --FREE_UNUSED_USER_MEMORY:用于执行了大内存操作(超过100K)之后回收未用内存 --语法:DBMS_SESSION.FREE_UNUSED_USER_MEMORY; --SET_CONTEXT:用于设置应用上下文属性的值 --语法:DBMS_SESSION.SET_CONTEXT(namespace VARCHAR2,attribute VARCHAR2,value VARCHAR2,username VARCHAR2,client_id VARCHAR2); --LIST_CONTEXT:用于返回当前会话的命名空间和上下文列表 --语法:TYPE AppCtxRecTyp IS RECORD(namespace VARCHAR2(30),attribute VARCHAR2(30),value VARCHAR2(256)); --TYPE AppCtxTabTyp IS TABLE OF AppCtxRecTyp INDEX BY BINARY_INTEGER; --DBMS_SESSION.LIST_CONTEXT(list OUT AppCtxTabTyp,size OUT NUMBER); --如上所示,list用于取得当前会话的列表集,size用于返回列表个数 --SWITCH_CURRENT_CONSUMER_GROUP:用于改变当前会话的资源使用组 --语法:DBMS_SESSION.switch_current_consumer_group(new_consumer_group in varchar2,old_consumer_group out varchar2,initial_group_on_error in boolean); --如上所示,new_consumer_group用于指定新资源使用组,old_consumer_group用于取得原有资源使用组,initial_group_on_error用于指定布尔值0230C88.0001.0000','HAIYA','EMP',0) from dual; --8.DBMS_RLS --包DBMS_RLS只适用于ORACLE ENTERPRISE EDITION,它用于实现精细访问控制,并且精细访问控制是通过在SQL语句中动态增加谓词(WHERE子句)来实现的 --通过使用ORACLE的精细访问控制特征,可以使不同数据库用户在执行相同SQL语句时操作同一张表上的不同数据 --如通过使用策略EMP_ACCESS,不同用户在执行相同SQL语句时,可以返回不同结果 --ADD_POLICY:用于为表、视图或同义词增加一个安全策略,当执行该操作结束时会自动提交事务 --DBMS_RLS.ADD_POLICY(object_schema IN VARCHAR2 NULL,object_name in VARCHAR2,policy_name IN VARCHAR2, --function_schema in varchar2 null,policy_function in varchar2,statement_types in varchar2 null, --update_check in boolean false,enable in boolean true,static_policy in boolean false); --如上所示,object_schema用于指定包含表、视图或同义词的方案(默认值NULL表示当前方案) --object_name用于指定要增加安全策略的表、视图或同义词 --policy_name用于指定要增加的安全策略名称,function_schema用于指定策略函数的所在方案(默认值NULL表示当前方案) --policy_function用于指定生成安全策略谓词的函数名 --statement_types用于指定使用安全策略的SQL语句(默认值NULL表示适用于SELECT,INSERT,UPDATE以及DELETE语句) --update_check用于指定在执行INSERT或UPDATE时是否检查安全策略 --enable用于指定是否要激活安全策略 --static_policy用于指定是否要生成静态的安全策略 --DROP_POLICY:用于删除定义在特定表、视图或同义词上的安全策略,当执行该操作结束时会自动提交事务 --语法:DBMS_RLS.DROP_POLICY(object_schema IN VARCHAR2 NULL,object_name in VARCHAR2,policy_name in VARCHAR2); --REFRESH_POLICY:用于刷新安全策略修改相关的所有SQL语句,并使得ORACLE重新解析相关SQL语句,当执行完该操作结束时会自动提交事务 --语法:DBMS_RLS.REFRESH_POLICY(object_schema in varchar2 null,object_name in varchar2 null,policy_name in varchar2 null); --ENABLE_POLICY:用于激活或禁止特定的安全策略,默认情况下当增加安全策略时会自动激活,当执行该操作结束时会自动提交事务 --DBMS_RLS.ENABLE_POLICY(object_schema IN VARCHAR2 NULL,object_name in varchar2,policy_name in VARCHAR2,enable in BOOLEAN); --CREATE_POLICY_GROUP:用于建立安全策略组 --语法:DBMS_RLS.CREATE_POLICY_GROUP(object_schema varchar2,object_name varchar2,policy_group varchar2); --如上所示:policy_group用于指定安全策略组的名称 --ADD_GROUPED_POLICY:用于增加与特定策略组相关的安全策略 --DBMS_RLS.ADD_GROUPED_POLICY(object_schema VARCHAR2,object_name varchar2,policy_group varchar2,policy_name varchar2,function_schema varchar2,policy_function varchar2,statement_types varchar2,update_check boolean,enabled boolean,static_policy boolean false); --ADD_POLICY_CONTEXT:用于为应用增加上下文 --语法:DBMS_RLS.ADD_POLICY_CONTEXT(object_schema VARCHAR2,object_name varchar2,namespace varchar2,attribute varchar2); --如上所示,namespace用于指定命名空间,attribute用于指定上下文属性 --DELETE_POLICY_GROUP:用于删除安全策略组 --语法:DBMS_RLS.DELETE_POLICY_GROUP(object_schema varchar2,object_name varchar2,policy_group varchar2); --DROP_GROUPED_POLICY:用于删除特定策略组的安全策略 --语法:DBMS_RLS.DROP_GROUPED_POLICY(object_schema varchar2,object_name varchar2,policy_group varchar2,policy_name varchar2); --DROP_POLICY_CONTEXT:用于删除对象的上下文 --语法:DBMS_RLS.DROP_POLICY_CONTEXT(object_schema varchar2,object_name varchar2,namespace varchar2,attribute varchar2); --ENABLE_GROUPED_POLICY:用于激活或禁止特定策略组的安全策略 --语法:DBMS_RLS.ENABLE_GROUPED_POLICY(object_schema varchar2,object_name varchar2,group_name varchar2,policy_name varchar2,enable boolean); --REFRESH_GROUPED_POLICY:用于刷新与特定安全策略组的安全策略相关的SQL语句(重新解析SQL语句) --语法:DBMS_RLS.REFRESH_GROUPED_POLICY(object_schema varchar2,object_name varchar2,group_name varchar2,policy_name varchar2); --使用DBMS_RLS实现精细访问控制 --假定应用开发人员希望SYS,SYSTEM,SCOTT用户可以访问EMP表的所有雇员,HAIYA用户只能访问部门1的雇员,而其他用户只能访问部门2的雇员 --下面以实现该眩目标为例,说明使用精细访问控制的方法 --a.建立应用上下文 --为了实现精细访问控制,必须要建立应用上下文,一般情况下建立应用上下文是由DBA来完成的,如果要以其他用户身份建立应用上下文,则要求该用户必须具有CREATE ANY CONTEXT系统权限 conn system/oracle create or replace context empenv using haiya.ctx; --b.建立包过程设置应用上下文属性 --如果会话用户为HAIYA,则设置属性DEPTNO为1,而如果是其他会话用户,则设置属性DEPTNO为2 CREATE or replace package haiya.ctx as procedure set_deptno; end; create or replace package body haiya.ctx as procedure set_deptno is id number; begin if sys_context('userenv','session_user')='HAIYA' then dbms_session.set_context('empenv','deptno',1); else dbms_session.set_context('empenv','deptno',2); end if; end; end; --c.建立登录触发器 --用户登录到数据库之后,会自动触发登录触发器,建立登录触发器的目的是要隐含调用过程ctx.set_deptno,从而设置上下文属性 --注意,必须要以SYS用户身份建立登录触发器 conn sys/oracle as sysdba; create or replace trigger login_trig after logon on database call haiya.ctx.set_deptno --如上所示,当用户登录到数据库时,会隐含调用过程HAIYA.CTX.SET_DEPTNO,并设置应用上下文EMPENV的属性DEPTNO --d.建立策略函数 --在增加策略之前,必须首先建立策略函数,并且策略函数必须带有两个参数,第一个参数对应于方案名,而第二个参数则对应于表名、视图或同义词名 create or replace package haiya.emp_security as function emp_sec(p1 varchar2,p2 varchar2) return varchar2; end; create or replace package body haiya.emp_security as function emp_sec(p1 varchar2,p2 varchar2) return varchar2 is d_predicate varchar2(2000); begin if user not in('SYS','SYSTEM','SCOTT') then d_predicate:='deptno=SYS_CONTEXT(''empenv'',''deptno'')'; return d_predicate; end if; return '1=1'; end; end; --如上所示,当以用户HAIYA登录时,谓词为"deptnoo=1",当以SYS,SYSTEM,SCOTT用户登录时,谓词为"1=1",而当以其他用户身份登录时,谓词为"deptnoo=2" --e.增加策略 --在建立了策略函数之后,就可以增加策略,并定义对象、策略、策略函数以及SQL语句之前的对应关系。 --增加策略是使用包DBMS_RLS来完成的 begin dbms_rls.add_policy('HAIYA','emp','emp_policy','HAIYA','emp_security.emp_sec','select'); end; --当执行了过程ADD_POLICY之后,会在系统默认的策略组SYS_DEFAULT中增加策略emp_policy,并且在表HAIYA.EMP上的SELECT语句会使用该策略 --其中,第一个参数为对象所在方案名,第二个参数为对象名,第三个参数为策略名,第四个参数为策略函数所在方案名,第五个参数为策略函数,第六个参数为使用该策略的SQL语句(如果不指定,则SELECT,INSERT,UPDATE和DELETE语句都会使用该策略) --当完成了以上步骤之后,就实现了精细访问控制 --当以SYS,SYSTEM,SCOTT登录,当查询HAIYA.EMP表时,因为谓词为"1=1",所以会将示例查询语句转变为"select * from haiya.emp where 1=1",也即会返回EMP表的所有数据 --当以HAIYA登录,当查询HAIYA.EMP表时,因为谓词为"deptno=1",所以会将示例查询语句转变为"select * from haiya.emp where deptno=1",也即只会显示部门1的雇员信息 select * from haiya.emp; --删除定义在HAIYA.EMP上的安全策略,当执行该操作结束时会自动提交事务 begin dbms_rls.drop_policy('HAIYA','emp','emp_policy'); end; --9.DBMS_DDL --该包提供了在PL/SQL块中执行DDL语句的方法,并且该包也提供了一些DDL的特殊管理方法 --ALTER_COMPILE:用于重新编译过程、函数和包 --语法:DBMS_DDL.ALTER_COMPILE(type varchar2,schema varchar2,name varchar2); --如上所示,type用于指定对象类型(PROCEDURE,FUNCTION,PACKAGE,TRIGGER),schema用于指定对象所在方案,name用于指定对象名 begin dbms_ddl.alter_compile('PROCEDURE',null,'ADD_EMPLOYEE'); end; --ANALYZE_OBJECT:用于分析表、索引和簇并生成统计数据 --语法:DBMS_DDL.ANALYZE_OBJECT(type VARCHAR2,schema VARCHAR2,name VARCHAR2,method VARCHAR2,estimate_rows NUMBER DEFAULT NULL,estimate_percent NUMBER default null,method_opt varchar2 default null,partname varchar2 default null); --如上所示,type用于指定对象类型(TABLE,INDEX或CLUSTER),method用于指定分析方法(COMPUTE、ESTIMATE、DELETE),estimate_rows用于指定要估计的行数, --estimate_percent用于指定要估计的百分比,method_opt用于指定分析方法选项(FOR TABLE、FOR ALL COLUMNS等),partname用于指定要分析的分区 begin dbms_ddl.analyze_object('TABLE',null,'EMP','COMPUTE'); end; --IS_TRIGGER_FIRE_ONCE:用于检测特定的DML或DDL触发器是否只触发一次 --语法:DBMS_DDL.IS_TRIGGER_FIRE_ONCE(trig_owner in varchar2,trig_name in varchar2) RETURN BOOLEAN; --如上所示,trig_owner用于指定触发器所有者,trig_name用于指定触发器名,如果函数返回TRUE,则表示触发器只被触发一次 --SET_TRIGGER_FIRING_PROPERTY:用于设置DML或DDL触发器的触发属性 --语法:dbms_ddl.set_trigger_firing_property(trig_owner in varchar2,trig_name in varchar2,fire_once in boolean); --如上所示,fire_once用于指定触发器属性,当设置为TRUE时只触发一次,当设置为FALSE时总是被触发 --10.DBMS_SHARED_POOL --该包提供了对共享池的一些过程和函数访问,它使用户可以显示共享池中的对象尺寸、绑定对象到共享池、清除绑定到共享池的对象 --为了使用该包,必须运行dbmspool.sql脚本来建立该包,下面介绍该包所包含的过程和函数 --SIZES:用于显示在共享池中大于指定尺寸的对象 --语法:DBMS_SHARED_POOL.SIZES(minsize NUMBER); --如上所示,minsize用于指定要显示对象的最小尺寸(单位:KB) set serveroutput on exec dbms_shared_pool.sizes(100); --KEEP:用于将特定对象绑定到共享他中 --语法:DBMS_SHARED_POOL.KEEP(name varchar2,flag char default 'P'); --如上所示,name用于指定要绑定的对象名,flag用于指定对象类型(P:过程、函数和包,T:对象类型,R:触发器,Q:序列) exec dbms_shared_pool.keep('standard'); --UNKEEP:用于清除被绑定到共享池中的对象 --语法:DBMS_SHARED_POOL.UNKEEP(name varchar2,flag char default 'P'); exec dbms_shared_pool.unkeep('standard'); --ABORTED_REQUEST_THRESHOLD:用于设置共享池终止请求的阈值 --语法:DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD(threshold_size NUMBER); --如上所示,threshold_size用于指定共享池阈值尺寸(5000-2O字节) exec dbms_shared_pool.aborted_request_threshold(10000); --11.DBMS_RANDOM --提供了内置的随机数生成器,可以用于快速生成随机数 --INITIALIZE:用于初始化DBMS_RANDOM包,在初始化DBMS_RANDOM包时,必须要提供随机数种子 --语法:DBMS_RANDOM.INITIALIZE(seed in binary_integer); --SEED:用于复位随机数种子 --语法:DBMS_RANDOM.SEEP(seed in binary_integer); --RANDOM:用于生成随机数 --语法:DBMS_RANDOM.RANDOM RETURN BINARY_INTEGER; --TERMINATE:用于关闭DBMS_RANDOM包 --语法:DBMS_RANDOM.TERMINATE; --随机数使用示例 --下面以生成10000以内的10个随机数为例 DECLARE num int; seed number:=10000000; begin dbms_random.initialize(seed); for i in 1..10 loop num:=abs(dbms_random.random()/seed); dbms_output.put_line(num); end loop; dbms_random.terminate; end; --12.DBMS_LOGMNR --通过使用包DMBS_LOGMNR和DBMS_LOGMNR_D,可以分析重做日志和归档日志所记载的事务变化,最终确定误操作(例如DROP TABLE)的时间、跟踪用户事务操作,跟踪并还原表的DML操作 --DBMS_LOGMNR.ADD_LOGFILE:用于为日志分析列表增加或删除日志文件,或者建立日志分析列表 --语法:DBMS_LOGMNR.ADD_LOGFILE(LogFileName in varchar2,Options in binary_integer default addfile); --如上所示,logfilename用于指定要增加或删除的日志文件名称,options用于指定选项(其中,DBMS_LOGMNR.NEW:建立日志分析列表,DBMS_LOGMNR.ADDFILE:增加日志文件,DBMS_LOGMNR.REMOVEFILE:删除日志文件) --DBMS_LOGMNR.START_LOGMNR:用于启支LogMiner会话,语法如下 --DBMS_LOGMNR.START_LOGMNR(startScn IN NUMBER default 0,endScn IN NUMBER default 0,startTime IN DATE default '01-jan-1988',endTime IN DATE default '01-jan-2988', --DictFileName IN VARCHAR2 default '',Options IN BINARY_INTEGER default 0); --startscn用于指定日志分析起始SCN值,endscn用于指定日志分析的结束SCN值,starttime用于指定日志分析的起始时间,endtime用于指定日志分析的结束时间 --dictfilename用于指定日志分析要使用的字典文件名,options用于指定LogMiner分析选项 --DBMS_LOGMNR.END_LOGMNR:用于结束LogMiner会话 --语法:DBMS_LOGMNR.END_LOGMNR; --DBMS_LOGMNR.MINE_VALUE:用于返回要摘取的列信息,该函数在启动LogMiner之后调用 --语法:dbms_logmnr.mine_value(sql_redo_undo IN RAW,column_name IN VARCHAR2 default '') RETURN VARCHAR2; --sql_redo_undo用于指定要摘取的数据(REDO_VALUE或UNDO_VALUE); --column_name用于指定要摘取的列(格式:schema.table.column) --DBMS_LOGMNR.COLUMN_PRESENT:用于确定是否出现在数据的REDO部分或UNDO部分 --dbms_logmnr.column_present(sql_redo_undo IN RAW,column_name IN VARCHAR2 default '') RETURN NUMBER; --如果列在REDO或UNDO部分存在,则返回1,否则返回0 --DBMS_LOGMNR_D.BUILD:用于建立字典文件,语法如下 --dbms_logmnr_d.build(dictionary_filename in varchar2,dictionary_location in varchar2,options in number); --dictionary_filename用于指定字典文件名,dictionary_location用于指定文件所在位置,options用于指定字典要写入位置(STORE_IN_FLAT_FILE:文本文件,STORE_IN_REDO_LOGS:重做日志) --DBMS_LOGMNR_D.SET_TABLESPACE:用于改变LogMiner表所在表空间 --语法:DBMS_LOGMNR_D.SET_TABLESPACE(new_tablespace IN DEFAULT VARCHAR2,dict_tablespace IN DEFAULT varchar2,spill_tablespace in default varchar2); --如上所示:new_tablespace用于指定LogMiner表所在表空间,dict_tablespace用于指定字典所在表空间,spill_tablespace用于指定溢出表所在表空间 --LogMiner使用示例 --下面以分析TEMP表的DDL和DML操作为例,介绍使用LogMiner分析重做日志和归档日志的方法,在使用LogMiner之前,首先建立表TEMP,然后执行DML操作和日志切换操作,生成归档日志 CREATE TABLE temp(cola NUMBER,colb VARCHAR2(10)); ALTER SYSTEM SWITCH LOGFILE; INSERT INTO temp values(9,'A'); UPDATE temp set cola=10; commit; alter system switch LOGFILE; DELETE FROM HAIYA.TEMP; ALTER SYSTEM SWITCH logfile; select * from temp; delete temp; --1.建立字典文件 --字典文件用于存放表及对象ID号之间的对应关系,从ORACLE9i开始,字典信息既可被摘取到字典文件中,也可被摘取到重做日志中。 --摘取字典信息到字典文件的方法如下: --a.设置字典文件所在目录: alter system set utl_file_dir="D:\temp" scope=spfile; --b.重启ORACLE SERVER shutdown immeditate; startup; --c.摘取字典信息 BEGIN dbms_logmnr_d.build(dictionary_filename=>'dict.ora',dictionary_location=>'g:\test\logminer'); END; --2.建立日志分析列表 --a.停止ORACLE SERVER并装载数据库 shutdown immediate; startup mount; --b.建立日志分析列表 begin dbms_logmnr.add_logfile(options=>dbms_logmnr.NEW,logfilename=>'d:\temp\arc1\test11.arc'); end; --c.增加其他日志文件(可选) BEGIN DBMS_LOGMNR.add_logfile(options=>dbms_logmnr.ADDFILE,logfilename=>'d:\temp\arc1\test12.arc'); END; --3.启动LogMiner执行分析 BEGIN dbms_logmnr.start_logmnr(DirFileName=>'g:\test\logminer\dict.ora',STARTTIME=>TO_DATE('2004-04-03:10:10:00','YYYY-MM-DD:HH24:MI:SS'),ENDTIME=>TO_DATE('2004-04-03:15:30:00','YYYY-MM-DD:HH24:MI:SS')); END; --4.查看日志分析结果 --在启动LogMiner执行了日志分析之后,就可以查看日志分析结果了,但是要注意,日志分析结果只能在当前会话查看,而其他会话将不能查看到日志分析结果 --显示DML结果 select operation,sql_redo,sql_undo from v$logmnr_contents where seg_name='TMEP'; --显示DDL结果 select to_char(timestamp,'YYYY-MM-DD:HH24:MI:SS') time,sql_redo from v$logmnr_contents where sql_redo like '%create%' or sql_redo like '%CREATE%'; --显示在用字典文件 select db_name,filename from v$logmnr_dictionary; --5.结束LogMiner exec dbms_logmnr.end_logmnr; --13.DBMS_FLASHBACK --用于激活或禁止会话的FLASHBACK特征,为了使得普通用户可以使用该包,必须要将执行该包的权限授予这些用户 --以sys用户登录 GRANT EXECUTE ON dbms_flashback to haiya; --a.ENABLE_AT_TIME:用于以时间方式激活会话的FLASHBACK --语法:DBMS_FLASHBACK.ENABLE_AT_TIME(query_time IN TIMESTAMP); --如上所示,query_time用于指定FLASHBACK对应的时间点 --b.ENABLE_AT_SYSTEM_CHANGE_NUMBER:用于以系统改变号(SCN)方式激活会话的FLASHBACK --语法:DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(query_scn IN NUMBER); --如上所示,query_scn用于指定FLASHBACK对应的SCN值 --c.GET_SYSTEM_CHANGE_NUMBER:用于取得系统的当前SCN值 --语法:DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER RETURN NUMBER; --d.DISABLE:用于禁止会话的FLASHBACK模式 --语法:DBMS_FLASHBACK.DISABLE; --e.FLASHBACK使用示例 -- Create table create table EMP ( EMPNO NUMBER(10), ENAME NVARCHAR2(255), SAL NUMBER(10,2), HIREDATE TIMESTAMP(6), COMM NUMBER(10,2), JOB NVARCHAR2(255), DEPTNO NUMBER(10) ) tablespace EAS_D_HAIYA_STANDARD pctfree 10 pctused 40 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); select * from emp for update; --取得雇员Test的工资及系统的SCN值 select sal from emp where ename='Test'; select dbms_flashback.get_system_change_number() from dual; --更新Test工资,并休眠5分钟 update emp set sal=3000 where ename='Test'; --使用DBMS_FLASHBACK取得特定SCN时间点对应的数据 begin dbms_flashback.enable_at_system_change_number(636242); end; select sal from emp where ename='Test'; begin dbms_flashback.disable; end; select sal from emp where ename='Test'; --14.DBMS_OBFUSCATION_TOOLKIT --该包用于加密和解密应用数据,另外还可以生成密码校验和 --当使用该包加密数据时,要求被加密数据的长度必须为8字节的整数倍,当使用DES算法加密数据时,密钥长度不能低于8字节,当使用DES3算法加密数据时,密钥长度不能低于16字节。 --a.DESEncrypt:用于使用DES算法对输入数据进行加密,并生成加密格式的数据,当使用该过程加密数据时,密钥不能少于8个字符,并且输入数据必须是8字节的整数倍 DECLARE encrypted_string varchar2(100); BEGIN dbms_obfuscation_toolkit.DESEncrypt(input_string=>'bijian09',key_string=>'abcd1234',encrypted_string=>encrypted_string); dbms_output.put_line(encrypted_string); END; --b.DESDecrypt:用于对使用DES算法所生成的加密数据进行解密。当对数据进解密时,解密密钥必须要与加密密钥完全一致 DECLARE encrypted_string varchar2(100); decrypted_string varchar2(100); BEGIN dbms_obfuscation_toolkit.DESEncrypt(input_string=>'bijian09',key_string=>'abcd1234',encrypted_string=>encrypted_string); dbms_obfuscation_toolkit.DESDecrypt(input_string=>encrypted_string,key_string=>'abcd1234',decrypted_string=>decrypted_string); dbms_output.put_line(decrypted_string); END; --c.DES3Encrypt:用于使用DES3算法对输入数据进行加密,并生成加密格式的数据。 --当使用该过程加密数据时,密钥不能少于16个字符,并且输入数据必须是8字节的整数倍 DECLARE str1 varchar2(8):='中国你好'; key varchar2(16):='ABCDEFGHIJKLMN12'; str2 varchar2(100); BEGIN dbms_obfuscation_toolkit.DES3Encrypt(input_string=>str1,key_string=>key,encrypted_string=>str2); dbms_output.put_line(str2); END; --d.DES3Decrypt:用于对使用DES3算法所生成的加密数据进行解密 --在对数据进行解密时,解密密钥必须要与加密密钥完全一致 DECLARE str1 varchar2(8):='中国你好'; key varchar2(16):='ABCDEFGHIJKLMN12'; str2 varchar2(100); str3 varchar2(100); BEGIN dbms_obfuscation_toolkit.DES3Encrypt(input_string=>str1,key_string=>key,encrypted_string=>str2); dbms_obfuscation_toolkit.DES3Decrypt(input_string=>str2,key_string=>key,decrypted_string=>str3); dbms_output.put_line(str3); END; --MD5:用于使用MD5算法生成密码校验和,通过使用密码校验和,可以防止其他用户破坏被传输的加密数据 DECLARE str1 varchar2(8):='中国你好'; str2 varchar2(100); BEGIN dbms_obfuscation_toolkit.MD5(input_string=>str1,checksum_string=>str2); dbms_output.put_line(str2); END; --DBMS_OBFUSCATION_TOOLKIT使用示例 --下面以使用管道发送加密消息,并确保消息的正确性为例,说明包DBMS_OBFUSCATION_TOOLKIT的使用方法 --建立过程send_message --过程send_message将用于生成消息的密码校验和、加密消息,并且会将密码校验和发送到管道CHECKSUM,而将加密消息发送到管道ENCRYPT。 --注意,当使用该过程为管道发送消息时,消息长度必须为8字节的整数倍 CREATE OR REPLACE PROCEDURE send_message(message VARCHAR2) IS flag int; checksum varchar2(100); key VARCHAR2(100):='12345678BJ'; encry_str varchar2(100); BEGIN /*使用MD5算法为消息生成密码校验和*/ dbms_obfuscation_toolkit.MD5(input_string=>message,checksum_string=>checksum); /*建立管道checksum,并将密码校验和发送到该管道*/ flag:=dbms_pipe.create_pipe('checksum'); if flag=0 then dbms_pipe.pack_message(checksum); flag:=dbms_pipe.send_message('checksum'); end if; /*加密要发送的消息*/ dbms_obfuscation_toolkit.DESEncrypt(input_string=>message,key_string=>key,encrypted_string=>encry_str); /*建立管道encrypt,并将加密消息发送到该管道*/ flag:=dbms_pipe.create_pipe('encrypt'); if flag=0 then dbms_pipe.pack_message(encry_str); flag:=dbms_pipe.send_message('encrypt'); end if; END; --建立过程receive_message --用于接收管道checksum的密码校验和、管道encrypt的加密消息,然后对加密消息进行解密,并且生成解密消息的密码校验和,然后比较两种密码校验和 --以确定消息是否被窜改。如果消息没有被窜改,则输出消息,如果消息被窜改,则显示“消息被窜改” CREATE OR REPLACE PROCEDURE receive_message is flag int; source_checksum varchar2(100); dest_checksum varchar2(100); key varchar2(100):='12345678BJ'; encry_str varchar2(100); decry_str varchar2(100); begin /*从管道encrypt中接收加密消息*/ flag:=dbms_pipe.receive_message('encrypt'); if flag=0 then dbms_pipe.unpack_message(encry_str); flag:=dbms_pipe.remove_pipe('encrypt'); end if; /*从管道checksum中接收密码校验和*/ flag:=dbms_pipe.receive_message('checksum'); if flag=0 then dbms_pipe.unpack_message(source_checksum); flag:=dbms_pipe.remove_pipe('checksum'); end if; /*使用密钥解密消息,并生成密码校验和*/ dbms_obfuscation_toolkit.DESDecrypt(input_string=>encry_str,key_string=>key,decrypted_string=>decry_str); dbms_obfuscation_toolkit.MD5(input_string=>decry_str,checksum_string=>dest_checksum); /*比较密码校验和,如果相同,则显示消息,否则显示消息被窜改*/ if trim(source_checksum)=trim(dest_checksum) then dbms_output.put_line(decry_str); else dbms_output.put_line('消息被窜改'); end if; end; --使用过程send_message --会话一:exec send_message('中国你好1234'); --注意:当数据库字符集是UTF8时,一个汉字的长度是1 --会话二: set serveroutput on exec haiya.receive_message; --15.DBMS_SPACE --用于分析段增长和空间的需求 --UNUSED_SPACE:用于返回对象(表、索引、簇)的未用空间 --语法: --DBMS_SPACE.UNUSED_SPACE(segment_owner IN VARCHAR2,segment_name IN VARCHAR2,segment_type in varchar2,total_blocks OUT NUMBER, --total_bytes OUT NUBMER,unused_blocks OUT NUMBER,unused_bytes OUT NUMBER,last_used_extent_file_id OUT NUMBER, --last_used_extent_block_id out number,last_used_block out number,partition_name in varchar2 default null); --如上所示,segment_owner用于指定段所有者,segment_name用于指定段名,segment_type用于指定段类型,total_blocks用于返回段的总计块个数 --total_bytes用于返回段的总计字节数,unused_blocks用于返回段的未用块个数,unused_bytes用于返回段的未用字节数 --last_used_extent_file_id用于返回包含数据的最后一个区所在文件的编号,last_used_block用于返回包含数据的最后一个区的块编号 --last_used_block用于返回包含数据的最后一个区的最后一个块,partition_name用于指定要分析的段分区名 DECLARE total_blocks number; total_bytes number; unused_blocks number; unused_bytes number; last_used_extent_file_id number; last_used_extent_block_id number; last_used_block number; begin dbms_space.unused_space('HAIYA','EMP','TABLE',total_blocks,total_bytes,unused_blocks,unused_bytes,last_used_extent_file_id,last_used_extent_block_id,last_used_block); dbms_output.put_line('HWM='||to_char(total_blocks-unused_blocks-1)); end; --FREE_BLOCKS:用于返回对象(表、索引、簇)的空闲块信息 --语法: --DBMS_SPACE.FREE_BLOCKS(segment_owner in varchar2,segment_name in varchar2,segment_type in varchar2,freelist_group_id in number, --free_blks OUT NUMBER,scan_limit IN NUMBER default null,partition_name in varchar2 default null); --如上所示,freelist_group_id用于指定段的空闲列表组号,free_blks用于返回空闲列表组所对应的空闲列表个数,scan_limit用于指定要读取的空闲列表块的最大个数 DECLARE free_blocks NUMBER; BEGIN DBMS_SPACE.free_blocks('HAIYA','EMP','TABLE',1,free_blocks); dbms_output.put_line('组0的空闲列表个数:'||free_blocks); END; --SPACE_USAGE:用于显示段HWM(High Water Mark)以下数据块的空间使用情况,并且该过程只适用于自动段空间管理的表空间 --语法: --DBMS_SPACE.SPACE_USAGE(segment_owner in varchar2,segment_name in varchar2,segment_type in varchar2,unformatted_blocks out number, --unformatted_bytes out number,fs1_blocks out number,fs1_bytes out number, --fs2_blocks out number,fs2_bytes out number, --fs3_blocks out number,fs3_bytes out number, --fs4_blocks out number,fs4_bytes out number, --full_blocks out number,full_bytes out number, --partition_name in varchar2 default null); --如上所示,unformatted_blocks用于返回未格式化块的个数,unformatted_bytes用于返回未格式化的字节数, --fs1_blocks用于返回空闲空间在0-25%之间的块个数,fs1_bytes用于返回空闲空间在0-25%之间的字节数 --fs2_blocks用于返回空闲空间在25-50%之间的块个数,fs2_bytes用于返回空闲空间在25-50%之间的字节数 --fs3_blocks用于返回空闲空间在50-75%之间的块个数,fs3_bytes用于返回空闲空间在50-75%之间的字节数 --fs4_blocks用于返回空闲空间在75-100%之间的块个数,fs4_bytes用于返回空闲空间在75-100%之间的字节数 --full_blocks用于返回段的总计块个数,full_bytes用于返回段的总计字节数 DECLARE unf NUMBER; unfb number; fs1 number; fs1b number; fs2 number; fs2b number; fs3 number; fs3b number; fs4 number; fs4b number; fulla number; fullb number; BEGIN dbms_space.space_usage('HAIYA','EMP','TABLE',unf,unfb,fs1,fs1b,fs2,fs2b,fs3,fs3b,fs4,fs4b,fulla,fullb); dbms_output.put_line('unf:' || unf); dbms_output.put_line('unfb:' || unfb); dbms_output.put_line('fs1:' || fs1); dbms_output.put_line('fs1b:' || fs1b); dbms_output.put_line('fs2:' || fs2); dbms_output.put_line('fs2b:' || fs2b); dbms_output.put_line('fs3:' || fs3); dbms_output.put_line('fs3b:' || fs3b); dbms_output.put_line('fs4:' || fs4); dbms_output.put_line('fs4b:' || fs4b); dbms_output.put_line('fulla:' || fulla); dbms_output.put_line('fullb:' || fullb); END; --16.DBMS_SPACE_ADMIN --包DBMS_SPACE_ADMIN提供了局部管理表空间的功能 --SEGMENT_VERIFY:用于检查段的区映像是否与位图一致 --语法:DBMS_SPACE_ADMIN.SEGMENT_VERIFY(tablespace_name in varchar2,header_relative file in positive,header_block in positive,verify_option in positive default segment_verify_extents); --如上所示,tablespace_name用于指定段所在表空间,header_relative_file用于指定段头所在的相对文件号,headr_block用于指定段头所在的块号,verfify_option用于指定检查方式 exec dbms_space_admin.segment_verify('USRES3',9,68) --SEGMENT_CORRUPT:用于将段标记为损坏或有效 --语法: --DBMS_SPACE_AMDIN.SEGMENT_CORRUPT(tablespace_name in varchar2,header_relative_file in POSITIVE,header_block in POSITIVE, --corrupt_option IN POSITIVE DEFAULT SEGMENT_MARK_CORRUPT); --如上所示,corrupt_option用于指定损坏(SEGMENT_MARK_CORRUPT)或有效(SEGMENT_MARK_VALID)选项 exec dbms_space_admin.segment_corrupt('USER3',9,68) --SEGMENT_DROP_CORRUPT:用于删除被标记为损坏的段 exec dbms_space_admin.segment_drop_corrupt('USERS3',9,68) --SEGMENT_DUMP:用于转储特定段的头块和区映像块 --语法:DBMS_SPACE_ADMIN.SEGMENT_DUMP(tablespace_name in varchar2,header_relative_file in positive,header_block in positive,header_block in positive,dump_option in positive default segment_dump_extend_map); --如上所示,dump_option用于指定转储选项 exec dbms_space_admin.segment_dump('USERS3',9,68) --TABLESPACE_VERIFY:用于检查表空间所有段的位图和区映像 exec dbms_space_admin.tablespace_verify('USERS3') --TABLESPACE_FIX_BITMAPS:用于将特定范围的空间标记为空闲或已用 --语法: --DBMS_SPACE_AMDIN.TABLESPACE_FIX_BITMAPS(tablespace_name in varchar2,dbarange_relative_file in POSITIVE,dbarange_begin_block IN POSITIVE, --dbarange_end_block IN POSITIVE,fix_option IN POSITIVE); --如上所示,dbarange_relative_file用于指定DBA范围内的相对文件号,dbarange_begin_block用于指定数据文件区的起始块编号,dbarange_end_block用于指定数据文件区的结束块编号 --fix_option用于指定选项(TABLESPACE_EXTENT_MAKE_FREE或TABLESPACE_EXTENT_MAKE_USED) exec dbms_space_amdin.tablespace_fix_bitmaps('USERS',4,33,83,7) --TABLESPACE_REBUILD_BITMAPS:用于重新建立合适的位图,如果没有指定位图块,则将重建特定表空间的所有位图块 --语法: --DBMS_SPACE_ADMIN.TABLESPACE_REBUILD_BITMAPS(tablespace_name in varchar2,bitmap_relative_file in POSITIVE DEFAULT NULL,bitmap_block IN POSITIVE DEFAULT NULL); --如上所示,bitmap_relative_file用于指定位图块的相对文件号,bitmap_block用于指定位图块的块号 exec dbms_space_admin.tablespace_rebuild_bitmaps('USERS3') --TABLESPACE_REBUILD_QUOTAS:用于重建表空间配额 --语法:DBMS_SPACE_ADMIN.TABLESPACE_REBUILD_QUOTAS(tablespace_name in varchar2); --示例如下 exec dbms_space_admin.tablespace_rebuild_quotas('USERS3') --TABLESPACE_MIGRATE_FROM_LOCAL:用于将局部管理表空间转变为字典管理表空间 --语法: --DBMS_SPACE_AMDIN.TABLESPACE_MIGRATE_FROM_LOCAL(tablespace_name in VARCHAR2); exec dbms_space_admin.tablespace_migrate_from_local('USERS1') --TABLESPACE_MIORATE_TO_LOCAL:用于将字典管理表空间转变为局部管理表空间 exec dbms_space_admin.tablespace_migrate_to_local('USERS1') --TABLESPACE_RELOCATE_BITMAPS:用于移动位图到指定位置 --语法 --DBMS_SPACE_AMDIN.TABLESPACE_RELOCATE_BITMAPS(tablespace_name in varchar2,relative_fno in binary_integer,block_number in binary_integer) --如上所示,relative_fno用于指定相对文件号,block_number用于指定数据块编号 exec DBMS_SPACE_ADMIN.TABLESPACE_RELOCATE_BITMAPS('USERS3',9,8) --TABLESPACE_FIX_SEGMENT_STATES:用于修正表空间的段状态,当升级表空间时,如果出现例程终止,那么为了重新升级表空间,必须要修正该表空间中相应段的状态 --语法: --DBMS_SPACE_ADMIN.TABLESPACE_FIX_SEGMENT_STATES(tablespace_name); exec dbms_space_admin.tablespace_fix_segment_states('USERS3') --17.DBMS_TTS --用于检查表空间集合是否是自包含的,并在执行了检查之后,将违反自包含规则的信息写入到临时表TRANSPORT_SET_VIOLATIONS中 --TRANSPORT_SET_CHECK:用于检查表空间集合是否是自包含的 --语法:DBMS_TTS.TRANSPORT_SET_CHECK(ts_list in varchar2,incl_constraints in boolean default,full_closure in boolean default false); --如上所示,ts_list用于指定表空间列表,如果要指定多个表空间,则表空间之间使用逗号隔开,incl_constraints用于指定是否要检查完整性约束,full_closure用于指定是否要进行完全或部分相关检查 --示例 exec sys.dbms_tts.transport_set_check('users1,users2') select * from sys.transport_set_violations; --如上所示,在查询临时表transport_set_violations时,如果有返回信息,则会显示违反自包含表空间规则的原因,如果没有返回行,则表示表空间是自包含的 --DOWNGRADE:用于降低搬移表空间的相关数据 --语法:DBMS_TTS.DOWNGRADE; --18.DBMS_REPAIR --包DBMS_REPAIR用于检测、修复在表和索引上的损坏数据块 --ADMIN_TABLES:提供了管理修复表和孤表的功能 --语法: --DBMS_REPAIR.ADMIN_TABLES(table_name in varchar2,table_type in binary_integer,action in binary_integer,tablespace in varchar2 default null); --如上所示,table_name用于指定要处理的表名,必须要指定前缀ORPHAN或REPAIR,table_type用于指定表类型(PRPHAN_TABLE或REPAIR_TABLE) --action用于指定要执行的管理操作(CREATE_ACTION:建立表;PURGE_ACTION:删除所有行;DROP_ACTION:删除表),tablespace用于指定表所在表空间 begin dbms_repair.admin_tables('REPAIR_TABLE',DBMS_REPAIR.REPAIR_TABLE,DBMS_REPAIR.CREATE_ACTION,'SYSTEM'); end; begin dbms_repair.admin_tables('ORPHAN_TABLE',DBMS_REPAIR.ORPHAN_TABLE,DBMS_REPAIR.CREATE_ACTION,'SYSTEM'); end; --CHECK_OBJECT:用于检查特定对象,并将损坏信息填写到修复表中 --语法:DBMS_REPAIR.CHECK_OBJECT(schema_name IN VARCHAR2,object_name in varchar2,partition_name in varchar2 default null, --object_type in binary_integer default table_object,repair_table_name in varchar2 default 'REPAIR_TABLE', --flags IN BINARY_INTEGER default null,relative_fno in binary_integer default null,block_start in binary_integer default null, --block_end in binary_integer default null,corrupt_count out binary_integer); --如上所示,schema_name用于指定要检查对象的方案名,object_name用于指定要检查的对象名,partition_name用于指定要检查的分区名,object_type用于指定要检查对象的类型(TABLE_OBJECT或INDEX_OBJECT) --repair_table_name用于指定要被填写的修复表名,flags为将来使用而保留,relative_fno用于指定相对文件号,block_start用于指定要检查的起始块号 --block_end用于指定要检查的结束块号,corrupt_count用于返回捐坏的块个数 --PLUSQL中示例 var corr_count number exec dbms_repair.check_object('HAIYA','EMP',corrupt_count=>:corr_count) print corr_count --DUMP_ORPHAN_KEYS:用于报告指向损坏数据块行的索引入口,并且会将相应索引入口的信息插入到孤表中 --语法:DBMS_REPAIR.DUMP_ORPHAN_KEYS(schema_name IN VARCHAR2,object_name in varchar2,partition_name in varchar2 default null, --object_type in binary_integer default index_object,repair_table_name in varchar2 default 'REPAIR_TABLE', --orphan_table_name IN VARCHAR2 DEFAULT 'ORPHAN_KEYS_TABLE',flags in binary_integer default null,key_count out binary_integer); --如上所示,object_type用于指定对象类型(INDEX_OBJECT),repair_table_name用于指定修复表名,orphan_table_name用于指定孤表名,key_count用于返回索引入口个数 --示例: var key_count number exec dbms_repair.dump_orphan_keys('HAIYA','PK_EMP',orphan_table_name=>'ORPHAN_TABLE',key_count=>:key_count) print key_count --FIX_CORRUPT_BLOCKS:用于修复被损坏的数据块,这些被损坏的数据块是在执行了CHECK_OBJECT之后生成的 --语法: --DBMS_REPAIR.FIX_CORRUPT_BLOCKS(schema_name IN VARCHAR2,object_name in varchar2,partition_name in varchar2 default null, --object_type in binary_integer default TABLE_OBJECT,repair_table_name IN VARCHAR2 DEFAULT 'REPAIR_TABLE', --flags IN BINARY_INTEGER DEFAULT NULL,fix_count out binary_integer); --如上所示,object_type用于指定对象类型(TABLE_OBJECT),fix_count用于返回修复的数据块个数 --示例如下: var fix_count number exec dbms_repair.fix_corrupt_blocks('HAIYA','EMP',fix_count=>:fix_count) print fix_count --REBUILD_FREELISTS:用于重建指定对象的空闲列表 --语法: --DBMS_REPAIR.REBUILD_FREELISTS(schema_name in varchar2,object_name in varchar2,partition_name in varchar2 default null,object_type in binary_integer default table_object); --如上所示,object_type用于指定对象类型(TABLE_OBJECT) --示例如下: exec dbms_repair.rebuild_freelists('HAIYA','EMP'); --SKIP_CORRUPT_BLOCKS:用于指定在扫描对象(表或索引)时跳过损坏块 --语法: --DBMS_REPAIR.SKIP_CORRUPT_BLOCKS(schema_name in varchar2,object_name in varchar2,object_type in binary_integer default table_object, --flags in binary_integer default SKIP_FLAG); --如上所示,object_type用于指定对象类型(TABLE_OBJECT),flags用于指定是否要跳过损坏块(SKIP_FLAO:跳过损坏块,NO_SKIP_FLAG:不跳过损坏块) --示例如下: exec dbms_repair.skip_corrupt_blocks('HAIYA','EMP'); --SEGMENT_FIX_STATUS:用于修复位图入口的损坏 --语法: --DBMS_REPAIR.SEGMENT_FIX_STATUS(segment_owner in varchar2,segment_name IN VARCHAR2,segment_type in binary_integer default table_object, --file_number in binary_integer default null,block_number in binary_integer default null,status_value in binary_integer default null, --partition_name in varchar2 default null); --如上所示,segment_owner用于指定段所有者,segment_name用于指定段名,segment_type用于指定段类型,file_number用于指定数据块所在的相对文件号, --block_number用于指定数据块号,status_value用于指定块状态值(1:全块;2:0-25%;3:25%-50%,4:50%-75%;5:75%-100%) --partition_name用于指定分区名 exec dbms_repair.segment_fix_status('SYS','MYTAB'); --19.DBMS_RESOURCE_MANAGER --包DBMS_RESOURCE_MANAGER用于维护资源计划、资源使用组和资源计划指令 --包DBMS_RESOURCE_MANAGER_PRIVS用于维护资源管理相关的权限 --DBMS_RESOURCE_MANAGER.CREATE_PLAN:用于建立资源计划 --语法: --DBMS_RESOURCE_MANAGER.CREATE_PLAN(plan IN VARCHAR2,comment IN VARCHAR2,cpu_mth IN VARCHAR2 DEFAULT 'EMPHASIS', --active_sess_pool_mth IN VARCHAR2 DEFAULT 'ACTIVE_SESS_POOL_ABSOLUTE', --parallel_degree_limit_mth IN VARCHAR2 DEFAULT 'PARALLEL_DEGREE_LIMIT_ABSOLUTE', --queueing_mth IN VARCHAR2 DEFAULT 'FIFO_TIMEOUT'); --如上所示,plan用于指定资源计划名,comment用于指定用户注释信息,cpu_mth用于指定CPU资源的分配方法 --active_sess_pool_mth用于指定最大活动会话的分配方法 --parallel_degree_limit_mth用于指定并行度的分配方法 --queueing_mth用于指定活动会话池的队队策略类型 --DBMS_RESOURCE_MANAGER.CREATE_SIMPLE_PLAN:用于建立简单资源计划,该资源计划最多包含8个资源使用组 --DBMS_RESOURCE_MANAGER.CREATE_SIMPLE_PLAN( --SIMPLE_PLAN in varchar2 default, --consumer_group1 in varchar2 default, --group1_cpu in number default, --consumer_group2 in varchar2 default, --group2_cpu in number default, --consumer_group3 in varchar2 default, --group3_cpu in number default, --consumer_group4 in varchar2 default, --group4_cpu in number default, --consumer_group5 in varchar2 default, --group5_cpu in number default, --consumer_group6 in varchar2 default, --group6_cpu in number default, --consumer_group7 in varchar2 default, --group7_cpu in number default, --consumer_group8 in varchar2 default, --group8_cpu in number default); --DBMS_RESOURCE_MANAGER.UPDATE_PLAN:用于更新资源计划的定义 --DBMS_RESOURCE_MANAGER.DELETE_PLAN:用于删除资源计划 --语法:DBMS_RESOURCE_MANAGER.DELETE_PLAN(plan in varchar2); --DBMS_RESOURCE_MANAGER.DELETE_PLAN_CASCADE:用于删除资源计划及其所有后代(资源计划指令、子计划和资源使用组) --语法:DBMS_RESOURCE_MANAGER.DELETE_PLAN_CASCADE(plan IN VARCHAR2); --DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP:用于建立资源使用组 --语法:DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP(consumer_group in varchar2,comment in varchar2,cpu_mth in varchar2 default 'ROUND-ROBIN'); --如上所示,consumer_group用于指定资源使用组名 --DBMS_RESOURCE_MANAGER.UPDATE_CONSUMER_GROUP:用于更新资源使用组信息 --DBMS_RESOURCE_MANAGER.DELETE_CONSUMER_GROUP:用于删除资源使用组 --DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE:用于建立资源计划指令 --DBMS_RESOURCE_MANAGER.UPDATE_PLAN_DIRECTIVE:用于更新资源计划指令 --DBMS_RESOURCE_MANAGER.DELETE_PLAN_DIRECTIVE:用于删除资源计划指令 --DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA:用于建立pending内存区,并且该内存区将用于改变资源管理对象 --DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA:用于校验资源管理器的改变 --DBMS_RESOURCE_MANAGER.CLEAR_PENDING_AREA:用于清除资源管理器的改变 --DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA:用于提交资源管理器的改变 --DBMS_RESOURCE_MANAGER.SET_INITIAL_CONSUMER_GROUP:用于指定用户的初始资源使用组 --DBMS_RESOURCE_MANAGER.SWITCH_CONSUMER_GROUP_FOR_SESS:用于改变特定会话的资源使用组 --DBMS_RESOURCE_MANAGER.SWITCH_CONSUMER_GROUP_FOR_USER:用于改变特定用户所有会话的资源使用组 --DBMS_RESOURCE_MANAGER_PROIVS.GRANT_SYSTEM_PRIVILEGE:用于将资源管理权限授予用户或角色 --语法 --DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SYSTEM_PRIVILEGE(grantee_name in varchar2,privilege in varchar2 default 'ADMINISTER_RESOURCE_MANAGER',admin_option in boolean); --如上所示,grantee_name用于指定被授权的用户或角色,privilege_name用于指定要授予的资源管理权限,admin_option用于指定是否可以转授资源管理权限(TRUE:转授权限,FALSE:不能转授权限) conn system/bijian begin dbms_resource_manager_privs.grant_system_privilege('HAIYA','ADMINISTER_RESOURCE_MANAGER',true); end; --在执行了以上命令之后,就会将资源管理权限授予HAIYA用户,该用户可以将该权限再授予其他用户 --DBMS_RESOURCE_MANAGER_PRIVS.REVOKE_SYSTEM_PRIVILEGE:用于收回资源管理权限 conn system/bijian begin dbms_resource_manager_privs.revoke_system_privilege('HAIYA','ADMINISTER_RESOURCE_MANAGER'); end; --DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP:用于将用户或角色分配给特定的资源使用组 conn system/bijian begin dbms_resource_manager_privs.grant_switch_consumer_group('HAIYA','SYS_GROUP',TRUE); end; --在执行了以上命令之后,就会将HAIYA用户分配给资源使用组SYS_GROUP,并且该用户可以再将其他用户分配给该资源使用组 --DBMS_RESOURCE_MANAGER_PRIVS.REVOKE_SWITCH_CONSUMER_GROUP:用于收回分配给用户或角色的资源使用组 begin dbms_resource_manager_privs.revoke_switch_consumer_group('HAIYA','SYS_GROUP'); end; --在执行了以上命令之后,HAIYA用户使用资源使用组SYS_GROUP的权限被收回 --资源管理使用示例 --默认情况下,只有特权用户SYS,DBA用户SYSTEM可以进行资源管理,为了使其他用户也可以进行资源管理,必须授予他相应的资源管理权限 --在建立与资源管理相关的对象时,必须要在PENDING内存区中建立资源对象,并且需要校验资源对象的正确性,最终提交PENDING内存区 --a.为用户授予资源管理权限 conn system/bijian dbms_resource_manager_privs.grant_system_privilege('HAIYA','ADMINISTER_RESOURCE',FALSE); --b.建立各种资源对象 --当用户具有资源管理权限时,就可以建立资源使用组、资源计划和资源计划指令。但是在建立资源对象之前,必须首先分配PENDING内存区, --在建立资源对象完成之后,必须检查并提交PENDING内存区 --建立PENDING内存区:为了临时存放各种资源对象,必须首先建立PENDING内存区 --以HAIYA用户登录 BEGIN dbms_resource_manager.create_pending_area; END; --建立资源使用组:在定义资源使用组时,必须提供资源使用组名称和相应注释信息 --下面以建立资源使用组OLTP和DSS为例,说明建立资源使用组的方法 BEGIN dbms_resource_manager.create_consumer_group('OLTP','联机事务处理组'); END; begin dbms_resource_manager.create_consumer_group('DSS','决策支持组'); end; --建立资源计划:在建立资源计划时,必须提供资源计划名称和相应注释信息 --下面以建立资源计划DAY和NIGHT为例,说明建立资源计划的方法 begin dbms_resource_manager.create_plan('DAY','该资源计划用于联机事务处理'); end; begin dbms_resource_manager.create_plan('NIGHT','该资源计划用于决策支持'); end; --建立资源计划指令:通过建立资源计划指令,可以指定资源使用组和资源计划的关联关系 --注意,当建立资源计划指令时,必须要在资源计划和OTHER_GROUPS组之间定义关联关系 --下面以在资源使用组SYS_GROUP,OLTP,OTHER_GROUPS和资源计划DAY之间建立关联,在资源使用组SYS_GROUP,DSS,OTHER_GROUPS和资源计划NIGHT之间建立关联为例,说明建立资源计划指令的方法 BEGIN dbms_resource_manager.create_plan_directive(plan=>'DAY',group_or_subplan=>'SYS_GROUP',comment=>'最高级别组',cpu_p1=>100,parallel_degree_limit_p1 => 3); dbms_resource_manager.create_plan_directive(plan=>'DAY',group_or_subplan=>'OLTP',comment=>'中间级别组',cpu_p1=>80,parallel_degree_limit_p1 => 1); dbms_resource_manager.create_plan_directive(plan=>'DAY',group_or_subplan=>'OTHER_GROUPS',comment=>'最低级别组',cpu_p1=>80,parallel_degree_limit_p1 => 1); END; BEGIN dbms_resource_manager.create_plan_directive(plan=>'NIGHT',group_or_subplan=>'SYS_GROUP',comment=>'最高级别组',cpu_p1=>100,parallel_degree_limit_p1 => 20); dbms_resource_manager.create_plan_directive(plan=>'NIGHT',group_or_subplan=>'DSS',comment=>'中间级别组',cpu_p1=>80,parallel_degree_limit_p1 => 20); dbms_resource_manager.create_plan_directive(plan=>'NIGHT',group_or_subplan=>'OTHER_GROUPS',comment=>'最低级别组',cpu_p1=>80,parallel_degree_limit_p1 => 20); END; --验证PENDING内存区:在建立了各种相关的资源对象之后,必须首先验证PENDING内存区 --如果验证通过,那么可以提交PENDING内存区,并建立资源对象,如果验证未能通过,需要清除PENDING内存区,重新建立资源对象 BEGIN dbms_resource_manager.validate_pending_area; END; --提交PENDING内存区:在PENDING内存区验证成功之后,可以提交PENDING内存区,最终建立永久的资源管理对象 BEGIN dbms_resource_manager.submit_pending_area; END; --c.分配用户到资源使用组 begin dbms_resource_manager_privs.grant_switch_consumer_group('HAIYA','OLTP',false); end; begin dbms_resource_manager_privs.grant_switch_consumer_group('HAIYA','DSS',false); end; --d.设置用户的默认资源使用组 --数据库用户可以属于多个资源使用组,但在特定会话特定地刻只能使用某个资源使用组的相应资源。 --通过设置用户的默认资源使用组,可以使得在用户登录时自动使用相应资源使用组的资源 --下面将HAIYA用户的默认资源使用组设置为OLTP为例,说明设置用户默认资源使用组的方法 begin dbms_resource_manager.set_initial_consumer_group('HAIYA','OLTP'); end; --e.激活资源计划 --为了通过数据库资源管理器限制数据库用户的资源使用,必须要激活资源计划 --下面以在日间激活资源计划DAY为例,说明激活资源计划的方法 alter system set RESOURCE_MANAGER_PLAN=DAY SCOPE=MEMORY; --f.改变会话或用户的资源使用组 --如果数据库用户属于多个资源使用组,那么在初始登录时会使用默认资源使用组 --为了改变特定会话的资源使用组,可以执行以下语句 begin dbms_resource_manager.switch_consumer_group_for_sess('HAIYA','DSS'); end; --为了改变特定用户所有会话的资源使用组,可以执行以下语句 begin dbms_resource_manager.switch_consumer_group_for_user('HAIYA','DSS'); end; --20.DBMS_STATS --用于搜集、查看、修改数据库对象的优化统计信息 --GET_COLUMN_STATS:用于取得列的统计信息 --语法:DBMS_STATS.GET_COLUMN_STATS(ownname VARCHAR2,tabname VARCHAR2,colname VARCHAR2,partname varchar2 default null, --stattab VARCHAR2 DEFAULT NULL,statid varchar2 default null,distcnt out number,density out number,nullcnt out number,srec out StatRec, --avgclen out number,statown varchar2 default null); --如上所示,ownname用于指定方案名,tabname用于指定表名,colname用于指定列名,partname用于指定分区名,stattab用于指定用户统计表名 --stattid用于指定与统计相关的标识符,distcnt用于返回不同值的个数,ddensity用于返回列的密度,nullcnt用于返回列的NULL个数,srec用于返回列的最大、最小和直方图值,avgclen用于返回列的平均长度,statown用于指定包含STATTAB的方案名 DECLARE dist_count number; density number; null_count number; srec dbms_stats.StatRec; avg_col_len NUMBER; begin dbms_stats.get_column_stats('HAIYA','EMP','JOB',distcnt=>dist_count,density=>density,nullcnt=>null_count,srec=>srec,avgclen=>avg_col_len); dbms_output.put_line('不同列值个数:'||dist_count); dbms_output.put_line('列平均长度:'||avg_col_len); end; --GET_INDEX_STATS:用于取得索引的统计信息 --语法: --DBMS_STATS.GET_INDEX_STATS(ownname varchar2,indname varchar2,partname varchar2 default null,stattab varchar2 default null, --statid varchar2 default null,number,numlblks out number,numdist out number,avglblk out number,avgdblk out number, --clstfct out number,indlevel out number,statown varchar2 default null); --如上所示,ownname用于指定索引所有者名,indname用于指定索引名,partname用于指定索引分区名,stattab用于指定统计表名, --statab用于指定统计表名,statid用于指定统计表相关的标识符,numrows用于返回索引行数,numlblks用于返回索引块个数,numdist用于返回索引不同键值个数 --avglblk用于返回每个键值占用的平均叶块个数,avgdblk用于返回每个键值对应表行所占用的平均数据块个数 --clstfct用于返回索引的聚簇因子,indlevel用于返回索引层数,statown用于指定统计表所有者 CREATE INDEX PK_EMP ON EMP(EMPNO); SELECT * FROM EMP; DECLARE numrows NUMBER; numlblks number; numdist number; avglblk number; avgdblk number; clstfct number; indlevel number; BEGIN dbms_stats.get_index_stats('HAIYA','PK_EMP',numrows=>numrows,numlblks=>numlblks,numdist=>numdist,avglblk=>avglblk,avgdblk=>avgdblk,clstfct=>clstfct,indlevel=>indlevel); dbms_output.put_line('叶块个数:'||numlblks); dbms_output.put_line('索引层次:'||indlevel); END; --GET_SYSTEM_STATS:用于从统计表或数据字典中取得系统统计信息 --语法:DBMS_STATS.GET_SYSTEM_STATS(status OUT VARCHAR2,dstart OUT DATE,dstop OUT DATE,pname VARCHAR2,pvalue OUT NUMBER, --stattab IN VARCHAR2 DEFAULT NULL,statid IN VARCHAR2 DEFAULT NULL,statown IN VARCHAR2 DEFAULT NULL); --如上所示,status用于返回状态信息(COMPLETED,AUTOGATHERING,MANUALGATHERING),dstat用于返回起始搜集日期,dstop用于返回结束搜集日期 --pname用于指定要取得的参数名(sreadtim,mreadtim,cpuspeed,mbrc,maxthr,slavethr) --pvalue用于返回参数值 --GET_TABLE_STATS:用于取得表的统计信息 DECLARE numrows number; numblks number; avgrlen number; BEGIN dbms_stats.get_table_stats('HAIYA','EMP',numrows => numrows,numblks=>numblks,avgrlen => avgrlen); dbms_output.put_line('表的总计行数:'||numrows); dbms_output.put_line('表所占用的块个数:'||numblks); dbms_output.put_line('表行的平均长度:'||avgrlen); END; --DELETE_COLUMN_STATS:用于删除列的统计信息 --语法: --DBMS_STATS.DELETE_COLUMN_STATS(owner VARCHAR2,tabname VARCHAR2,colname VARCHAR2,partname VARCHAR2 DEFAULT NULL, --stattab varchar2 DEFAULT NULL,statid varchar2 DEFAULT NULL,cascade_parts boolean default true,statown varchar2 DEFAULT NULL,no_invalidate boolean DEFAULT FALSE); --如上所示,cascade_parts用于指定是否要级联删除分区统计,no_invalidate用于指定是否要使相关游标无效 begin dbms_stats.delete_column_stats('HAIYA','EMP','ENAME'); end; --DELETE_INDEX_STATS:用于删除索引统计信息 begin dbms_stats.delete_index_stats('HAIYA','PK_EMP'); end; --DELETE_SYSTEM_STATS:用于删除系统统计信息 --DELETE_TABLE_STATS:用于删除表的统计信息 BEGIN dbms_stats.delete_table_stats('HAIYA','EMP'); END; --DELETE_SCHEMA_STATS:用于删除特定方案的统计信息 BEGIN dbms_stats.delete_schema_stats('HAIYA'); END; --DELETE_DATABASE_STATS:用于删除整个数据库的统计信息 BEGIN dbms_stats.delete_database_stats; END; --CREATE_STAT_TABLE:用于在特定方案中建立统计表 BEGIN DBMS_STATS.create_stat_table('HAIYA','stattab'); END; --DROP_STAT_TABLE:用于删除特定方案的统计表 begin dbms_stats.drop_stat_table('HAIYA','stattab'); end; --EXPORT_COLUMN_STATS:用于导出列统计并存储到统计表中 begin dbms_stats.export_column_stats('HAIYA','EMP','ENAME',stattab=>'stattab'); end; --EXPORT_INDEX_STATS:用于导出索引统计信息,并存储到统计表中 BEGIN DBMS_STATS.export_index_stats('HAIYA','PK_EMP',stattab=>'stattab'); END; --EXPORT_SYSTEM_STATS:用于导出系统统计信息,并存储到统计表中 --EXPORT_TABLE_STATS:用于导出表的统计信息,并将其存储到统计表中 BEGIN dbms_stats.export_table_stats('HAIYA','EMP',stattab=>'stattab'); END; --EXPORT_SCHEMA_STATS:用于导出方案的统计信息,并将其存储到统计表中 BEGIN dbms_stats.export_schema_stats('HAIYA',stattab=>'stattab'); END; --EXPORT_DATABASE_STATS:用于导出数据库的所有统计信息,并存储到统计表中 BEGIN DBMS_STATS.export_database_stats(stattab=>'stattab',statown=>'HAIYA'); END; --IMPORT_COLUMN_STATS:用于从统计表中取得列统计,并将其存储到数据字典中 BEGIN dbms_stats.import_column_stats('HAIYA','EMP','ENAME',stattab=>'STATTAB',statown=>'HAIYA'); END; --IMPORT_INDEX_STATS:用于从统计表中取得索引统计,并将其存储到数据字典中 begin dbms_stats.import_index_stats('HAIYA','PK_EMP',stattab=>'STATTAB',statown => 'HAIYA'); end; --IMPORT_SYSTEM_STATS:用于从统计表中取得系统统计,并将其存储到数据字典中 --IMPORT_TABLE_STATS:用于从统计表中取得表统计,并将其存储到数据字典中 BEGIN DBMS_STATS.import_table_stats('HAIYA','EMP',stattab => 'STATTAB',statown => 'HAIYA'); END; --IMPORT_SCHEMA_STATS:用于从统计表中取得方案统计,并将其存储到数据字典中 BEGIN dbms_stats.import_schema_stats('HAIYA',stattab => 'STATTAB',statown=>'HAIYA'); END; --IMPORT_DATABASE_STATS:用于从统计表中取得数据库所有对象的统计,并将其存储到数据字典中 begin dbms_stats.import_database_stats(stattab=>'STATTAB',statown=>'HAIYA'); end; --GATHER_INDEX_STATS:用于搜集索引统计 begin DBMS_STATS.gather_index_stats('HAIYA','pk_emp'); end; --GATHER_TABLE_STATS:用于搜集表统计 BEGIN dbms_stats.gather_table_stats('HAIYA','EMP'); END; --GATHER_SCHEMA_STATS:用于搜集特定方案所有对象的统计 BEGIN dbms_stats.gather_schema_stats('HAIYA'); END; --GATHER_DATABASE_STATS:用于搜集数据库所有对象的统计 BEGIN dbms_stats.gather_database_stats; END; --OATHER_SYSTEM_STATS:用于搜集系统统计 --语法: --DBMS_STATS.GATHER_SYSTEM_STATS(gathering_mode VARCHAR2 default 'NOWORKLOAD',interval INTEGER DEFAULT NULL,stattab VARCHAR2 DEFAULT NULL, --statid VARCHAR2 DEFAULT NULL,statown varchar2 default null); --如上所示,gathering_mode用于指定搜集模式值(NOWORKLOAD,INTERVAL,START|STOP) --interval用于指定搜集统计的时间间隔(只适用于INTERVAL模式) BEGIN dbms_stats.gather_system_stats; END; select * from stattab; --21.UTL_FILE --用于读写OS文件,使用该包访问OS文件时,必须要为OS目录建立相应的DIRECTORY对象。 --当用哀恸要访问特定目录下的文件时,必须要具有读写DIRECTORY对象的权限。 --在使用UTL_FILE包之前,应首先建立DRIECTORY对象,并要为用户授权 --以system用户登录 GRANT READ,WRITE ON DIRECTORY user_dir to haiya; CREATE DIRECTORY user_dir as 'D:\TestDir'; grant create any directory to haiya; grant create any type to haiya; drop directory user_dir; --a.FILE_TYPE:该类型是UTL_FILE包中所定义的记录类型,其成员是私有的,不能被直接引用。 --该类型的定义如下 TYPE file_type is RECORD(id BINARY_INTEGER,datatype BINARY_INTEGER); --b.FOPEN:用于打开OS文件,注意,使用该函数最多可以同时打开50个文件 --注意,当指定文件位置时,必须要使用DIRECTORY对象,并且其名称必须大写 DECLARE handle UTL_FILE.file_type; BEGIN handle:=utl_file.fopen('USER_DIR','readme.txt','r',1000); dbms_output.put_line('打开文件成功'); END; --c.FOPEN_NCHAR:用于以UNICODE方式打开文件,当使用该函数打开文件之后,读写文件会使用UNICODE取代数据库字符集 --语法:UTL_FILE.FOPEN_NCHAR(location in varchar2,filename in varchar2,open_mode in varchar2,max_linesize in binary_integer) return file_type; --d.IS_OPEN:用于确定文件是否已经打开 DECLARE handle UTL_FILE.file_type; BEGIN IF NOT utl_file.is_open(handle) then handle:=utl_file.fopen('USER_DIR','&filename','r',1000); end if; dbms_output.put_line('打开文件成功'); END; --e.FCLOSE:用于关闭已经打开的文件 --语法:UTL_FILE.FCLOSE(file in out file_type); --f.FCLOSE_ALL:用于关闭当前会话打开的所有文件 --语法:UTL_FILE.FCLOSE_ALL; --g.GET_LINE:用于从已打开文件中读取行内容,行内容会被读取到输出缓冲区 DECLARE handle UTL_FILE.file_type; buffer varchar2(100); begin handle:=utl_file.fopen('USER_DIR','a.txt','r',1000); utl_file.get_line(handle,buffer,100); dbms_output.put_line(buffer); utl_file.fclose(handle); end; --h.GET_LINE_NCHAR:用于以UNICODE方式读取已打开文件的行内容,并且将行内容读取到输出缓冲区中 declare handle utl_file.file_type; buffer varchar2(1000); begin handle:=utl_file.fopen_nchar('USER_DIR','a.txt','r',1000); utl_file.get_line_nchar(handle,buffer); dbms_output.put_line(buffer); utl_file.fclose(handle); end; --GET_RAW:用于从文件中读取RAW字符串,并调节文件指针到读取位置 --读出的是UNICODE编码 DECLARE handle UTL_FILE.file_type; buffer RAW(100); BEGIN handle:=utl_file.fopen('USER_DIR','a.txt','r',1000); UTL_FILE.get_raw(handle,buffer,100); dbms_output.put_line(buffer); utl_file.fclose(handle); END; --PUT:用于将绊缓冲区内容写入到文件中,当使用PUT过程时,文件必须要以写方式打开 --在写入缓冲区之后,如果要结束行,那么可以使用NEW_LINE过程 DECLARE handle UTL_FILE.file_type; buffer varchar2(100); BEGIN handle:=utl_file.fopen('USER_DIR','b.txt','w',1000); buffer:='&content1'; utl_file.put(handle,buffer); utl_file.new_line(handle); buffer:='&content2'; utl_file.put_line(handle,buffer); utl_file.fclose(handle); END; --PUT_NCHAR:用于将缓冲区内容以UNICODE方式写入到文件 DECLARE handle UTL_FILE.file_type; buffer varchar2(100); BEGIN handle:=utl_file.fopen_nchar('USER_DIR','b.txt','w',1000); buffer:='&content1'; utl_file.put_nchar(handle,buffer); utl_file.new_line(handle); buffer:='&content2'; utl_file.put_line_nchar(handle,buffer); utl_file.fclose(handle); END; --PUT_RAW:用于将RAW缓冲区中的数据写入到OS文件 --语法: --UTL_FILE.PUT_RAW(fid in utl_file.file_type,r in raw,autoflush in boolean default false); --如上所示,fid用于指定文件句柄,r用于指定存放RAW数据的缓冲区,autoflush用于指定是否要自动刷新缓冲区数据 DECLARE handle UTL_FILE.file_type; buffer RAW(100); BEGIN handle:=utl_file.fopen('USER_DIR','b.txt','w',1000); buffer:='&content'; utl_file.put_raw(handle,buffer); utl_file.new_line(handle); utl_file.fclose(handle); END; --NEW_LINE:用于为文件增加行终止符 --语法:UTL_FILE.NEW_LINE(file IN FILE_TYPE,lines in NATURAL:=1) --如上所示,lines用于指定要增加的行终止符个数 --PUT_LINE:用于将文本缓冲区内容写入到文件中,当使用该过程为文件追加内容时,会自动在内容的尾部追加行终止符 --PUT_LINE_NCHAR:用于将文本缓冲区内容以UNICODE方式写入文件,当使用该过程为文件写入内容时,会自动在尾部追加行终止符 --PUTF:用于以特定格式将文本内容写入到OS文件,其中格式符%s表示字符串,格式符\n表示行终止符 --语法:UTL_FILE.PUTF(file in file_type,format in varchar2,[arg1 in varchar2 default null,...arg5 in varchar2 default null]); --如上所示,format用于指定格式符(最多5个%s),arg1,...,arg5用于指定对应于格式符的字符串 DECLARE handle UTL_FILE.file_type; BEGIN handle:=utl_file.fopen('USER_DIR','b.txt','w',1000); utl_file.putf(handle,'%s\n%s\n%s\n','&line1','&line2','&line3'); utl_file.fclose(handle); END; --PUTF_NCHAR:用于以特定格式将文本内容以UNICODE方式写入到OS文件中,其中格式符%s表示字符串,格式符\n表示行终止符 --语法:UTL_FILE.PUTF_NCHAR(file in file_type,format in varchar2,[arg1 in varchar2 default null,...arg5 in varchar2 default null]); --如上所示,arg1,...,arg5用于指定对应于格式符的字符串 --FFLUSH:用于将数据强制性写入到OS文件 --语法:UTL_FILE.FFLUSH(file in file_type); --FSEEK:用于移动文件指针到特定位置,当使用该过程移动文件指针时,即可以指定文件指针的绝对位置,也可以指定文件指针的相对位置 --语法:UTL_FILE.FSEEK(fid in utl_file.file_type,absolute_offset in PL_INTEGER DEFAULT NULL,relative_offset IN PLS_INTEGER DEFAULT NULL); --如上所示,absolute_offset用于指定文件指针的绝对位置(单位:字节),relative_offset用于指定文件指针的相对位置(单位:字节) DECLARE handle utl_file.file_type; BEGIN handle:=utl_file.fopen('USER_DIR','a.txt','r'); dbms_output.put_line('文件指针起始位置:'||utl_file.fgetpos(handle)); utl_file.fseek(handle,20); dbms_output.put_line('文件指针当前位置:'||utl_file.fgetpos(handle)); utl_file.fclose(handle); END; --FREMOVE:用于删除磁盘文件 begin utl_file.fremove('USER_DIR','b.txt'); end; --FCOPE:用于将源文件的全部或部分内容复制到目标文件中。当使用该过程时,如果不设置起始行和结束行,则将复制文件的所有内容 --语法:UTL_FILE.FCOPY(location IN VARCHAR2,filename IN VARCHAR2,dest_dir IN VARCHAR2,dest_file IN VARCHAR2,start_line IN PLS_INTEGER DEFAULT 1,end_line IN PLS_INTEGER DEFAULT null); --如上所示:location用于指定源文件所在目录对应的DIRECTORY对象,filename用于指定源文件名,dest_dir用于指定目标文件所在目录对应的DIRECTORY对象 --dest_file用于指定目标文件的名称,start_line用于指定起始行号,end_line用于指定结束行号 begin utl_file.fcopy('USER_DIR','a.txt','USER_DIR','c.txt'); end; --FGETPOS:用于返回文件指针所在的偏移位置 --语法:UTL_FILE.FGETPOS(fileid IN file_type) RETURN PLS_INTEGER; --FGETATTR:用于读取磁盘文件,并返回文件属性 --UTL_FILE.FGETATTR(location IN VARCHAR2,filename IN VARCHAR2,exists OUT BOOLEAN,file_length OUT NUMBER,blocksize OUT NUMBER); --如上所示,location用于指定OS目录所对应的DIRECTORY对象,filename用于指定OS文件名,exists用于确定文件是否存在,file_length用于取得文件长度,blocksize用于取得OS块的尺寸 DECLARE fileexist boolean; filelen int; os_block int; BEGIN utl_file.fgetattr('USER_DIR','readme.txt',fileexist,filelen,os_block); if fileexist then dbms_output.put_line('文件尺寸:'||filelen); dbms_output.put_line('OS块尺寸:'||os_block); end if; END; --FRENAME:用于修改已存在的OS文件名,其作用与UNIX的mv命令相同。 --在修改文件名时,通过指定overwrite参数,可以覆盖已存在的文件 --语法: --UTL_FILE.FRENAME(location IN VARCHAR2,filename IN VARCHAR2,dest_dir IN VARCHAR2,dest_file IN VARCHAR2,overwrite IN BOOLEAN DEFAULT FALSE); --如上所示,overwrite用于指定是否要覆盖已存在文件(FALSE:不能覆盖,TRUE:覆盖) begin utl_file.frename('USER_DIR','d.txt','USER_DIR','c.txt'); end; --22.UTL_INADDR --用于取得局域网或Internet环境中的主机名和IP地址 --GET_HOST_NAME:用于取得指定IP地址所对应的主机名 select utl_inaddr.get_host_name('127.0.0.1') hostname from dual; select utl_inaddr.get_host_name('192.168.1.100') hostname from dual; --GET_HOST_ADDRESS:用于取得指定主机所对应的IP地址 select utl_inaddr.get_host_address('haiya-85ad31149') ip from dual; select utl_inaddr.get_host_address('haiya-85ad31142') ip from dual;