java 操作oracle查询条件为时间类型_oracle伪列

@[toc]

Oracle有两个常用的伪列rowid和rownum,对伪列的操作类似于表中的列,你可以对其进行查询操作,但是你却不能对其进行增加、修改或者是删除。

一、rowid伪列

1、rowid的原理

Oracle数据库表中的每一行在数据库中有一个存放的位置,即rowid(row identification),rowid的长度是10个字节,显示的结果是18字节的字符串,该值表明了行在Oracle数据库中存放的物理具体位置,是唯一的,Oracle内部通常使用它来访问数据。

我们从超女表中查询每行的rowid。

61011d6c4f62b3a4d4042cae47b23db9.png

rowid虽然不是表的字段,但是,在Oracle数据库的内部,保存了每行数据的rowid。

rowid使用base64编码行的物理地址,编码字符包含A-Z, a-z, 0-9, +, 和/,由四部分组成:OOOOOOOFFFBBBBBBRRR,如下图:

096a58df727e1ac0b4385daa6271e1be.png

1)对象编号:行所属数据库对象的编号,每个数据库对象在创建的时候都被分配一个唯一的编号,六位显示。

2)文件编号:行所在数据文件的编号,每一个文件标号也是唯一的,三位显示。

3)块编号:行所在数据文件的数据块的位置,六位显示。

4)行编号:行目录中的具体位置,三位显示。

Oracle正是根据rowid可以准确的定位存放行数据的物理位置。

2、rowid数据类型

在Oracle数据库中,用rowid数据类型存放rowid的值,长度是10个字节,为了方便查看和书写,Oracle可以把10字节的rowid类型和18字节的字符串自动转换。

对程序员来说,把rowid当成18字节的字符串就行了。

e9433533a3daa69b2fb1e8b2a83321a5.png

二、rowid的应用

我以一个程序员的视角来向大家介绍rowid的应用场景。

1、记录表数据的变化

例如我希望把超女基本信息表T_GIRL的操作日志(增加、修改和删除)记录下来。

1)创建一个SQL日志表

create table T_SQL_LOG
(
  tname    varchar2(30),        -- 原表的表名。
  srcrowid rowid,               -- 原表rowid。
  sqltype  number(1),           -- SQL语句的类型:1-insert、2-update、3-delete。
  crttime  date default sysdate -- 操作时间。
);

2)在原表中创建触发器

在超女基本信息表T_GIRL上创建触发器。

create or replace trigger TR_GIRL_LOG
       after insert or update or delete
       on T_GIRL for each row
begin
  if inserting then
    insert into T_SQL_LOG(tname,srcrowid,sqltype) values('T_GIRL',:new.rowid,1);
  end if;
  if updating then
    insert into T_SQL_LOG(tname,srcrowid,sqltype) values('T_GIRL',:new.rowid,2);
  end if;
  if deleting then
    insert into T_SQL_LOG(tname,srcrowid,sqltype) values('T_GIRL',:old.rowid,3);
  end if;
end;

3)测试效果

如果对T_GIRL表插入了四条记录,在T_SQL_LOG中记录的内容如下:

b57e5919c6781e6c1cfab08a322ec9ee.png

4)应用经验

T_SQL_LOG日志表中可以找到原表数据变化的情况,这种处理技巧在数据审计和数据同步中经常用到。

2、用于where的条件

rowid是记录了数据存放的物理位置,用rowid作为where的条件的效率永远是最高的,远远超过任何索引,利用这个特点可以提高数据操作的效率。

3、rowid的缺点

rowid的效率虽然很高,在实际开发中经常用到,但也有缺点,主要有两方面:

1)兼容性不好,rowid是Oracle数据库特有的,其它数据库没有,如果你的应用程序需要迁移到其它数据库,就不能用rowid了。

2)rowid记录的是数据存放的物理位置,这个值在数据整理、数据迁移和数据备份的时候会变化。

三、rownum伪列

首先,rowid和rownum都是oracle的伪列,但原理和用法完全不同,没有任何关联和可比性,不要用学习rowid的经验来学习rownum。

rownum(row number)是Oralce为查询结果集的行分配的顺序号,例如:

cc26ae20d6de734ce2df94ca07de30d3.png

e7dd43a3c3f4d2ed583b447dad111e15.png

再说一次,rownum很简单,就是Oralce为查询结果集的行分配的顺序号。

rownum在数据库中没有存储空间,从以上的两个查询可以看出,在第一个查询结果中,妲已的rownum是3,在第二个查询结果集中,妲已的rownum是1。

如果你还不明白,我再解释一次,rownum是Oralce为查询结果集的行分配的顺序号。

四、rownum的应用

1、限制数据库大事务和长事务

用delete删除表中数据的时候,如果数据记录比较多,会产生大事务和长事务,为了避免对数据库的冲击,可以用rownum限制每次delete数据的记录数。

delete from 表名 where 待删除数据的条件 and rownum<=100000 ;

以上delete语句一次删除100000条记录,这种用法适用于update语句。

2、用于筛选查询结果集的记录

筛选查询结果集的记录的用法对C/C++程序员意义不大,但对java程序员来说非常重要,主要用于查询结果的分页,各位有兴趣可以看一下。

1)rownum 对于等于某值的查询条件

如果希望找到超女表中第一条超女的信息,可以使用rownum=1作为条件。但是想找到超女表中第二条超女的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。

select rownum,id,name from T_GIRL where rownum=1; --有记录
select rownum,id,name from T_GIRL where rownum=2; --无记录

24778721816c714fe6c719dc40e78d92.png

2)rownum对于大于某值的查询条件

如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,可以使用以下的子查询方法来解决。注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。

select * from (select rownum no,id,name from T_GIRL) where no>2;      -- 有记录
select * from (select rownum   ,id,name from T_GIRL) where rownum>2;  -- 无记录

3981b5938d2c0f06d5c04d83cd95b075.png

3)rownum对于小于某值的查询条件

如果想找到第三条记录以前的记录,当使用rownum<3是能得到两条记录的。显然rownum对于rownum1的自然数)的条件认为是成立的,所以可以找到记录。

select rownum,id,name from T_GIRL where rownum<3; -- 有记录

39915e67da879645e1277644246d2cba.png

4)rownum排序

Oracle中的rownum的是在从数据库中取数据的时候产生的序号,所以想对指定排序的数据去指定的rowmun行数据就必须注意了。

select rownum,id,name from T_GIRL order by name;

7a282846286d54ed72c36794f6a87118.png

可以看出,rownum并不是按照name列来生成的序号。系统是按照记录从数据库取出的顺序给记录排的号,为了解决这个问题,必须使用子查询。

select rownum,id,name from (select * from T_GIRL order by name);

73250db49cf5da79e8c5ed3699c628b7.png

五、小结

rownum和rowid都是伪列,但两者的原理是不同的,rownum是根据SQL查询出来的结果给每行分配一个临时编号,不同的SQL会导致rownum不同。rowid是物理存在的,在每条记录insert到数据库时,就会有一个唯一的物理位置,记录了在数据库中的位置ID,只要记录没被搬动过,rowid是不变的。

rownum常用于分页查询,rowid常用于提高数据操作的效率,在某些场景中,还会把rowid当成主建来使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值