[英]How do I call Codeigniters 2 Active record to get 2 sets of results from the same query?
我本质上是在为文件导出创建分块功能,并且我已经在其中建立了select-> from->。 我希望每次可以使用不同的限制/偏移值两次调用“ get”。
这是基本概念的演练。
// BallReport.php
function ProcessData(){
//Report 1
$query = createSelectQuery();
$query = applyReportOneWhereValues($query);
$results1 = CSVTool::processLargeDataSet($query, 10, 1000);
//Report 2
$query = createSelectQuery();
$query = applyReportTwoWhereValues($query);
$results2 = CSVTool::processLargeDataSet($query, 10, 1000);
}
function createSelectQuery(){
// the select is complicated having multiple joins and sub queries
// so I only want to have to write this once
$query = $this->db->select('ball.name,
color.name,
size.name,
shape.name')
->from('ball')
->join('color', 'ball.color_id = color.id')
->join('size', 'ball.size_id = size.id')
->join('shape', 'ball.shape_id = shape.id');
return $query;
}
function applyReportOneWhereValues($query){
// I have 2 different sets of where parameters
// But they are both using the same select
// so I separated them into these functions
// So I can apply the set of where statements
// all at once
$query = $query->where("table.color", "blue")
->where("table.size" , "large")
->where("table.shape", "round");
return $query;
}
function applyReportTwoWhereValues($query){
$query = $query->where("table.color", "red")
->where("table.size" , "small")
->where("table.shape", "round");
return $query;
}
//In CSVTool.php
public static function processLargeDataSet($query, $numberOfPages, $chunkSize){
// Since the data set is going to be so large we want to process in chunks
// So that we don't hit the limit and break mid way.
// To do that we only call the DB in sets of 1000 rows
for(int $i = 0; $i <= $numberOfPages: $i++){
processRows($query, $i * $chunkSize, $chunkSize);
}
}
function processRows($query, $offset, $limit){
// We limit in here so each time it's called we change the offset and limit
$query = $query->offset($offset)->limit($limit);
$valuesToProcess = $query->get()->result_array();
// process the rows here
}
这当然是行不通的,因为一旦processRows第一次调用$ query-> get(),所有后续调用都将引发Query error: No tables used
有什么解决办法吗? 我没有意识到Codeigniter 2中的分块功能吗?
我认为您正在寻找的是“活动记录缓存”。 可以从几个不同的地方进行管理。 在这个答案中,它在ProcessData()
注意:您正在为相同的var $query
分配很多东西,并且在没有充分理由的情况下将其大量传递。 而且,您经常连续多次用完全相同的值覆盖$query
。 我在您使用$query
大多数地方都使用过$this->db
。
public function ProcessData()
{
//Report 1
$this->db->start_cache();
//createSelectQuery(); not needed if you want all fields from one table
applyReportOneWhereValues();
$this->db->stop_cache();
processLargeDataSet(10, 1000);
//Report 2
$this->db->flush_cache()
$this->db->start_cache();
//createSelectQuery(); not needed if you want all fields from one table
applyReportTwoWhereValues();
$this->db->stop_cache();
processLargeDataSet(10, 1000);
$this->db->flush_cache();
}
您的问题使用select("*")
和from("table_name")
,如果您确实希望从一个表中获取所有字段,可以将其删除。 当使用get("table_name")
且没有select()
调用时,则假定所有字段。 IOW,查询语句为SELECT * FROM 'table_name';
根据问题的代码,您似乎不需要createSelectQuery()
函数。
您的“应用在哪里”功能起作用,但使用方法链重写。
public function applyReportOneWhereValues()
{
$this->db
->where("table.color", "blue")
->where("table.size", "large")
->where("table.shape", "round");
}
public function applyReportTwoWhereValues()
{
$this->db
->where("table.color", "red")
->where("table.size", "small")
->where("table.shape", "round");
}
我消除了processRows()
并将该逻辑合并到processLargeDataSet()
。 注意get()
的用法-传递表名,限制和偏移量-消除了对select()
, from()
, limit()
和offset()
调用的需要。
/**
* Process the records in chunks
* @param int $numberOfPages The number of pages to create in the set (1 to n)
* @param int $pageSize The number of records per page
*/
function processLargeDataSet($numberOfPages, $pageSize)
{
if($numberOfPages < 1)
{
$numberOfPages = 1;
}
for($i = 1; $i < $numberOfPages; $i++)
{
$valuesToProcess = $this->db
->get('table', $pageSize, ($i-1) * $pageSize)
->result_array();
// process the rows in $valuesToProcess
}
}
这是对修订后的问题的新答案。
public function ProcessData()
{
//Report 1
$query_builder = $this->applyReportOneWhereValues($this->createSelectQuery());
$this->db->stop_cache();
$results1 = CSVTool::processLargeDataSet($query_builder, 10, 1000);
$this->db->flush_cache();
//Report 2
$query_builder = $this->applyReportTwoWhereValues($this->createSelectQuery());
$this->db->stop_cache();
$results2 = CSVTool::processLargeDataSet($query_builder, 10, 1000);
$this->db->flush_cache(); //just to be safe
}
public function createSelectQuery()
{
$this->db->start_cache();
return $this->db->select('ball.name, color.name, size.name, shape.name')
->join('color', 'ball.color_id = color.id')
->join('size', 'ball.size_id = size.id')
->join('shape', 'ball.shape_id = shape.id');
}
public function applyReportOneWhereValues($query_builder)
{
return $query_builder
->where("table.color", "blue")
->where("table.size", "large")
->where("table.shape", "round");
}
public function applyReportTwoWhereValues($query_builder)
{
return $query_builder
->where("table.color", "red")
->where("table.size", "small")
->where("table.shape", "round");
}
在CSVTool.php中
/**
* Process the records in chunks
* @param CI_DB_query_builder $qb An instance of the CI_DB_query_builder class
* @param int $numberOfPages The number of pages to create in the set (1 to n)
* @param int $pageSize The number of records per page
*/
public static function processLargeDataSet($qb, $numberOfPages, $pageSize)
{
if($numberOfPages < 1)
{
$numberOfPages = 1;
}
for($i = 1; $i < $numberOfPages; $i++)
{
$valuesToProcess = $qb
->get('ball', $pageSize, $i - 1 * $pageSize)
->result_array();
// process the rows in $valuesToProcess
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.