2010-05-04 61 views
3

我有一個Oracle全局臨時表「ON COMMIT DELETE ROWS」。從Oracle全局臨時表中選擇PHP的問題

我有一個循環,其中我:

  • 插入到全局臨時表
  • 從全局臨時表中選擇(後處理)
  • 提交,使表下一次迭代之前清除的循環

插入是通過調用oci_execute($ stmt,OCI_DEFAULT)完成的。通過調用oci_fetch_all($ stmt,$ result,0,-1,OCI_FETCHSTATEMENT_BY_ROW | OCI_ASSOC)來進行檢索。之後,提交:oci_commit()。

的問題是,檢索有時候工作,有時候我收到以下錯誤之一:

  • ORA-08103:對象不再存在
  • ORA-01410:無效的ROWID

就好像會話不能「查看」它先前插入的記錄一樣。

你有什麼想法可能導致這種情況?

謝謝。

回答

2

您使用連接池嗎?如果是這樣,那麼可能是不同的調用在單獨的會話中執行。

更好的解決方案是使單個PL/SQL過程填充臨時表並在單次調用中返回結果集。這意味着更好的解決方案:徹底廢除臨時表。

Oracle中很少有需要使用臨時表的情況。大多數東西都可以用純SQL解決,也可以批量收集到嵌套表中。在插入和隨後的選擇之間,您對臨時表中的數據進行了哪些實際操作?

編輯

臨時表有一個性能命中 - 行被寫入磁盤。 PL/SQL集合保留在(會話)內存中,所以速度更快。當然,因爲它們在會話內存中,它們不會解決連接池問題。

您是否需要將數據塊化,因爲您不想一次向您的PHP傳遞200,000行數據?如果我想進一步幫助你,我想我需要更多的背景。

+0

感謝您的出色反應。是的,我正在使用連接池,所以這可能確實是問題所在。實際上,在INSERT和SELECT之前不進行處理。處理本身是非常大且複雜的SELECT語句。 檢索到的數據最多可以有200 000條記錄 - 這是因爲我決定使用全局臨時表。將這些數據存儲在嵌套表中是否明智?或者從內存使用的角度來看,與Oracle的觀點沒有多大區別? – Dario 2010-05-04 13:22:43

+0

再次感謝。實際上,原始表格有數百萬條記錄。在循環的每次迭代中,我必須處理來自該表的大約200 000條記錄。我不想在原始表上使用我的複雜查詢,因此我將這些200k記錄提取到全局臨時表,以便在此塊上使用我的查詢。如果您建議,我可以將此塊存儲在嵌套表格中(通過BULK COLLECT收集)我只是擔心PGA內存使用情況。 – Dario 2010-05-04 14:21:38