1、第 1 页不足之处,敬请指正 QQ 77056803ORACLE SQL 对比网上已经有很多 SQL 与 ORACLE 的对比 ,但本人要讲的即不是单纯的 SQL,也不是单纯的 ORACLE,更不是评价谁好谁坏(意思不大) ,而是两种数据库之相同和异同,本人曾讲授过 SQL 与 ORACLE 的课程,讲 SQL 时说 SQL 好,讲 ORACLE 时又说 ORACLE棒,现在终于可以平心而评啦。估计有人现在会嘿嘿冷笑(又一个误人子弟的骗子) ,老实说,当初每次讲完课,就有这种感觉教的人不得其法,学的人不得其道。说点严肃的事吧,据说比尔与艾里森在洗手间相遇,两个又是拥抱,又是 KISS,不多久
2、就吵了起来,比尔对查询分析器(SQL QUERY ANALYZE)赞不经绝口,艾里森嘿嘿冷笑,只说了一句话SQL PLUS 内秀。言归正传,且听我一一道来001、SQL 与 ORACLE 的内存分配ORACLE 的内存分配大部分是由 INIT.ORA 来决定的,一个数据库实例可以有 N 种分配方案,不同的应用(OLTP、OLAP)它的配置是有侧重的。SQL 概括起来说,只有两种内存分配方式:动态内存分配与静态内存分配,动态内存分配充许 SQL 自己调整需要的内存,静态内存分配限制了 SQL 对内存的使用。002、SQL 与 ORACLE 的物理结构总得讲,它们的物理结构很相似,SQL 的数据库
3、相当于 ORACLE 的模式(方案) ,SQL的文件组相当于 ORACLE 的表空间,作用都是均衡 DISK I/O,SQL 创建表时,可以指定表在不同的文件组,ORACLE 则可以指定不同的表空间。CREATE TABLE A001(ID DECIMAL(8,0) ) ON 文件组-CREATE TABLE A001(ID NUMBER(8,0) ) TABLESPACE 表空间注:以后所有示例,先 SQL,后 ORACLE003、SQL 与 ORACLE 的日志模式SQL 对日志的控制有三种恢复模型:SIMPLE、FULL、BULK-LOGGED;ORACLE对日志的控制有二种模式:NOA
4、RCHIVELOG、ARCHIVELOG。SQL 的 SIMPLE 相当于ORACLE 的 NOARCHIVELOG,FULL 相当于 ARCHIVELOG,BULK-LOGGED 相当于ORACLE 大批量数据装载时的 NOLOGGING。经常有网友抱怨 SQL 的日志庞大无比且没法处理,最简单的办法就是先切换到 SIMPLE 模式,收缩数据库后再切换到 FULL,记住切换到 FULL 之后要马上做完全备份。第 2 页不足之处,敬请指正 QQ 77056803004、SQL 与 ORACLE 的备份类型SQL 的备份类型分的极杂:完全备份、增量备份、日志备份、文件或文件组备份;ORACLE
5、 的备份类型就清淅多啦:物理备份、逻辑备份;ORACLE 的逻辑备份(EXP)相当于 SQL 的完全备份与增量备份,ORACLE 的物理备份相当于 SQL 的文件与文件组备份。SQL 的各种备份都密切相关,以完全备份为基础,配合其它的备份方式,就可以灵活地备分数据;ORACLE 的物理备份与逻辑备份各司其职。SQL 可以有多个日志,相当于ORACLE 日志组,ORACLE 的日志自动切换并归档,SQL 的日志不停地膨胀SQL 有附加数据库,可以将数据库很方便地移到别一个服务器,ORACLE 有可传输表空间,可操作性就得注意啦。005、SQL 与 ORACLE 的恢复类型SQL 有完全恢复与基于
6、时间点的不完全恢复;ORACLE 有完全恢复与不完全恢复,不完全恢复有三种方式:基于取消的、基于时间的、基于修改的(SCN)的恢复。不完全恢复可以恢复数据到某个稳定的状态点。006、SQL 与 ORACLE 的事务隔离SET TRANSACTION ISOLATION LEVEL SQL 有四种事务隔离级别:READ COMMITTED、READ UNCOMMITTED、REPEATABLE READ、SERIALIZABLEORACLE 有两种事务隔离级别READ COMMITTED、SERIALIZABLESQL 虽然有四种事务隔离,事务之间还是经常发生阻塞;ORACLE 则利用回退段很好
7、地实现了事务隔离,不会产生阻塞。SQL 与 ORACLE 如果发生死锁,都可以很快地识别并将之处理掉。007 SQL 与 ORACLE 的外键约束SQL 的外键约束可以实现级联删除与级联更新,ORACLE 则只充许级联删除。CREATE TABLE A001(ID INT PRIMARY KEY ,NAME VARCHAR(20) )CREATE TABLE A002(ID INT REFERENCES A001( ID)ON DELETE CASCADE ON UPDATE CASCADE,AGE TINYINT)CREATE TABLE A001(ID INT PRIMAY KEY,NAM
8、E VARCHAR2(20) )CREATE TABLE A002(ID INT REFERENCES A001(ID )ON DELETE CASCADE,AGE NUMBER(2,0) )第 3 页不足之处,敬请指正 QQ 77056803008、SQL 与 ORACLE 的临时表SQL 的临时表用#或#开头,使用完后自动释放,ORACLE 的临时表则存在数据库中,每个会话的数据都互不干涉。oracle 临时表中的纪录可以被定义为自动删除(分 commit 方式和 transaction 方式) ,而表结构不会被自动删除。临时表的 DML,DDL 操作和标准表一样。CREATE TABL
9、E #TEMP(ID INT,NAME VARCHAR(20) )-CREATE GLOBAL TEMPORARY TABLE TEMP(ID INT,VARCHAR2(20) )009、SQL 与 ORACLE 的类型转换SQL 常用类型转换函数有:CAST、CONVERT、STRORACLE 常用类型转换函数有:TO_CHAR、TO_NUMBER、TO_DATESELECT CONVERT(VARCHAR(20) ,GETDATE() ,112)-SELECT TO_CHAR(SYSDATE, YYYYMMDD)FROM DUAL010、SQL 与 ORACLE 的自动编号SQL 的编号一
10、般由 IDENTITY 字段来提供,可以灵活地设定种子值,增量,取值范围有BIGINT、INT、SMALLINT 、 TINYINT、DEIMAL 等;ORACLE 的编号一般由SEQUENCE 来提供,由 NEXTVAL 与 CURVAL 函数从 SEQUENCES 取值。CREATE TABLE A003(ID INT IDENTITY(-9999,9) ,NAME VARCHAR(20) )-CREATE SEQUENCE SEQ_001 START 9999 INCREMENT BY 9CREATE TABLE A004(ID INT)INSERT INTO A004 VALUES(S
11、EQ_001.NEXTVAL)INSERT INTO A004 VALUES(SEQ_001.CURVAL+1)011、SQL 与 ORACLE 的分区表从严格意思上来讲,SQL 还没有分区表,它的分区表是以 UNION 为基础,将多个结果集串起来,实际上是视图;ORACLE 的分区表有多种:PARTITION BY RANGE、PARTITION BY HASH、PARTITION BY LIST,其它就是混合分区,以上三种基础分区的混合使用。当然 ORACLE 也可以象 SQL 那样分区视图。CREATE TABLE A1999(ID INT,NAME VARCHAR(20) )CREAT
12、E TABLE A2000(ID INT,NAME VARCHAR(20) )第 4 页不足之处,敬请指正 QQ 77056803CREATE VIEW V_PART AS SELECT * FROM A1999 UNION SELECT * FROM A2000-CREATE TABLE A_PART1(ID INT,NAME VARCHAR2(20)PARTITON BY RANGE(ID)(PARTITION P1 VALUES LESS THEN (2000000) PATITION P2 VALUES LESS THEN (MAXVALUE)CREATE TABLE A_PART2
13、(ID INT,NAME VARCHAR2(20)PARTITION BY HASH(ID) PARTITIONS 2 STORE IN (USERS01,USERS02)CREATE TABLE A_PART3(ID INT,NAME VARCHAR2(20)PARTITION BY LIST(ID)(PARTIION P1 VALUES(01,03,05) PARTITON P2 VALUES(02,04)012、SQL 与 ORACLE 的存储过程SQL 的存储过程可以很方便地返回结果集,ORACLE 的存储过程只有通过游标类型返回结果集,这种结果集 ADO 不可识别,如果想使用 ORA
14、CLE 存储过程的结果集,只有使用ODAC 开发包(DELPHI/BCB 控件组 与 有下载) ,SQL的过程参数如果是字符必须指定参数长度,ORACLE 的过程则不充许指定字符参数的长度。CREATE PROCEDURE UP_001(ID INT) ASBEGIN SELECT ID ,SUM(QTY) FROM A_TEST WHERE ID=ID GROUP BY IDEND-CREATE OR REPLACE PACKAGE UP_002 ASTYPE MYCURSOR IS REF CURSOR;FUNCTION GETRECORD RETURN MYCURSOR;END;CE
15、EATE OR REPLACE PACKAGE BODY UP_002 ASFUNCTION GETRECORD RETURN MYCURSOR ASMC MYCURSOR;SL VARCHAR2(999) ;BEGINOPEN MC FOR SELECT * FROM A001;RETURN MC;END; END;ORACLE 的存储函数返回结果这么艰难,但 SQL 的触发器竟然也充许返回结果集就令人费解啦,触发器的调试比较麻烦,在 SQL 实际开发中,一般都将触发器要执行的代码放到过程中进行调试,在查询分析器中可以对过程进行设断点调试。第 5 页不足之处,敬请指正 QQ 7705680
16、3013、SQL 与 ORACLE 的触发器触发器的事务是引起触发动作事务的延续,在 SQL 的触发器中是可以无 BEGIN TRAN 而可以直接 COMMIT TRAN 的。SQL 的触发器是表级触发器, DML 影响一行或无数行触发动作只触发一次,ORACLE 分表级触发器与行级触发器,触发的粒度更细腻一些,SQL 在处理多行时就必须使用 CURSOR 啦。ORACLE 使用 INSERTING、DELTING、UPDATING 判断执行了什么DML 操作,SQL 只有判断 INSERTED、DELETED 的记录数来判断执行了什么操作,只有INSERTED 映象表记录数大于 0 表示 I
17、NSERT,只有 DELETED 映象表记录数大于 0 表示DELETE,若两个表记录数都大于 0 表示 UPDATE。用 SQL 的触发器实现级联添加、级联删除、级联更新CREATE TABLE A1(ID INT,NAME VARCHAR(20) )CREATE TABLE A2(ID INT,NAME VARCHAR(20) )CREATE TRIGGER TRI_A1_INS ON A1 FOR INSERT , DELETE , UPDATE AS BEGINDECLARE I INT,D INT,ID INTSELECT I=COUNT(*) FROM INSERTEDSELECT
18、 D=COUNT(*) FROM DELETED-IF (I0 AND D0) 执行更新,由于用到游标,故略去IF I0INSERT INTO A2 SELECT * FROM INSERTEDIF D0DELETE FROM A2 WHERE ID=IDEND-用 ORACLE 的触发器实现级联添加、级联删除、级联更新CREATE OR REPLACE TRI_A1_INS AFTER INSERT OR DELETE OR UPDATE ON A1 FOR EACH ROWBEGINIF INSERTING THENINSERT INTO A2 SELECT * FROM :NEW;END
19、 IF;IF DELETING THENDELETE FROM A2 WHERE ID = :OLD.ID ;END IF;IF UPDATING THENUPATE A2 SET ID = :NEW.ID , NAME = :NEW.NAME WHERE ID = :OLD.ID ;END IF;END 第 6 页不足之处,敬请指正 QQ 77056803014、SQL 与 ORACLE 的游标SQL 的游标用FETCH_STATUS 判断是否还有数据,ORACLE 的游标用%FOUND、%NOTFOUND 来判断游标是否结束,游标分服务端游标与客户端游标,在存储过程、函数、触发器中声明的
20、游标为服务端游标,其它处声明的游标为客户端游标,游标需要使用较多的内存,但它比临时表的性能要优一些,因为临时表占用的是 DISK I/O,DISK I/O应该比服务器的内存要更珍贵一些吧。015、SQL 与 ORACLE 的重复记录删除好的数据库设计重复记录是不存在的,如果有重复记录如何删除呢?SQL 可以使用 SET ROWCOUNT N 设置客户端缓冲区的记录来删除,ORACLE 可以使用 ROWID 来进行,都必须进行一些简单的编程,SQL 可以做用过程,更通用一些,ORACLE 如果想做得通过不太容易,字段小些会更方便处理一些。DECLARE M INTSELECT M=COUNT(*
21、) FROM A_TEST WHERE ID=XSELECT M=M-1SET ROWCOUNT M -限制客户端缓冲区的记录数DELETE FROM A_TEST WHERE ID=XSET ROWCOUNT 0 -取消限制说明 删除某条记录的重复值,如果想清除表的所有重值要使用游标,取得所有的 X-DELETE FROM A_TEST A WHERE ROWID!=(SELECT MAX(ROWID) FROM A_TEST BWHERE A.ID=B.ID AND A.NAME=B.NAME)说明 当数据量较大时,这种方法将会使用系统大量的资源016 SQL 与 ORACLE 的对象加密
22、SQL 与 ORACLE 的某些对象如过程、视图、函数、触发器可能涉及商业,开发商通常希望对这些对象进行加密,SQL 的加密方法在创建时带上 WITH ENCRYPTION,ORACLE 的对象加密明显复杂一些,要使用 WRAP 工具,在 ORACLE 的 BIN 目录内。017 SQL 与 ORACLE 的表生成 SQL 语句SQL 与 ORACLE 的表如何才导成 SQL 语句呢?如果一定要编程实现,SQL 需要将其它数据类型的字段转换成 VARCHAR 类型,ORACLE 则可以隐式进行数据类型转换。CREATE TABLE A_SQL(ID INT,NAME VARCHAR(20) 假
23、如有两万记录SELECT INSERT INTO A_SQL VALUES(+CAST(ID AS VARCHAR(20)+,+NAME+) FROM A_SQL-SELECT INSERT INTO A_SQL VALUES(|ID|,|NAME|)FROM A_SQL第 7 页不足之处,敬请指正 QQ 77056803说明 SQL 的字符串连接用+号,ORACLE 字符串连接用|,单引号可以做转义符。018、SQL 与 ORACLE 的动态 SQLSQL 与 ORACLE 都支持动态 SQL 语句,SQL 用 EXEC()执行的动态 SQL 语句,ORACLE用 EXECUTE IMME
24、DIATE 执行动态 SQL。动态 SQL 的效率要比非动态 SQL 性能差,但使用起来非常灵活,可以根据不同条件执行不同的任务。DECLARE SQL VARCHAR(99)SELECT SQL=declare m int select m=count(*) from sysobjects select mEXEC(SQL)-DECLARES VARCHAR2(99);BEGIN S:=SELECT COUNT(*) FROM | USER_TABLES;EXECUTE IMMEDIATE S;END;19、返回记录集中前 N 条记录的语法?SQL 只有使用 TOP,ORACLE 可以使用
25、ROWNUMSELECT TOP N * FROM 记录集(表,视图,子查询)-SELECT * FROM 记录集 WHERE ROWNUMX.QTY)第 14 页不足之处,敬请指正 QQ 77056803-SELECT CODE,QTY,RANK() OVER (ORDER BY QTY) ORD FROM A_TEST说明 SQL 中的排序是通过 UPDATE 更新,然后再显示出来,而 ORACLE 使用了 RANK OVER 函数,直接将数据集显示出来,而且 RANK OVER 函数还可以通过 PARTITION BY 对分组中的数据进行排序。32、SQL 与 ORACLE 的文件结构
26、SQL 文件被格式化为 8K 为单位的页,每 8 个相邻的页称为盘区(64K) ,若该盘区分配给一个对象,称为一致盘区,若分配给多个对象等为混合盘区,SQL 有全局分配页面、数据页面、索引页页、BLOB 页面、TEXT 页面。ORACLE 的文件最小逻辑单位是由 INIT.ORA 中的 BLOCK_SIZE 的值决定的,可以取 2K、4K、6K、8K、16K、32K 等,ORACLE 的盘区是由一些块组成的,ORACLE 的段是由盘区组成的,ORACLE 有数据段、索引段、回退段(UNDO 段) 、临时段、CLOB/BLOB 段、CLUSTER 段等。33、SQL 与 ORACLE 如何取得一
27、个全局唯一标识标(GUID)SELECT NEWID()-SELECT SYS_GUID() FROM DUAL34、本人有一张表单, 要求统计 col1col6中不等于 2 的列的个数,数据如下:ROW_ID | COL1 | COL2 | COL3 | COL4 | COL5 | COL6 |1 | 2 | 1 | 1 | 2 | 3 | 2 |2 | 1 | 1 | 2 | 2 | 2 | 2 |3 | 2 | 3 | 2 | 2 | 1 | 2 |4 | 2 | 2 | 2 | 2 | 1 | 2 |5 | 1 | 2 | 2 | 2 | 2 | 2 |6 | 2 | 2 | 2 |
28、2 | 2 | 1 |要求结果如下:ROW_ID | COUNT | 第 15 页不足之处,敬请指正 QQ 770568031 | 3 | 2 | 2 |3 | 2 |4 | 1 |5 | 1 |6 | 1 |SELECT ROW_ID,(6-(CASE WHEN COL1=2 THEN COL1 / 2 ELSE 0 END)-(CASE WHEN COL2=2 THEN COL2 / 2 ELSE 0 END)-(CASE WHEN COL3=2 THEN COL3 / 2 ELSE 0 END)-(CASE WHEN COL4=2 THEN COL4 / 2 ELSE 0 END)-(
29、CASE WHEN COL5=2 THEN COL5 / 2 ELSE 0 END)-(CASE WHEN COL6=2 THEN COL6 / 2 ELSE 0 END)AS COUNT FROM TABLE_A 说明 本例摘自 WWW.DELPHIBBS.COM,有名的 DELPHI 开发网站,本人不拥有版权。该SQL 的实现方法与 ORACLE 的实现写法完全一样,不在多述。35、有一客户表,数据如下:客户 日期 资金F001 2003-03-05 123.00F002 2003-03-04 1223.00F002 2003-03-02 1123.00F003 2003-03-05 12
30、31.00F003 2003-03-04 1232.00要求选出每个客户最新的哪条记录 组成一个结果集,结果如下:F001 2003-03-05 123.00F002 2003-03-04 1223.00F003 2003-03-05 1231.00实现方法:SELECT A.客户, B.日期, A.资金 FROM 客户资金表 A,(SELECT 客户, MAX(日期) 日期 FROM 客户资金表 GROUP BY 客户 ) BWHERE A.客户 = B.客户 AND A.日期 = B.日期说明 ORACLE 的写法与 SQL 一样,本例也摘自 WWW.DELPHIBBS.COM,本人不拥有
31、版权。36 现在看一个高难度的作业,后来解决办法和本例不同,请看需求。视图 1 CITYWATER_VIEW行政区划名称 城市用水量(亿 M3) 。 。 。北京市 15000 第 16 页不足之处,敬请指正 QQ 77056803上海市 9000 天津市 5400 重庆市 9500 表 1 DICTIONARY字段别名 字段全名区划 行政区划名称代码 行政区划代码城市用水 城市用水量(亿M3)表 1-2 是数据库 public 中的基表,表 3 是数据库 water 中的基表;在数据库 water 中创建视图 1,用 T-SQL 语句怎样实现?把查询结果的 “字段别名 ”修改为视图中的“字段
32、全名”,如果采用 T-SQL 中的常用修改列标题方式( SELECT column_name AS expression 或者SELECT expression= column_name ) ,很烦,每个基表里的字段太多,并且基表有近 200个,字段近 3000 个。说明:其实现在要作的就是将表 3 中的“代码“、 “城市用水”替代成表 1 中的行政区划代码、城市用户量(亿 M3)等。CREATE VIEW V_GODAS SELECT A.100000,B.310000,B.114011,B.114111,B.114421,B.114311,B.114321 FROM CODE A,FA01
33、P B WHERE A.200000=B.200000DECLARE CUR_COL CURSOR LOCAL FOR SELECT NAME FROM SYSCOLUMNS WHERE ID=OBJECT_ID(V_GOD)DECLARE COL VARCHAR(20),SQL VARCHAR(999),COL_TOTAL VARCHAR(8000),ALIAS VARCHAR(99),SOURCE VARCHAR(8000)OPEN CUR_COLFETCH CUR_COL INTO COLWHILE FETCH_STATUS=0BEGINSELECT ALIAS=字段名 FROM DIC
34、TIONARY WHERE 段码=COLIF COL_TOTAL IS NULL SELECT COL_TOTAL=ALIASELSESELECT COL_TOTAL=COL_TOTAL+,+ALIASFETCH CUR_COL INTO COLENDCLOSE CUR_COLSELECT SOURCE=RTRIM(TEXT) FROM SYSCOMMENTS WHERE ID=OBJECT_ID(V_GOD)SELECT SOURCE=RTRIM(SUBSTRING(SOURCE,CHARINDEX(AS,SOURCE),LEN(SOURCE)表 2 CODE区划 代码北京市 100000上
35、海市 200000天津市 300000表 3 CITYWATER代码 城市用水100000 15000200000 9000300000 5400第 17 页不足之处,敬请指正 QQ 77056803SELECT SOURCE=ALTER VIEW V_GOD(+COL_TOTAL+) +SOURCEEXEC(SOURCE)说明 由于该实例需要的表有两个已没有记录,所以大家只有看看 T-SQL 的语法及动态SQL 的编写,ORACLE 也类似。37、如何用 SQL 操作一段 XML 文件?CREATE PROCEDURE UP_XML_TEST(DOC VARCHAR(7999)ASBEGI
36、NDECLARE IDOC INTEXEC SP_XML_PREPAREDOCUMENT IDOC OUTPUT, DOCSELECT *FROM OPENXML (IDOC, /ROOT/DATASET/BOOKS,2)WITH(TITLE VARCHAR(32) TITLE,AUTHOR VARCHAR(20) AUTHOR,PRICE DECIMAL(9,2) PRICE)EXEC SP_XML_REMOVEDOCUMENT IDOCENDCREATE FUNCTION UF_XML_TEST(DOC VARCHAR(7999)RETURNS T TABLE(TITLE VARCHAR(
37、32),AUTHOR VARCHAR(20),PRICE DECIMAL(9,2)ASBEGINDECLARE IDOC INTEXEC SP_XML_PREPAREDOCUMENT IDOC OUTPUT, DOCINSERT INTO T SELECT *FROM OPENXML (IDOC, /ROOT/DATASET/BOOKS,2)WITH(TITLE VARCHAR(32) TITLE,AUTHOR VARCHAR(20) AUTHOR,PRICE DECIMAL(9,2) PRICE)EXEC SP_XML_REMOVEDOCUMENT IDOCRETURNENDDECLARE
38、DOC VARCHAR(7999)SELECT DOC=DELPHI第 18 页不足之处,敬请指正 QQ 77056803ABC38.00MIDASDEF26.00EXEC UP_XML_TEST DOC-SELECT * FROM DBO.UF_XML_TEST(DOC)说明 用过程可以方便地对 XML 进行操作,但编写成 FUNCTION 时就报错,大概 MS 的函数内部不充许执行 OPENXML 等这类行集函数。另一个重要的问题是,SQL 的这种语法竟然不支持汉字字串,真是要命。38、使用 DBMS_REPAIR 检测与修复破损的 BLOCK?ADMIN_TABLES 提供管理函数修复
39、或孤立关键表,包含创建、净化与删除函数。CHECK_OBJECT 检测并报告表或索引的破损块。DUMP_ORPHAN_KEYS 导出破损块的数据FIX_CORRUPT_BLOCKS 在 CHECK_OBJECT 检测出的破损块上做标记REBUILD_FREELISTS 重建对象的 FREELISTSSKIP_CORRUPT_BLOCKS 设置在表或索引扫描时是否不扫描被做了破损标记的块。SEGMENT_FIX_STATUS 整理 BITMAP 实体上的破损标志上表列举了 DBMS_REPAIR 包所有的过程,下边将对这些过程要引入的参数的枚举值进行说明,这引些参数将在过程应用中起决定作用。ob
40、ject_type TABLE_OBJECT, INDEX_OBJECT, CLUSTER_OBJECTaction CREATE_ACTION, DROP_ACTION, PURGE_ACTIONtable_type REPAIR_TABLE, ORPHAN_TABLEflags SKIP_FLAG, NOSKIP_FLAGSQL EXEC DBMS_REPAIR.ADMIN_TABLES(SCOTT.EMP,DBMS_REPAIR.REPAIR_TABLE,-DBMS_REPAIR.CREATE_ACTION,USERS);ORA-24129: 表名 SCOTT.EMP 没有以前缀 REP
41、AIR_ 开始SQL EXEC DBMS_REPAIR.ADMIN_TABLES(REPAIR_EMP,DBMS_REPAIR.REPAIR_TABLE,-第 19 页不足之处,敬请指正 QQ 77056803DBMS_REPAIR.CREATE_ACTION,USERS);SQL SELECT OBJECT_NAME FROM REPAIR_EMP;SQL EXEC DBMS_REPAIR.ADMIN_TABLES(ORPHAN_EMP,DBMS_REPAIR.ORPHAN_TABLE,-DBMS_REPAIR.CREATE_ACTION,USERS);SQL SELECT TABLE_N
42、AME FROM ORPHAN_EMP;ADMIN_TABLES 过程可以创建 DBMS_REPAIR 包的使用中需要的一些辅助表。SQL DECLAREM INTEGER;BEGINDBMS_REPAIR.CHECK_OBJECT(SCHEMA_NAME=SCOTT,OBJECT_NAME=EMP,REPAIR_TABLE_NAME =REPAIR_EMP,CORRUPT_COUNT=M);DBMS_OUTPUT.PUT_LINE(M);END;说明 统计 SCOTT 模式的 EMP 表有多少破损块。其它的过程本人就不再一一举例说明啦,引用方法类似与上边的实例,其它一些过程的参数列表可以通用
43、 SQLDESC DBMS_REPAIR 来查看。39、关于 UTL_FILE 包的使用方法使用 UTL_FILE 时有个地方要注意:INIT.ORA 文件中的 UTL_FILE_DIR 参数必须指定路径,即 UTL_FILE 包只有在 UTL_FILE_DIR 所指的目录中有权限读写,以下的实例表示本人已经修改 UTL_FILE_DIR=C:啦。SQLDESC UTL_FILE可以查看 UTL_FILE 包的所有类型与过程。例将表中数据输出到文件:CREATE OR REPLACE PROCEDURE UP_FILEW ISID NUMBER;NAME VARCHAR2(20);HANDLE
44、 UTL_FILE.FILE_TYPE;CURSOR REGION_CUR IS SELECT * FROM A_JOB;BEGINHANDLE :=UTL_FILE.FOPEN(C:,JOB.OUT,W);OPEN REGION_CUR;FETCH REGION_CUR INTO ID,NAME;WHILE REGION_CUR%FOUND LOOPUTL_FILE.PUTF(HANDLE,%S,%SN,ID,NAME);FETCH REGION_CUR INTO ID,NAME;END LOOP;CLOSE REGION_CUR;UTL_FILE.FFLUSH(HANDLE);UTL_FILE.FCLOSE(HANDLE);第 20 页不足之处,敬请指正 QQ 77056803END UP_FILEW;例将文件中数据写入到表中CREATE OR REPLACE PROCEDURE UP_FILER ISSTR VARCHAR(200);ID NUMBER;NAME VARCHAR2(20);HANDLE UTL_FILE.FILE_TYPE;POS NUMBER(6);BEGINHANDLE :=UTL_FILE.FOPEN(C:,JOB.OUT,R);UTL_FIL