我先贴几个(如有不正确或不确切的地方,望指正):
1。job的使用:
DBMS_JOB.SUBMIT(:jobno,//job号
'your_procedure;',//要执行的过程
trunc(sysdate)+1/24,//下次执行时间
'trunc(sysdate)+1/24+1'//每次间隔时间
);
删除job:dbms_job.remove(jobno);
修改要执行的操作:job:dbms_job.what(jobno,what);
修改下次执行时间:dbms_job.next_date(job,next_date);
修改间隔时间:dbms_job.interval(job,interval);
停止job:dbms.broken(job,broken,nextdate);
启动job:dbms_job.run(jobno);
例子:
VARIABLE jobno number;
begin
DBMS_JOB.SUBMIT(:jobno,
'Procdemo;',//Procdemo为过程名称
SYSDATE, 'SYSDATE + 1/720');
commit;
end;
/
2。把一个表放在内存里
alter table tablename cache.
3。创建临时表
CREATE GLOBAL TEMPORARY TABLE TABLENAME (
COL1 VARCHAR2(10),
COL2 NUMBER
) ON COMMIT PRESERVE(DELETE) ROWS ;
这种临时表不占用表空间,而且不同的SESSION之间互相看不到对方的数据
在会话结束后表中的数据自动清空,如果选了DELETE ROWS,则在提交的时候即清空数据,PRESERVE则一直到会话结束
4。加一个自动增加的id号
第一种方法:
第一步:创建SEQUENCE
create sequence s_country_id increment by 1 start with 1 maxvalue 999999999;
第二步:创建一个基于该表的before insert 触发器,在触发器中使用该SEQUENCE
create or replace trigger bef_ins_t_country_define
before insert on t_country_define
referencing old as old new as new for each row
begin
select s_country_id.nextval into :new.country_id from dual;
end;
/
第二种方法:
CREATE OR REPLACE TRIGGER TR1
BEFORE INSERT ON temp_table
FOR EACH ROW
declare
com_num NUMBER;
BEGIN
SELECT MAX(ID) INTO COM_NUM FROM TEMP_TABLE;
:NEW.ID:=COM_NUM+1;
END TR1;
/
5。限制用户登录:创建一个概要文件
create profile CLERK_PROFILE limit
session_per_user 1 #用户可拥有的会话次数
idle_time 10 #进程处于空闲状态的时间(10分钟)
然后就可以将该概要文件授予一个用户
alter user A profile CLERK_PROFILE;
6。使触发器为无效alter trigger yourtriggername disable如果是对于某一个表的所有的触发器:
alter table yourtablename disable all triggers
1。job的使用:
DBMS_JOB.SUBMIT(:jobno,//job号
'your_procedure;',//要执行的过程
trunc(sysdate)+1/24,//下次执行时间
'trunc(sysdate)+1/24+1'//每次间隔时间
);
删除job:dbms_job.remove(jobno);
修改要执行的操作:job:dbms_job.what(jobno,what);
修改下次执行时间:dbms_job.next_date(job,next_date);
修改间隔时间:dbms_job.interval(job,interval);
停止job:dbms.broken(job,broken,nextdate);
启动job:dbms_job.run(jobno);
例子:
VARIABLE jobno number;
begin
DBMS_JOB.SUBMIT(:jobno,
'Procdemo;',//Procdemo为过程名称
SYSDATE, 'SYSDATE + 1/720');
commit;
end;
/
2。把一个表放在内存里
alter table tablename cache.
3。创建临时表
CREATE GLOBAL TEMPORARY TABLE TABLENAME (
COL1 VARCHAR2(10),
COL2 NUMBER
) ON COMMIT PRESERVE(DELETE) ROWS ;
这种临时表不占用表空间,而且不同的SESSION之间互相看不到对方的数据
在会话结束后表中的数据自动清空,如果选了DELETE ROWS,则在提交的时候即清空数据,PRESERVE则一直到会话结束
4。加一个自动增加的id号
第一种方法:
第一步:创建SEQUENCE
create sequence s_country_id increment by 1 start with 1 maxvalue 999999999;
第二步:创建一个基于该表的before insert 触发器,在触发器中使用该SEQUENCE
create or replace trigger bef_ins_t_country_define
before insert on t_country_define
referencing old as old new as new for each row
begin
select s_country_id.nextval into :new.country_id from dual;
end;
/
第二种方法:
CREATE OR REPLACE TRIGGER TR1
BEFORE INSERT ON temp_table
FOR EACH ROW
declare
com_num NUMBER;
BEGIN
SELECT MAX(ID) INTO COM_NUM FROM TEMP_TABLE;
:NEW.ID:=COM_NUM+1;
END TR1;
/
5。限制用户登录:创建一个概要文件
create profile CLERK_PROFILE limit
session_per_user 1 #用户可拥有的会话次数
idle_time 10 #进程处于空闲状态的时间(10分钟)
然后就可以将该概要文件授予一个用户
alter user A profile CLERK_PROFILE;
6。使触发器为无效alter trigger yourtriggername disable如果是对于某一个表的所有的触发器:
alter table yourtablename disable all triggers
SQL> alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
会话已更改。1. 选取 TOP N 行记录
A. SELECT * FROM CAT WHERE ROWNUM<=N
B. SELECT * FROM
( SELECT * FROM CAT ORDER BY TABLE_TYPE )
WHERE ROWNUM<=N 2. 选取N1-N2行记录
A. SELECT TABLE_NAME,TABLE_TYPE FROM
( SELECT ROWNUM ROWSEQ,TABLE_NAME,TABLE_TYPE FROM CAT )
WHERE ROWSEQ BETWEEN N1+1 AND N2;
或:
SELECT * FROM CAT WHERE ROWNUM<=N2
MINUS
SELECT * FROM CAT WHERE ROWNUM
B. SELECT TABLE_NAME,TABLE_TYPE FROM
( SELECT ROWNUM ROWSEQ,TABLE_NAME,TABLE_TYPE FROM CAT ORDER BY TABLE_TYPE)
WHERE ROWSEQ BETWEEN N1+1 AND N2; 查主键名称:
select * from user_constraints
where table_name = 'ART'
and constraint_type ='P';保存过程内容到文件
先修改init.ora
例如:
utl_file_dir=/usr //路径为 oracle所在的盘:/usr
此过程将用户TEMP的P1过程的代码保存到ORACLE安装盘下/USR/TEXT.TXT中
create or replace procedure TEST
is
file_handle utl_file.file_type;
STOR_TEXT VARCHAR2(4000);
N NUMBER;
I NUMBER;
begin
I:=1;
SELECT MAX(LINE) INTO N FROM ALL_SOURCE WHERE OWNER='TEMP' AND NAME='P1';
file_handle:=utl_file.fopen('/usr','test.txt','a');
WHILE I<=N LOOP
SELECT TEXT INTO STOR_TEXT FROM ALL_SOURCE WHERE OWNER='TEMP' AND NAME='P1' AND LINE= I;
I:=I+1;
utl_file.put_line(file_handle,stor_text);
END LOOP;
utl_file.fclose(file_handle);
commit;
end TEST;
/
有空常来这里,最好你也能任oracle的斑竹,大家需要你。
如果有什么做的不好的地方,请多多指教。
另外,我上网的时间一般在下班的时间内(包括中午),所以如果你在上班的时候能上网的话,请多多照看这里。
这是我回答的分区表的问题,那位楼主没有看,可惜了,贴在这里,哪位需要的
可以取用。0、建立分区表
create table partition_test
(
id number(9),
tmpStr varchar2(10)
)
partition by range(id)
(
partition id01 values less than (3000000) tablespace test_tabspc1,
partition id02 values less than (6000000) tablespace test_tabspc2,
partition id03 values less than (9000000) tablespace test_tabspc3,
partition id04 values less than (12000000) tablespace test_tabspc4,
partition id05 values less than (MAXVALUE) tablespace test_tabspc5
)
/1、建立局部分区索引
Create index your_index on caishui.partition_test(id)
local
(
partition id01 tablespace test_tabspc1,
partition id02 tablespace test_tabspc2,
partition id03 tablespace test_tabspc3,
partition id04 tablespace test_tabspc4,
partition id05 tablespace test_tabspc5
)
/2、重建某一个分区的索引
alter index your_index rebuild partition id01 tablespace test_tabspc1
/3、增加分区
alter table caishui.partition_test
add partition id06 values less than (15000000) tablespace test_tabspc6
/4、有影响5、可以
ALTER TABLE PARTITION_TEST
MERGE PARTITIONS
id01, id02
INTO PARTITION 新分区名
/6、外部数据文件 d:\test.txt
1|猪八戒
2|孙悟空
3|唐僧
建一个控制文件 d:\test.ctl
load data
infile 'd:\test.txt'
append
into table partition_test
FIELDS TERMINATED BY "|"
(id,tmpStr)
将数据文件的数据导入数据库
sqlldr userid=caishui/password control=d:\test.ctl
如何正确利用Rownum来限制查询所返回的行数? 软件环境:
1、Windows NT4.0+ORACLE 8.0.4
2、ORACLE安装路径为:C:\ORANT含义解释:
1、rownum是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,
依此类推,这个伪字段可以用于限制查询返回的总行数。
2、rownum不能以任何基表的名称作为前缀。
使用方法:
现有一个商品销售表sale,表结构为:
month char(6) --月份
sell number(10,2) --月销售金额create table sale (month char(6),sell number);
insert into sale values('200001',1000);
insert into sale values('200002',1100);
insert into sale values('200003',1200);
insert into sale values('200004',1300);
insert into sale values('200005',1400);
insert into sale values('200006',1500);
insert into sale values('200007',1600);
insert into sale values('200101',1100);
insert into sale values('200202',1200);
insert into sale values('200301',1300);
insert into sale values('200008',1000);
commit;SQL> select rownum,month,sell from sale where rownum=1;(可以用在限制返回记录条数的地方,保证不出错,如:隐式游标)ROWNUM MONTH SELL
--------- ------ ---------
1 200001 1000SQL> select rownum,month,sell from sale where rownum=2;(1以上都查不到记录)没有查到记录SQL> select rownum,month,sell from sale where rownum>5;
(由于rownum是一个总是从1开始的伪列,Oracle 认为这种条件不成立,查不到记录)
没有查到记录只返回前3条纪录
SQL> select rownum,month,sell from sale where rownum<4;ROWNUM MONTH SELL
--------- ------ ---------
1 200001 1000
2 200002 1100
3 200003 1200
如何用rownum实现大于、小于逻辑?(返回rownum在4—10之间的数据)(minus操作,速度会受影响)
SQL> select rownum,month,sell from sale where rownum<10
2 minus
3 select rownum,month,sell from sale where rownum<5;ROWNUM MONTH SELL
--------- ------ ---------
5 200005 1400
6 200006 1500
7 200007 1600
8 200101 1100
9 200202 1200想按日期排序,并且用rownum标出正确序号(有小到大)
SQL> select rownum,month,sell from sale order by month;ROWNUM MONTH SELL
--------- ------ ---------
1 200001 1000
2 200002 1100
3 200003 1200
4 200004 1300
5 200005 1400
6 200006 1500
7 200007 1600
11 200008 1000
8 200101 1100
9 200202 1200
10 200301 1300查询到11记录.可以发现,rownum并没有实现我们的意图,系统是按照记录入库时的顺序给记录排的号,rowid也是顺序分配的SQL> select rowid,rownum,month,sell from sale order by rowid;ROWID ROWNUM MONTH SELL
------------------ --------- ------ ---------
000000E4.0000.0002 1 200001 1000
000000E4.0001.0002 2 200002 1100
000000E4.0002.0002 3 200003 1200
000000E4.0003.0002 4 200004 1300
000000E4.0004.0002 5 200005 1400
000000E4.0005.0002 6 200006 1500
000000E4.0006.0002 7 200007 1600
000000E4.0007.0002 8 200101 1100
000000E4.0008.0002 9 200202 1200
000000E4.0009.0002 10 200301 1300
000000E4.000A.0002 11 200008 1000查询到11记录.正确用法,使用子查询
SQL> select rownum,month,sell from (select month,sell from sale group by month,sell) where rownum<13;ROWNUM MONTH SELL
--------- ------ ---------
1 200001 1000
2 200002 1100
3 200003 1200
4 200004 1300
5 200005 1400
6 200006 1500
7 200007 1600
8 200008 1000
9 200101 1100
10 200202 1200
11 200301 1300按销售金额排序,并且用rownum标出正确序号(有小到大)
SQL> select rownum,month,sell from (select sell,month from sale group by sell,month) where rownum<13;ROWNUM MONTH SELL
--------- ------ ---------
1 200001 1000
2 200008 1000
3 200002 1100
4 200101 1100
5 200003 1200
6 200202 1200
7 200004 1300
8 200301 1300
9 200005 1400
10 200006 1500
11 200007 1600查询到11记录.利用以上方法,如在打印报表时,想在查出的数据中自动加上行号,就可以利用rownum。返回第5—9条纪录,按月份排序
SQL> select * from (select rownum row_id ,month,sell
2 from (select month,sell from sale group by month,sell))
3 where row_id between 5 and 9;ROW_ID MONTH SELL
---------- ------ ----------
5 200005 1400
6 200006 1500
7 200007 1600
8 200008 1000
9 200101 1100
(1)
查所及杀锁
select l.session_id sid,
l.locked_mode lockmode,
l.oracle_username db_user,
l.os_user_name os_user,
s.machine,
s.schemaname,
o.object_name tablename,
q.sql_text
from v$locked_object l, v$session s, v$sql q, all_objects o
where l.session_id=s.sid and
s.type='USER' and
s.sql_address=q.address and
l.object_id=o.object_idalter system kill session 'sid,SERIAL#'
1.having 子句的用法 having 子句对 group by 子句所确定的行组进行控制,having 子句条件中只允许涉及常量,聚组函数或group by 子句中的列. 2.外部联接"+"的用法 外部联接"+"按其在"="的左边或右边分左联接和右联接.若不带"+"运算符的表中的一个行不直接匹配于带"+"预算符的表中的任何行,则前者的行与后者中的一个空行相匹配并被返回.若二者均不带’+’,则二者中无法匹配的均被返回.利用外部联接"+",可以替代效率十分低下的 not in 运算,大大提高运行速度.例如,下面这条命令执行起来很慢 select a.empno from emp a where a.empno not in (select empno from emp1 where job=’SALE’); 倘若利用外部联接,改写命令如下: select a.empno from emp a ,emp1 b where a.empno=b.empno(+) and b.empno is null and b.job=’SALE’; 可以发现,运行速度明显提高. 3.删除表内重复记录的方法 可以利用这样的命令来删除表内重复记录: delete from table_name a where rowid< (select max(rowid) from table_name where column1=a.column1 and column2=a.column2 and colum3=a.colum3 and ...);
如我要找出以tt_开头的表,若安以下写法只能取出以tt开头的表,
因为_在like中用意是任意单一字符。
SELECT Tname FROM tab
WHERE Tname like 'tt_%'
答:SELECT * FROM tab
WHERE tname LIKE 'TT/_%' ESCAPE '/'
(2)
1. 监控事例的等待 select event,sum(decode(wait_Time,0,0,1)) "Prev",
sum(decode(wait_Time,0,1,0)) "Curr",count(*) "Tot"
from v$session_Wait
group by event order by 4; 2. 回滚段的争用情况 select name, waits, gets, waits/gets "Ratio"
from v$rollstat a, v$rollname b
where a.usn = b.usn; 3. 监控表空间的 I/O 比例 select df.tablespace_name name,df.file_name "file",f.phyrds pyr,
f.phyblkrd pbr,f.phywrts pyw, f.phyblkwrt pbw
from v$filestat f, dba_data_files df
where f.file# = df.file_id
order by df.tablespace_name; 4. 监控文件系统的 I/O 比例 select substr(a.file#,1,2) "#", substr(a.name,1,30) "Name",
a.status, a.bytes, b.phyrds, b.phywrts
from v$datafile a, v$filestat b
where a.file# = b.file#; 5.在某个用户下找所有的索引 select user_indexes.table_name, user_indexes.index_name,uniqueness, column_name
from user_ind_columns, user_indexes
where user_ind_columns.index_name = user_indexes.index_name
and user_ind_columns.table_name = user_indexes.table_name
order by user_indexes.table_type, user_indexes.table_name,
user_indexes.index_name, column_position; 6. 监控 SGA 的命中率 select a.value + b.value "logical_reads", c.value "phys_reads",
round(100 * ((a.value+b.value)-c.value) / (a.value+b.value)) "BUFFER HIT RATIO"
from v$sysstat a, v$sysstat b, v$sysstat c
where a.statistic# = 38 and b.statistic# = 39
and c.statistic# = 40; 7. 监控 SGA 中字典缓冲区的命中率 select parameter, gets,Getmisses , getmisses/(gets+getmisses)*100 "miss ratio",
(1-(sum(getmisses)/ (sum(gets)+sum(getmisses))))*100 "Hit ratio"
from v$rowcache
where gets+getmisses <>0
group by parameter, gets, getmisses; 8. 监控 SGA 中共享缓存区的命中率,应该小于1% select sum(pins) "Total Pins", sum(reloads) "Total Reloads",
sum(reloads)/sum(pins) *100 libcache
from v$librarycache; select sum(pinhits-reloads)/sum(pins) "hit radio",sum(reloads)/sum(pins) "reload percent"
from v$librarycache; 9. 显示所有数据库对象的类别和大小 select count(name) num_instances ,type ,sum(source_size) source_size ,
sum(parsed_size) parsed_size ,sum(code_size) code_size ,sum(error_size) error_size,
sum(source_size) +sum(parsed_size) +sum(code_size) +sum(error_size) size_required
from dba_object_size
group by type order by 2; 10. 监控 SGA 中重做日志缓存区的命中率,应该小于1% SELECT name, gets, misses, immediate_gets, immediate_misses,
Decode(gets,0,0,misses/gets*100) ratio1,
Decode(immediate_gets+immediate_misses,0,0,
immediate_misses/(immediate_gets+immediate_misses)*100) ratio2
FROM v$latch WHERE name IN ('redo allocation', 'redo copy'); 11. 监控内存和硬盘的排序比率,最好使它小于 .10,增加 sort_area_size SELECT name, value FROM v$sysstat WHERE name IN ('sorts (memory)', 'sorts (disk)');
12. 监控当前数据库谁在运行什么SQL语句 SELECT osuser, username, sql_text from v$session a, v$sqltext b
where a.sql_address =b.address order by address, piece; 13. 监控字典缓冲区 SELECT (SUM(PINS - RELOADS)) / SUM(PINS) "LIB CACHE" FROM V$LIBRARYCACHE;
SELECT (SUM(GETS - GETMISSES - USAGE - FIXED)) / SUM(GETS) "ROW CACHE" FROM V$ROWCACHE;
SELECT SUM(PINS) "EXECUTIONS", SUM(RELOADS) "CACHE MISSES WHILE EXECUTING" FROM V$LIBRARYCACHE; 后者除以前者,此比率小于1%,接近0%为好。 SELECT SUM(GETS) "DICTIONARY GETS",SUM(GETMISSES) "DICTIONARY CACHE GET MISSES"
FROM V$ROWCACHE 14. 找ORACLE字符集 select * from sys.props$ where name='NLS_CHARACTERSET'; 15. 监控 MTS select busy/(busy+idle) "shared servers busy" from v$dispatcher; 此值大于0.5时,参数需加大 select sum(wait)/sum(totalq) "dispatcher waits" from v$queue where type='dispatcher';
select count(*) from v$dispatcher;
select servers_highwater from v$mts; servers_highwater接近mts_max_servers时,参数需加大 16. 碎片程度 select tablespace_name,count(tablespace_name) from dba_free_space group by tablespace_name
having count(tablespace_name)>10; alter tablespace name coalesce;
alter table name deallocate unused; create or replace view ts_blocks_v as
select tablespace_name,block_id,bytes,blocks,'free space' segment_name from dba_free_space
union all
select tablespace_name,block_id,bytes,blocks,segment_name from dba_extents; select * from ts_blocks_v; select tablespace_name,sum(bytes),max(bytes),count(block_id) from dba_free_space
group by tablespace_name; 查看碎片程度高的表 SELECT segment_name table_name , COUNT(*) extents
FROM dba_segments WHERE owner NOT IN ('SYS', 'SYSTEM') GROUP BY segment_name
HAVING COUNT(*) = (SELECT MAX( COUNT(*) ) FROM dba_segments GROUP BY segment_name); 17. 表、索引的存储情况检查 select segment_name,sum(bytes),count(*) ext_quan from dba_extents where
tablespace_name='&tablespace_name' and segment_type='TABLE' group by tablespace_name,segment_name; select segment_name,count(*) from dba_extents where segment_type='INDEX' and owner='&owner'
group by segment_name; 18、找使用CPU多的用户session 12是cpu used by this session select a.sid,spid,status,substr(a.program,1,40) prog,a.terminal,osuser,value/60/100 value
from v$session a,v$process b,v$sesstat c
where c.statistic#=12 and c.sid=a.sid and a.paddr=b.addr order by value desc;
软件环境:
1、Windows NT4.0+ORACLE 8.0.4
2、ORACLE安装路径为:C:\ORANT问题提出:
1、当我们想要为一个表创建唯一索引时,如果该表有重复的记录,则无法创建成功。
方法原理:
1、Oracle中,每一条记录都有一个rowid,rowid在整个数据库中是唯一的,
rowid确定了每条记录是在ORACLE中的哪一个数据文件、块、行上。2、在重复的记录中,可能所有列的内容都相同,但rowid不会相同,所以只要确定出重复记录中
那些具有最大rowid的就可以了,其余全部删除。3、以下语句用到了3项技巧:rowid、子查询、别名。实现方法:
SQL> create table a (
2 bm char(4), --编码
3 mc varchar2(20) --名称
4 )
5 /表已建立.SQL> insert into a values('1111','1111');
SQL> insert into a values('1112','1111');
SQL> insert into a values('1113','1111');
SQL> insert into a values('1114','1111');SQL> insert into a select * from a;插入4个记录.SQL> commit;完全提交.SQL> select rowid,bm,mc from a;ROWID BM MC
------------------ ---- -------
000000D5.0000.0002 1111 1111
000000D5.0001.0002 1112 1111
000000D5.0002.0002 1113 1111
000000D5.0003.0002 1114 1111
000000D5.0004.0002 1111 1111
000000D5.0005.0002 1112 1111
000000D5.0006.0002 1113 1111
000000D5.0007.0002 1114 1111查询到8记录.
查出重复记录
SQL> select rowid,bm,mc from a where a.rowid!=(select max(rowid) from a b where a.bm=b.bm and a.mc=b.mc);ROWID BM MC
------------------ ---- --------------------
000000D5.0000.0002 1111 1111
000000D5.0001.0002 1112 1111
000000D5.0002.0002 1113 1111
000000D5.0003.0002 1114 1111删除重复记录
SQL> delete from a a where a.rowid!=(select max(rowid) from a b where a.bm=b.bm and a.mc=b.mc);删除4个记录.SQL> select rowid,bm,mc from a;ROWID BM MC
------------------ ---- --------------------
000000D5.0004.0002 1111 1111
000000D5.0005.0002 1112 1111
000000D5.0006.0002 1113 1111
000000D5.0007.0002 1114 1111
ORACLE一般的做法是同时使用序列和触发器来生成一个自增字段.
CREATE SEQUENCE SEQname
INCREMENT BY 1
START WITH 1
MAXVALUE 99999999
/
CREATE TRIGGER TRGname
BEFORE INSERT ON table_name
REFERENCING
NEW AS :NEW
FOR EACH ROW
Begin
SELECT SEQname.NEXTVAL
INTO :NEW.FIELDname
FROM DUAL;
End;
/
在oracle8.1.5中:
用execute immediate来实现
declare
tsql varchar2(200);
begin
tsql:='insert into '||tname||'values ('aaa','bbb')';
execute immediate tsql;
end;
/
希望以后有更多的工具型PL/SQL
create or replace procedure backup_table_to_file /*功能:将ORACLE的任意表数据导出(标准格式) 编写:中国工商银行四川省分行营业部技术保障处杨宇*/
(
v_tablename varchar2, /*需要导出的表名*/
v_path varchar2, /*服务器上导出数据文件的目录*/
v_string varchar2, /*服务器上导出数据文件的文件名*/
v_where varchar2, /*查询条件*/
v_flag varchar2, /*写数据文件的方式 w:重写 a:追加*/
outflag out varchar2 /*返回处理结果 0 成果、1 写入目录有误、2 表名有误、3 写入目录不能为空、4 写入文件方式有误、5 查询条件有误、6 其他错误*/
)
is
file_handle utl_file.file_type;
path_notinput_exception EXCEPTION;
table_notfind_exception EXCEPTION;
write_type_exception EXCEPTION;
type ref_cursor_type is REF CURSOR;
cursor_select ref_cursor_type;
outputline varchar2(1000) ;
select_cname varchar2(1000) ;
w_flag varchar2(10);
get_cname varchar2(1000) ;
put_cname varchar2(1000) ;
temp varchar2(1000) ;
resault varchar2(1000) ;
filepath varchar2(100) ;
filename varchar2(100) ;
i integer;
begin
outflag :='0';
IF (v_path is null) THEN --初始化服务器文件夹
RAISE path_notinput_exception;
ELSE
filepath := rtrim(trim(v_path),'/');
END IF; --初始化服务器文件夹
get_cname := '';
temp := nls_upper(v_tablename);
if (v_flag is null) then --初始化写文件方式
w_flag := 'w';
else
w_flag := v_flag;
end if; --初始化写文件方式
if w_flag in ('W','w','A','a') then
select_cname := 'select cname from col where tname = '||''''||temp||'''';
OPEN cursor_select for select_cname;
FETCH cursor_select into get_cname;
IF (get_cname is null) THEN
RAISE table_notfind_exception;
END IF;
put_cname := ''''||'"'||''''||'||'||get_cname||'||'||''''||'"'||'''';
WHILE cursor_select%FOUND LOOP
FETCH cursor_select into get_cname;
EXIT WHEN cursor_select%NOTFOUND;
put_cname :=put_cname ||'||'||''''||','||''''||'||'||''''||'"'||''''||'||'||get_cname||'||'||''''||'"'||'''';
END LOOP;
CLOSE cursor_select;
IF (v_string is null) then
select_cname := 'select to_char(sysdate,'||''''||'yyyymmdd'||''''||') from DUAL';
OPEN cursor_select for select_cname;
FETCH cursor_select into filename;
CLOSE cursor_select;
filename := v_tablename||'.'||filename||'.txt';
ELSE
filename := v_string;
END IF;
file_handle :=utl_file.fopen(filepath,filename,w_flag);
select_cname := 'select '||put_cname||' from '||temp||' '||v_where;
resault := '';
OPEN cursor_select for select_cname;
FETCH cursor_select into resault;
WHILE cursor_select%FOUND LOOP
outputline := resault;
utl_file.put_line(file_handle,outputline);
FETCH cursor_select into resault;
END LOOP;
CLOSE cursor_select;
utl_file.fclose(file_handle);
ELSE
RAISE write_type_exception;
end if;
exception
when utl_file.invalid_path then
outflag :='1';
--raise_application_error(-20001,'错误:主机的写入文件目录有误!');
when table_notfind_exception then
outflag :='2';
--raise_application_error(-20002,'错误:输入的表名有误!');
when path_notinput_exception then
outflag :='3';
--raise_application_error(-20003,'错误:服务器的写入文件目录为必输项!');
when write_type_exception then
outflag :='4';
--raise_application_error(-20004,'错误:写入文件方式有误!');
when others then
if sqlcode like '-9%' then
outflag :='5';
--raise_application_error(-20005,'错误:查询条件有误!');
else
outflag :='6';
raise_application_error(sqlcode,sqlerrm);
end if;
end backup_table_to_file;
重新启动数据库;
打开审计audit session; (audit session by username)
执行登录操作;
察看审计结果:
select * from dba_audit_session;
select * from sys.aud$;
select * from dba_audit_trail;
select * from dba_audit_exists;
关于审计: 为了使oracle8i的审计功能可用,必须在数据库参数文件中修改audit_trail初始参数,而这个修改并不支配oracle8i把生成的审计记录记入审计痕迹中,
由于状态,特权和模式对象已被修改,因而审计的默认值不可用,其参数应设置为none.下面列出了audit_trail 可用的参数db_使数据库审计和全部直属审计记录到数据库审计的痕迹中
os_是数据库审计依据直属审计记入到操作系统的审计很集中
none_不可用