精通Oracle10编程SQL(17)使用ORACLE系统包

/*
 *使用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;

 

你可能感兴趣的:(oracle,数据库,plsql)