208
Oracle8 和Oracle8i/9i 的Rowid 由四个部分组成,结构为: OOOOOOFFFBBBBBBRRR 格式为:
OOOOOO 代表数据对象号,它表示数据库段的编号; FFF 代表在表空间中的相对文件号;
BBBBBB 代表在一个文件中的块号,块号与数据文件有关,与表空间无关; RRR 代表块中行的位置号。
例1:查询记录中的ROWID 列的值: SQL> select * from emp; ENAME SAL DEPTNO TEL
-------------------- ---------- ---------- ------------- 赵元杰 9999.12 10 1360 136 5681 赵元杰 9999.12 10 1360 136 5681
例2:使用ROWID 删除重复的记录。由于记录每个列的值完全一样,where 条件无法辨别, 但是两条记录的ROWID 号是不一样的。所以可以用ROWID 作为条件。详细操作如下: 1)先查出记录:
SQL> select ename,sal,deptno,tel,rowid from emp; ENAME SAL DEPTNO TEL ROWID
------------ ---------- ---------- -------------------- ------------------ 赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAA 赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAB
2)看到两条记录的rowid 不一样,可以使用chartorowid 函数和rowid 值完成删除操作: SQL> delete from emp where rowid = chartorowid('AAAFyUAADAAAAADAAB');
已删除 1 行。
3)删除操作完成,再查看emp 表的数据:
SQL> select ename,sal,deptno,tel,rowid from emp; 209
ENAME SAL DEPTNO TEL ROWID
------------ ---------- ---------- -------------------- ------------------ 赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAA
从例子中可以看出,rowid 的优势,建议在PL/SQL 中的循环操作使用ROWID 来提高处理速度。 10.1.6 在查询中不让记录被更新
要保证在统计(查询)执行过程中,记录不被其他用户更新,则可以使用For update 子句进行加锁。这样在这个锁释放前其他用户不能对这些记录作update、delete 和加锁。 SQL>Select daptno from dept Where deptno=25 For update;
如果你使用了FOR UPDATE 来对表进行加锁,组必须用commit 来释放加锁的记录。 10.1.7 EXCEPTIONS(违反完整性)问题
前面介绍的主键的创建方法,如果我们对表创建了主键后,那么在查入记录时,Oracle 会自动对插入数据进行唯一性检查,当出现有数据违反唯一性限定的情况时,一般用户可能 只看到ORA-0001 Dup_val_on_index ( 试图破坏一个唯一性限制 ) 类似的提示,而没有看 是哪条记录违反唯一性限定。为了使用户有针对性地修改违反唯一性限定的记录,Oracle 提 供了一种方法可以容许用户捕获那些导致限定产生失败的行的信息。方法是: 用户生成一个列为 EXCEPTION 的表,创建该表的脚本是UTLEXCPT.SQL,你可以从 oracle.../rdbms/admin 目录中找。如:
SQL> start c:\\oracle\\ora81\\rdbms\\admin\%utlexcpt 表已创建。
在建表时声明 EXCEPTIONS。 激活 EXCEPTIONS,如:
Alter table newspaper enable primary key Exceptions into EXCEPTIONS; EXCEPTIONS 表有四个列: Row_ID 违反限定的各行 Ower 违反限定的拥有者 210
Table_name 违反限定所在的表 Constraint 行所在的限定 查看违反完整性的记录: Select * form Newspaper
Where Rowid in (select Row_id from EXCEPTIONS);
注:可能原版资料上将例外的表拼写成为 except_table ,其实脚本并不是这样。下面是原 版资料的例子: ALTER TABLE emp
ENABLE VALIDATE CONSTRAINT fk_deptno EXCEPTIONS INTO except_table; SELECT emp.*
FROM emp e, except_table ex WHERE e.row_id = ex.row_id AND ex.table_name = ’EMP’ AND ex.constraint = ’FK_DEPTNO’; 10.1.8 Not in 和Not Exists
一般来说,在处理存在性检查中,用户都会看到Not in 和Not Exists 两个判断语句, 但是它们在处理速度上有些不同。 Not in 速度慢
Not Exists 速度较快。 SQL>select name,depart,zip From export
Where name not in (select name from xxx not exists Item_application where ?) and rownum<6 Order by score; 10.1.9 关于 COPY 命令
可以弥补 create table ... as select ... from ...的和imp,exp 的不足,主要功能有: 1) 从一个本地数据库将一个或多个表拷贝到一个远程数据库; 2) 将一个表的一些记录拷贝到远程或本地库的其它表中; 3) 将包含 long 类型的表的一些列拷贝到其他表中; 4) 从一个oracle 数据库向一个非oracle 数据库的拷贝表。 211 语法如下:
COPY { FROM username[/password]@database | TO username[/password]@database | FROM username[/password]@database TO username[/password]@database } { APPEND|CREATE|INSERT|REPLACE }
destination_table[(col1,col2,...) ] USING query 参数说明:
APPEND 如果目标表已存在,将查询的记录插入该表中, 如果目标表不存在,则创建再插入所查询的记录。 CREATE 先创建目标表再插入所查询的记录, 如果目标表不存在,则提示错误。
INSERT 将查询(必须用 using query 查)的记录插入到目标表中, 如果目标表不存在,则提示错误。
REPLACE 将查询的记录替换到目标表中的内容, 如果目标表存在,则先删旧表内容再用拷贝表替换, 如果目标表不存在,则创建表。 使用copy 命令还需设置以下变量: SQL>set long n; /* 数据长度 */
SQL>set copycommit m;/* m 行提交一次 */ SQL>set arraysize n; /* 批操作的大小 */ 10.1.10 列值为NULL 情形的处理
对于编程人员来说,如果对列的空值(NULL)不注意而使处理结果不正确的情况还比
较多。这主要是由于数学上的问题引起的,数学的数字运算是:null + 数字 = null 。这样 的法则使我们在处理表中的列的值为空时会出现不正确的结果。请看下面操作: 例子:假设EMP 表有下面的记录: SQL> select * from emp; ENAME SAL DEPTNO TEL COMM
------------ ---------- ---------- -------------------- ---------- 赵元杰 9000 10 1360 136 5681 1000 张三 8898 10 123456 1200 李四 7000 10 654321