Posted on 2008-08-17 14:26
flustar 閱讀(2836)
評論(1) 編輯 收藏 所屬分類:
Oracle
在做音視頻網(wǎng)站審核的時(shí)候,發(fā)現(xiàn)分頁出現(xiàn)了重復(fù)記錄。原以為是自己程序出了問題,可仔細(xì)檢查了程序之后,并沒有發(fā)現(xiàn)有什么不對的地方,于是上網(wǎng)查了一下,原來是oracle
分頁機(jī)制的問題,在oracle中,分頁是通過rownum函數(shù)來實(shí)現(xiàn)的,
rownum順序號的生成是排序后生成的,例如下面這條sql:
select * from user where rownum <= 20 and rownum > 10 order by userName
按照我們正常的理解,這條sql查詢的是user表中按照userName升序后取其10~20條記錄,
其實(shí)不然,oracle是排序后才生成rownum,理想情況下如userName在user表的值是唯一
的或者userName在數(shù)據(jù)庫中被建了唯一索引,結(jié)果是正確的,但是如果userName的值存在
大量重復(fù)記錄或者為空,就會出現(xiàn)問題重復(fù)記錄的情況。正確的sql應(yīng)該這樣寫:
select * from (select * from (select * from user order by userName)
where rownum <= 20) where rownum >=10
但是這并不能從根本上解決問題,為了避免這種情況,建議慎用oracle的排序功能,
如果需要使用排序,一定要選擇那些建有唯一索引的字段。當(dāng)然有時(shí)候我們可能需要對
那些不是唯一索引的字段進(jìn)行排序,這些字段的值可能大量重復(fù)也可能為空,怎么辦,
這時(shí)候可以采用聯(lián)合字段排序,也就是排序字段中包含一個(gè)主鍵或不會重復(fù)的字段。