我遇到了codeigniter的odbc驱动程序的一个奇怪的问题。 我正在使用FreeTDS从Linux机器连接到MSSQL 2008机器。
虽然我得到'num_rows'函数总是返回-1,这完全是数据库/驱动程序问题 - 由于某种原因,当我尝试创建 - > result()时,整个应用程序崩溃(错误500 ,有时只是一个空白的页面),如果我很幸运,我收到一条错误消息,通知我应用程序死了,因为它试图分配2 TB的内存(!)。
这种情况不规律地发生,即:每次刷新。有时它运行正常,有时页面返回错误500,有时它会给出内存分配错误 - 在任何情况下,它都不是真正可以用percision再现的东西,并且查询非常简单。
任何人的想法?答案 0 :(得分:6)
当你调用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}}。如果有人想解决这个问题,那你很棒。