时间:2021-10-13 09:09:58 | 栏目:Oracle | 点击:次
记一次 开发中遇到的坑:
第一种情况 rowid
select * from table where rowid=(select max(rowid) from table )
这种方式是取最大的rowid作为最新的数据,但是有一个隐患 :数据库一旦有删除操作,rowid不能保证每次都是递增的!即max(rowid)并不一定就是最新的数据,尽管可能不会每次复现 但这个问题是绝对存在的!
第二种情况 使用rownum (或相同思路)
select t.* from (select ti.sysno,ti.cr_date from t_insurance ti order by ti.selldatetime desc ) t where rownum = 1
这有很大一个问题,如果排序字段数据库使用的是date类型,而且存在时分秒刚好相同的数据(尤其高并发项目中),我们子查询语句中 的确可以准确的 order by desc出来,但是一旦外层套了一层select ,查出来的很可能就不是子查询里面的第一条数据,详细如图:
11:35:25存在两条数据 执行选中的查询sql,
但是 当我们加了一层select,可以看到 已经不是上面的第一条数据了
类似的,不管怎么写的花里胡哨,如下sql,子查询里面 row_row = 1时,sysno确实为3126 1018 0001 5Z14,但是外面套了一层select 结果也变了
select * from (select t.sysno, t.cr_date, row_number() over(order by t.cr_date desc) row_row from t_insurance t) where row_row = 1
同理 用with temp as 也是一样的情况,取不到最新的结果。
解决方法:
暂时没有从写什么高级的sql语句层面想到好的办法,(如果有大佬有好的方法,希望可以指点一二)
提供一些思路:如果项目没有上生产 或者说是小项目,那还可以追加自增列,或者数据库使用时间戳类型,但是上了生产 改动数据库是大忌。
一般的,数据表中还会有其它的字段可以作为辅助排序,例如一段时间内的单号是递增的 那么可以多个字段排序 例如 order by date desc,orderNo desc ,(我是通过这种方式解决的,但还是不治根 万一哪天遇到数据库没其他辅助排序字段 问题还是得不到解决)
实在不行 就根据实际业务 看看能不能对时间加限制(如果数据量不大 不加也罢),select * from table where date >=xxxx order by desc date ,然后把一堆数据查询出来,在代码里面list.get(0)取出第一条数据。