I have a function in codeigniter that i want to use to update two tables. This is the code
if($loss_making_trade_amount > 5 && $loss_making_trade_amount < 20){
$user_data = array(
'trading_balance' => $trading_balance_float - 0.50
);
$data = array(
'trade_consequence' => '0.50',
'loss_in_amounts_cron_status' => 'seen'
);
$where = "id='$rid'";
$where_trading_balance = "email='$email'";
$this->db->where($where);
$this->db->set($data);
$this->db->update('mailbox_ke_01', $data);
//update users table at this level
$this->db->where($where_trading_balance);
$this->db->set($user_data);
$this->db->update('users', $user_data);
}
Will i be able to update the tables in the way i have done or will $this be pointing to the first table when updating the second table?.
Your code looks fine, once a query ran - you don't have to be worry about because the Query Builder resets itself after every query if it is finished - or dies in case of a DB Error.
You can take a closer look here
The documentation also clearly suggests that the query runs if the update function gets called.
$this->db->update() generates an update string and runs the query based on the data you supply.
For more information read the documentation here
The only thing i would change are your where clauses:
instead of
$where = "id='$rid'";
$this->db->where($where);
you should use the where function of the Querybuilder properly
$this->db->where("id", $rid);
The same applies for your $where_trading_balance
Related
I'm in a situation where I'm doing a MySQL query with Codeigniter and where I have a lot of fields value request which are ALL the same.
Example:
$this->db->query('SELECT * FROM abc WHERE user_id = ? AND msg_from = ? AND msg_to != ?', [$id, $id, $id]);
This has just 3 question marks but the query I'm working on is HUGE and has 19 question marks WHICH ARE ALL THE SAME variable.
So I was trying to figure out how to tell Codeigniter all question marks are pointing to the same variable without having to fill an array with 19 times the same variable.
I thought of a for-loop but I wanted to know if a shortcut exist.
you should be able to do this with Codeigniters Query Builder pretty easily
Something like that should work:
$this->db
->select('*')
->from('abc');
$arrFields = array('users_id', 'msg_from', 'msg_to');
foreach($arrFields AS $val)
{
$this->db->where($val, $id);
}
$query = $this->db->get();
I have a quite complex search method which handles the $input array from a controller, the thing is that I want to perform a custom SQL statement in the middle of it, for example:
$input['myField'] = array('condition' => 'rawStatement', value => 'AND WHERE LEFT(field,9) = 10`
and that would apply into my busy-conditions-method-builder
You can see the method at
http://pastebin.com/BNUKk2Xd
I'm trying to apply it on lines 52-54 but cant seem to get it working.
I know this is an old question but looking at your pastbin you have to chain your query like.
$query = User::join('user_personal','users.id','=','user_personal.user_id');
# Join user askings
$query = $query->leftJoin('user_askings','users.id','=','user_askings.user_id');
$query = ..........
$query = $query->orderBy('users.profile_score','DESC');
$query = $query->groupBy('users.id')->paginate(32);
return $query;
I want to optimized my query on codeigniter.
this query works but it seems, its take time to insert the result to my database table.
$this->db->select('client_id');
$this->db->from('event');
$query = $this->db->get();
foreach($query->result_array() as $row){
$client_id = $row['client_id'];
$data = array( 'event_id' => $event_id , 'client_id' => $client_id);
$this->db->insert('event_entry', $data);
}
I would like to know if theres a way it to optimized.
Instead of doing n number of inserts, doing just a single insert should improve execution time. You can achieve this in codeigniters active record by using insert_batch() .
$this->db->select('client_id');
$this->db->from('event');
$query = $this->db->get();
$data = array();
foreach($query->result_array() as $row){
$client_id = $row['client_id'];
array_push($data, array('event_id' => $event_id , 'client_id' => $client_id));
}
$this->db->insert_batch('event_entry', $data);
Produces:
INSERT INTO event_entry (event_id, client_id) VALUES ('event_id', 'client_id'), ('event_id', 'client_id'), ...
Replace all of that code with:
$this->db->query("
INSERT INTO event_entry (event_id, client_id)
SELECT ?, client_id
FROM event
", array($event_id));
And you will clearly notice the difference in execution time :) Plus in my opinion, having less code to worry about.
This query can't be run from Active Records, but it should be quite self explaining. Just like a normal SELECT, if fetches client_id and the already defined value $event_id by each event row. It then takes these values, and INSERT them into event_entry.
Note that ? and array($event_id) insert the value into the query escaped (and safe). Never insert into query as SELECT {$event_id}, client_id unless you know what you're doing.
Jeemusu's solution is indeed a nice way to do it through Active Records, but if it's performance you want all the way, one query is faster than two in this case.
you can use insert_batch command to insert data to database . Produce your data array with foreach loop and then use insert_batch database.http://ellislab.com/codeigniter/user-guide/database/active_record.html
please let me know if you need any help
In first function of my controller, I am fetching random records from mysql table using CI active record
$query = $this->db->query("SELECT DISTINCT * FROM questions WHERE `level` = '1' ORDER BY RAND() limit 0,5");
$result = $query->result_array();
and saving result in session as
// saving questions id in session
for($i = 0; $i < count($result); $i++)
{
$session['questionsId'][] = $result[$i]['qId'];
}
$this->session->set_userdata($session);
and if print session variable it shows output like:
$qIds_o = $this->session->userdata('questionsId');
var_debug($qIds_o);
Array
(
[0] => 5
[1] => 9
[2] => 3
[3] => 6
[4] => 11
)
but if I retrieve same session in another function of same controller it shows different result
$qIds = $this->session->userdata('questionsId');
var_debug($qIds);
Array
(
[0] => 2
[1] => 8
[2] => 6
[3] => 3
[4] => 5
)
and if I remove ORDER BY RAND() from mysql query like:
$this->db->query("SELECT DISTINCT * FROM questions WHERE `level` = '1' limit 0,5");
it shows same session array in both functions. Very strange.
Please guide what is going wrong....
Here is my controller script:
public function set_value(){
$query = $this->db->query("SELECT DISTINCT * FROM questions WHERE `level` = '1' ORDER BY RAND() limit 0,5");
$result = $query->result_array();
// saving questions id in session
for($i = 0; $i < count($result); $i++)
{
$session['questionsId'][] = $result[$i]['qId'];
}
$this->session->set_userdata($session);
$qIds_o = $this->session->userdata('questionsId');
var_debug($qIds_o);
}
public function get_value(){
$qIds = $this->session->userdata('questionsId');
var_debug($qIds);
}
I called set_value() on page load while once the page loaded I call get_value() using AJAX post which simply hits my_controller/get_value/ and response back to browser.
Without looking at your controller (let's call it my_controller in detail, I think what might be happening is:
(1) You call the first function, my_controller/set_value where set_value sets the session variable and you echo the result.
(2) You then call the second function, show_value that simply echos out the session variable.
What you might be doing in set_value is:
1) echo out the current session variable
2) call the query and re-set the session variable
If this is the case, then when you go to show_value (2nd function) you are looking at the recently re-set value instead of the prior value that you echoed out in the first function.
I have two questions about this sentence:
but if I retrieve same session in another function of same controller it shows different result
Is this on a new page load?
If so, is the query run again?
I'm going to assume the answer to both of these questions is yes, since you said removing RAND() gives you the same results.
You are using a combination of RAND() and LIMIT in your query, meaning you want only five rows in a random order. That means that each time the query is run (and your session data is set), it is very likely that the results will be different.
I don't know exactly what you're doing with these IDs and what sort of data set you need, so this may not be 100% perfect for your solution, but if you only need to set this session data once, you should check if it exists before running the query.
if ($this->session->userdata('questionsId') === FALSE)
{
// Run your query and set your session data here.
// Note that in CI 3.0, Session::userdata()
// will return NULL if empty, not a boolean.
}
I'm using codeigniter and the pagination class. This is such a basic question, but I need to make sure I'm not missing something. In order to get the config items necessary to paginate results getting them from a MySQL database it's basically necessary to run the query twice is that right?
In other words, you have to run the query to determine the total number of records before you can paginate. So I'm doing it like:
Do this query to get number of results
$this->db->where('something', $something);
$query = $this->db->get('the_table_name');
$num_rows = $query->num_rows();
Then I'll have to do it again to get the results with the limit and offset. Something like:
$this->db->where('something', $something);
$this->db->limit($limit, $offset);
$query = $this->db->get('the_table_name');
if($query->num_rows()){
foreach($query->result_array() as $row){
## get the results here
}
}
I just wonder if I'm actually doing this right in that the query always needs to be run twice? The queries I'm using are much more complex than what is shown above.
Unfortunately, in order to paginate you must know how many elements you are breaking up into pages.
You could always cache the result for the total number of elements if it is too computationally expensive.
Yeah, you have to run two queries, but $this->db->count_all('table_name'); is one & line much cleaner.
Pagination requires reading a record set twice:
Once to read the whole set so that it can count the total number records
Then to read a window of records to display
Here's an example I used for a project. The 'banner' table has a list of banners, which I want to show on a paginated screen:
Using a public class property to store the total records (public $total_records)
Using a private function to build the query (that is common for both activities). The parameter ($isCount) we pass to this function reduces the amount of data the query generate, because for the row count we only need one field but when we read the data window we need all required fields.
The get_list() function first calls the database to find the total and stores it in $total_records and then reads a data window to return to the caller.
Remember we cannot access $total_records without first calling the get_list() method !
class Banner_model extends CI_Model {
public $total_records; //holds total records for get_list()
public function get_list($count = 10, $start = 0) {
$this->build_query();
$query = $this->db->get();
$result = $query->result();
$this->total_records = count($result); //store the count
$this->build_query();
$this->db->limit($count, $start);
$query = $this->db->get();
$result = $query->result();
return $result;
}
private function build_query($isCount = FALSE) {
$this->db->select('*, b.id as banner_id, b.status as banner_status');
if ($isCount) {
$this->db->select('b.id');
}
$this->db->from('banner b');
$this->db->join('company c', 'c.id = b.company_id');
$this->db->order_by("b.id", "desc"); //latest ones first
}
And now from the controller we call:
$data['banner_list'] = $this->banner_model->get_list();
$config['total_rows'] = $this->banner_model->total_records;
Things get complicated when you start using JOINs, like in my example where you want to show banners from a particular company! You may read my blog post on this issue further:
http://www.azmeer.info/pagination-hitting-the-database-twise/