解決“ORA-01445: 無法從不帶保留關鍵字的表的聯結視圖中選擇 ROWID 或採樣”

來源:互聯網
上載者:User

今天排查一個分頁預存程序缺陷,發現錯誤ORA-01445: 無法從不帶保留關鍵字的表的聯結視圖中選擇 ROWID 或採樣。

開始納悶用了N年的分頁預存程序怎麼會有問題,後來發現關鍵問題在於該預存程序訪問的主要對象是張多表串連的視圖,預存程序需要使用ROWID偽列,而從視圖中讀取ROWID的限制是做關聯對應的欄位必須建立一個唯一索引。

經過檢查發現預存程序中涉及的視圖關聯使用的欄位建立唯一索引的位置在從表上(即“一多”對應的多),所以發生問題。

附上預存程序與使用(網路公開版,這裡使用的ROWNUM):

oracle分頁預存程序:<br />CREATE OR REPLACE PROCEDURE FGK.prc_page<br /> (p_tableName in varchar2, --表名<br /> p_strWhere in varchar2, --查詢條件<br /> p_orderColumn in varchar2, --排序的列<br /> p_orderStyle in varchar2, --排序方式<br /> p_curPage in out Number, --當前頁<br /> p_pageSize in out Number, --每頁顯示記錄條數<br /> p_totalRecords out Number, --總記錄數<br /> p_totalPages out Number, --總頁數<br /> v_cur out pkg_page.cur_page) --返回的結果集<br />IS<br /> v_sql VARCHAR2(3000) := ''; --sql語句<br /> v_startRecord Number(4); --開始顯示的記錄條數<br /> v_endRecord Number(4); --結束顯示的記錄條數<br />BEGIN<br /> --記錄中總記錄條數<br /> v_sql := 'SELECT TO_NUMBER(COUNT(*)) FROM ' || p_tableName || ' WHERE 1=1';<br /> IF p_strWhere IS NOT NULL or p_strWhere <> '' THEN<br /> v_sql := v_sql || p_strWhere;<br /> END IF;<br /> EXECUTE IMMEDIATE v_sql INTO p_totalRecords;</p><p> --驗證頁面記錄大小<br /> IF p_pageSize < 0 THEN<br /> p_pageSize := 0;<br /> END IF;</p><p> --根據頁大小計算總頁數<br /> IF MOD(p_totalRecords,p_pageSize) = 0 THEN<br /> p_totalPages := p_totalRecords / p_pageSize;<br /> ELSE<br /> p_totalPages := p_totalRecords / p_pageSize + 1;<br /> END IF;</p><p> --驗證頁號<br /> IF p_curPage < 1 THEN<br /> p_curPage := 1;<br /> END IF;<br /> IF p_curPage > p_totalPages THEN<br /> p_curPage := p_totalPages;<br /> END IF;</p><p> --實現分頁查詢<br /> v_startRecord := (p_curPage - 1) * p_pageSize + 1;<br /> v_endRecord := p_curPage * p_pageSize;<br /> v_sql := 'SELECT * FROM (SELECT A.*, rownum r FROM ' ||<br /> '(SELECT * FROM ' || p_tableName;<br /> IF p_strWhere IS NOT NULL or p_strWhere <> '' THEN<br /> v_sql := v_sql || ' WHERE 1=1' || p_strWhere;<br /> END IF;<br /> IF p_orderColumn IS NOT NULL or p_orderColumn <> '' THEN<br /> v_sql := v_sql || ' ORDER BY ' || p_orderColumn || ' ' || p_orderStyle;<br /> END IF;<br /> v_sql := v_sql || ') A WHERE rownum <= ' || v_endRecord || ') B WHERE r >= '<br /> || v_startRecord;<br /> DBMS_OUTPUT.put_line(v_sql);<br /> OPEN v_cur FOR v_sql;<br />END prc_page;<br />/<br />Model層代碼:</p><p> public class PageInfo<br /> {</p><p> // 定義<br /> private string p_tableName; //-表名<br /> private string p_strWhere; // --查詢條件<br /> private string p_orderColumn; // --排序的列<br /> private string p_orderStyle; // --排序方式<br /> private int p_curPage; //--當前頁<br /> private int p_pageSize; // --每頁顯示記錄條數<br /> private int p_totalRecords; // --總記錄數<br /> private int p_totalPages; // --總頁數</p><p> /// <summary><br /> /// 定義函數<br /> /// </summary><br /> public PageInfo() { }</p><p> /// <summary><br /> ///<br /> /// </summary><br /> /// <param name="fgmasterid"></param><br /> /// <param name="fgmastertile"></param><br /> public PageInfo(string p_tableName, string p_strWhere, string p_orderColumn, string p_orderStyle, int p_curPage, int p_pageSize, int p_totalRecords, int p_totalPages)<br /> {<br /> this.p_tableName = p_tableName;<br /> this.p_strWhere = p_strWhere;<br /> this.p_orderColumn = p_orderColumn;<br /> this.p_orderStyle = p_orderStyle;<br /> this.p_curPage = p_curPage;<br /> this.p_pageSize = p_pageSize;<br /> this.p_totalRecords = p_totalRecords;<br /> this.p_totalPages = p_totalPages;</p><p> }</p><p> /// <summary><br /> /// 查詢的表名<br /> /// </summary><br /> public string P_tableName<br /> {<br /> get { return p_tableName; }<br /> set { p_tableName = value; }<br /> }<br /> /// <summary><br /> /// 查詢條件<br /> /// </summary><br /> public string P_strWhere<br /> {<br /> get { return p_strWhere; }<br /> set { p_strWhere = value; }<br /> }<br /> /// <summary><br /> /// 排序的列<br /> /// </summary><br /> public string P_orderColumn<br /> {<br /> get { return p_orderColumn; }<br /> set { p_orderColumn = value; }<br /> }<br /> /// <summary><br /> /// 排序方式<br /> /// </summary><br /> public string P_orderStyle<br /> {<br /> get { return p_orderStyle; }<br /> set { p_orderStyle = value; }<br /> }<br /> /// <summary><br /> /// 當前頁<br /> /// </summary><br /> public int P_curPage<br /> {<br /> get { return p_curPage; }<br /> set { p_curPage = value; }<br /> }<br /> /// <summary><br /> /// 每頁顯示記錄條數<br /> /// </summary><br /> public int P_pageSize<br /> {<br /> get { return p_pageSize; }<br /> set { p_pageSize = value; }<br /> }<br /> /// <summary><br /> /// 總記錄數<br /> /// </summary><br /> public int P_totalRecords<br /> {<br /> get { return p_totalRecords; }<br /> set { p_totalRecords = value; }<br /> }<br /> /// <summary><br /> /// 總頁數<br /> /// </summary><br /> public int P_totalPages<br /> {<br /> get { return p_totalPages; }<br /> set { p_totalPages = value; }<br /> }<br /> }<br />

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.