codeigniter使用odbc数据库驱动程序的问题

时间:2010-04-27 04:40:45

标签: php sql-server codeigniter odbc

我遇到了codeigniter的odbc驱动程序的一个奇怪的问题。 我正在使用FreeTDS从Linux机器连接到MSSQL 2008机器。

虽然我得到'num_rows'函数总是返回-1,这完全是数据库/驱动程序问题 - 由于某种原因,当我尝试创建 - > result()时,整个应用程序崩溃(错误500 ,有时只是一个空白的页面),如果我很幸运,我收到一条错误消息,通知我应用程序死了,因为它试图分配2 TB的内存(!)。

这种情况不规律地发生,即:每次刷新。有时它运行正常,有时页面返回错误500,有时它会给出内存分配错误 - 在任何情况下,它都不是真正可以用percision再现的东西,并且查询非常简单。

任何人的想法?

1 个答案:

答案 0 :(得分:6)

哈哈,这也发生在我身上!关于它的开发者I've complained,以及他们ignored me

当你调用result()时,它将遍历每一个可能的结果,并将记录存储到一个庞大的内部数组中。请参阅result_object()和result_array()

末尾的system/database/DB_result.php while循环

有三种方法可以解决它。

简单方法:

LIMIT(或TOP in MSSQL)您在SQL查询中的结果。

SELECT TOP(100) * FROM Table

更新的无缓冲方式:

在询问此问题2年后,使用unbuffered_row() $query = $this->db->query($sql); // not $query->result() because that loads everything into an internal array. // and not $query->first_row() because it does the same thing (as of 2013-04-02) while ($record = $query->unbuffered_row('array')) { // code... } 函数。

-class CI_DB_result {
+class CI_DB_result implements Iterator {

    var $conn_id        = NULL;
    var $result_id      = NULL;
    var $result_array   = array();
    var $result_object  = array();
-   var $current_row    = 0;
+   var $current_row    = -1;
    var $num_rows       = 0;
    var $row_data       = NULL;
+   var $valid          = FALSE;


    /**
    function _fetch_assoc() { return array(); } 
    function _fetch_object() { return array(); }

+   /**
+    * Iterator implemented functions
+    * http://us2.php.net/manual/en/class.iterator.php
+    */
+   
+   /**
+    * Rewind the database back to the first record
+    *
+    */
+   function rewind()
+   {
+       if ($this->result_id !== FALSE AND $this->num_rows() != 0) {
+           $this->_data_seek(0);
+           $this->valid = TRUE;
+           $this->current_row = -1;
+       }
+   }
+   
+   /**
+    * Return the current row record.
+    *
+    */
+   function current()
+   {
+       if ($this->current_row == -1) {
+           $this->next();
+       }
+       return $this->row_data;
+   }
+   
+   /**
+    * The current row number from the result
+    *
+    */
+   function key()
+   {
+       return $this->current_row;
+   }
+   
+   /**
+    * Go to the next result.
+    *
+    */
+   function next()
+   {
+       $this->row_data = $this->_fetch_object();
+       if ($this->row_data) {
+           $this->current_row++;
+           if (!$this->valid)
+               $this->valid = TRUE;
+           return TRUE;
+       } else {
+           $this->valid = FALSE;
+           return FALSE;
+       }
+   }
+   
+   /**
+    * Is the current_row really a record?
+    *
+    */
+   function valid()
+   {
+       return $this->valid;
+   }
+   
 }
 // END DB_result class

困难的方式:

使用正确的结果对象,该对象使用PHP5迭代器(开发人员不喜欢,因为它排除了php4)。在DB_result.php文件中按下这样的东西:

$query->result()

然后使用它,而不是调用->result(),而不是像$query那样只使用不带result()的对象。并且所有内部CI内容仍适用于$query = $this->db->query($sql); foreach ($query as $record) { // not $query->result() because that loads everything into an internal array. // code... }

$query->result()

顺便说一句,我的Iterator代码使用他们的代码在整个-1事件上有一些逻辑问题,所以不要在同一个对象上同时使用$query和{{1}}。如果有人想解决这个问题,那你很棒。