Oracle数据库的表中的每一行数据都有一个唯一的标识符,或者称为rowid,在Oracle内部通常就是使用它来访问数据的。
rowid需要 10个字节的存储空间,并用18个字符来显示。该值表明了该行在Oracle数据库中的物理具体位置。可以在一个查询中使用rowid来表明查询结果中包含该值。
Oracle的物理扩展rowid有18位,每位采用64位编码,分别用A~Z、a~z、0~9、+、/共64个字符表示。
例如:
select rowid,empno from scott.emp;
ROWID EMPNO
------------------ ----------
AAAR3sAAEAAAACXAAA 7369
AAAR3sAAEAAAACXAAB 7499
AAAR3sAAEAAAACXAAC 7521
AAAR3sAAEAAAACXAAD 7566
AAAR3sAAEAAAACXAAE 7654
AAAR3sAAEAAAACXAAF 7698
AAAR3sAAEAAAACXAAG 7782
AAAR3sAAEAAAACXAAH 7788
AAAR3sAAEAAAACXAAI 7839
AAAR3sAAEAAAACXAAJ 7844
AAAR3sAAEAAAACXAAK 7876
AAAR3sAAEAAAACXAAL 7900
AAAR3sAAEAAAACXAAM 7902
AAAR3sAAEAAAACXAAN 7934
已选择14行。
这里的AAAR3s是数据库对象编号,AAE是文件标号,AAAACX是块编号,最后三位(empno = 7934时为AAN)是行编号。
通过dbms_rowid包,可以直接得到具体的rowid包含的信息:
select
dbms_rowid.rowid_object(rowid) object_id,
dbms_rowid.rowid_relative_fno(rowid) file_id,
dbms_rowid.rowid_block_number(rowid) block_id,
dbms_rowid.rowid_row_number(rowid) row_number
from emp;
OBJECT_ID FILE_ID BLOCK_ID ROW_NUMBER
---------- ---------- ---------- ----------
73196 4 151 0
73196 4 151 1
73196 4 151 2
73196 4 151 3
73196 4 151 4
73196 4 151 5
73196 4 151 6
73196 4 151 7
73196 4 151 8
73196 4 151 9
73196 4 151 10
73196 4 151 11
73196 4 151 12
73196 4 151 13
已选择14行。
如何去掉重复记录?
一个表中上万条记录,由于没设置主键、唯一键,表中掺杂了一个相同的记录。
如何找到它们呢?如何删除掉它们呢?
表T(ID、NAME、AGE)
存在ID、NAME、AGE重复的记录。
如何查找表中多余的重复记录?
这个SQL可以利用group by having 来处理
select * from t
where (id, name, age) in
(select id, name, age
from t
group by id, name, age
having count(*) > 1);
如何要删除这些重复的记录?
这就需要用到rowid,rowid在数据库中可以唯一标识一条记录。删除时可保留最大的rowid或者最小的rowid所对应的记录即可。
delete from t
where (t.id, t.age, t.name) in
(select id, age, name
from t
group by id, age,name
having count(*) >1)
and rowid not in
(select min(rowid)
from t
group by id, age,name
having count(*) > 1);
个人认为写成exists比较好理解:
delete from t
where exists
(select t1.rowid
from t t1,
(select id,age,name,min(rowid) rid
from t
group by id,age,name
having count(*) >1 ) b
where t1.id = b.id
and t1.age = b.age
and t1.name = b.name
and t1.rowid != b.rid
and t1.rowid = t.rowid);