проблема с codeigniter при использовании драйвера базы данных odbc - PullRequest
2 голосов
/ 27 апреля 2010

Я столкнулся с любопытной проблемой с драйвером odbc codeigniter.я подключаюсь с машины linux к машине MSSQL 2008, используя FreeTDS.

, в то время как я получаю, что функция 'num_rows' всегда возвращает -1, и это полностью проблема базы данных / драйвера - по какой-то причинея пытаюсь создать -> result (), происходит сбой всего приложения (ошибка 500, иногда просто пустая страница), если мне повезет, я получаю сообщение об ошибке, информирующее меня о том, что приложение умерло, поскольку оно попыталось выделить 2 террабайтапамяти (!).

Это происходит нерегулярно, то есть: каждые несколько обновлений.иногда он работает нормально, иногда страница возвращает ошибку 500, а иногда выдает ошибку выделения памяти - в любом случае это не совсем то, что может быть воспроизведено с помощью percision, а запросы СУПЕР просты.

кто-нибудь задумывается?

1 Ответ

6 голосов
/ 29 апреля 2010

Ха-ха, это случилось со мной тоже! И Я пожаловался на это разработчикам, и они проигнорировали меня .

Когда вы вызываете result (), он будет перебирать все возможные результаты и сохранять запись в массивном внутреннем массиве. Смотрите system/database/DB_result.php цикл while в конце result_object () и result_array ()

Есть три способа исправить это.

Простой способ:

LIMIT (или TOP в MSSQL ) ваши результаты в запросе SQL.

SELECT TOP(100) * FROM Table

ОБНОВЛЕНО небуферизованным способом:

Используйте функцию unbuffered_row(), которая была введена 2 года спустя после того, как был задан этот вопрос.

$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...
}

Сложный путь:

Используйте правильный объект результата, который использует итераторы PHP5 (что не нравится разработчикам, поскольку он исключает php4). Сделайте что-то подобное в вашем файле DB_result.php:

-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

Затем, чтобы использовать его, вместо вызова $query->result() вы используете только объект без ->result() на конце, как $query. И все внутреннее содержимое CI все еще работает с result().

$query = $this->db->query($sql);
foreach ($query as $record) { // not $query->result() because that loads everything into an internal array.
    // code...
}

Кстати, у моего кода Iterator, работающего с их кодом, есть некоторые логические проблемы со всем -1, так что не используйте одновременно $query->result() и $query для одного и того же объекта. Если кто-то хочет это исправить, вы великолепны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...