im using codeigniter 2.0.2 and this is from its userguide
$data = array(
'title' => $title,
'name' => $name,
'date' => $date
);
$this->db->where('id', $id);
$this->db->update('mytable', $data);
my question is once this executed how do you find its executed correctly or not?
The update function returns a value:
$result = $this->db->update('mytable', $data);
Check that value for either being TRUE (success) or FALSE (failure). update runs query internally and then returns the return value of query (Ref):
The query() function returns a database result object when "read" type queries are run, which you can use to show your results. When "write" type queries are run it simply returns TRUE or FALSE depending on success or failure.
Use
$this->db->affected_rows()
to see how many rows have been affected on write type queries (update, insert, etc...)
http://codeigniter.com/user_guide/database/helpers.html
Both answers was valid. You just have to use each one depending on the case. If you are just checking if the query was executed use this method:
$result = $this->db->update('mytable', $data);
if you really want the number of rows affected the second method is better:
$this->db->affected_rows()
however I always use the second method. The update query is a good example why. A query can be successful and still there was nothing updated on the database because the value that you were trying to update was actually equal to the value you are sending in the query.
This would be a false positive. And the affected rows would be 0.
I hope it helped =)
When developing CodeIgniter model methods, I find that I consistently return desirable values depending on the type of database write that is executed. It is often important to differentiate between a query that has run successfully versus a query that has actually changed a record.
For an update or delete query, I'll return the number of affected rows -- this will be most helpful to controller methods that call it. If you are performing logging (to keep track of change history), then ONLY log something if there is a change to the row; otherwise you are unnecessarily bloating your change history logs.
public function update(int $id, array $newData) :int
{
$oldData = $this->db->get_where('mytable', ['id' => $id])->row_array();
if ($this->db->update('mytable', $newData, ['id' => $id])) {
$affectedRows = $this->db->affected_rows();
if ($affectedRows) {
$this->Log->mytableUpdate($id, $newData, $oldData);
}
return $affectedRows;
}
return 0;
}
For insert queries, I always return the auto-incremented id of the newly inserted row via insert_id().
If using the PDO driver with PostgreSQL, or using the Interbase driver, this function requires a $name parameter, which specifies the appropriate sequence to check for the insert id.
public function insert(array $newData) :int
{
if ($this->db->insert('mytable', $newData)) {
$newId = $this->db->insert_id(); // or insert_id('mytable')
$this->Log->mytableInsert($newId, $newData);
return $newId;
}
return 0;
}
Having consistent return types in your model methods will make your project easier to develop and maintain. The script that calls these model methods will be able to quickly assess the outcome by making a "falsey" check.
Related
i have tried to update data of my database, but there is no error
this my method
public function update_pj_si(request $request)
{
$id = $request->id;
DB::table('tbl_profil_penyedia')
->where('id_profil_penyedia', $id)
->update(array('status' => 1));
return redirect('/verif/pj_si');
}
if i run this method, it run correctly and no error but the database is not updated.
how can i fix this?
The $id variable doesn't contain a value that exists in your table, tbl_profil_penyedia, for the field id_profil_penyedia. It is as simple as that.
You are trying to update a profil_penyedia that doesn't exist.
The update call returning 0, means it didn't update any rows, which means your where condition didn't yield any results to be updated.
I am new in PHP as well as in Codeigniter.
public function test_table()
{
$q = $this->db
->where('id',$id)
->get('table_name');
return $q->row();
}
// test_table() is a function written to models in codeigniter .
Can anyone please share me in details Why we are used return statement to insert or retrieve data in database ?
From the php manual:
If called from within a function, the return statement immediately ends execution of the current function, and returns its argument as the value of the function call
http://php.net/manual/en/function.return.php
That means the "return" statement will return the data to the parent method who called it.
The behavior of DB operations will depend on the frameworks/libraries you are using.
From the codeigniter manual:
insert([$table = ''[, $set = NULL[, $escape = NULL]]])
RETURNS: TRUE on success, FALSE on failure
https://www.codeigniter.com/userguide3/database/query_builder.html
When selecting, the "return" statement will return the row from the database or "false" if not found.
function getPerson(){
return \DB::table('user')->select('firstname as name', 'age');
}
function getPet(){
return \DB::table('pet')->select('petname as name', 'age');
}
function getNames($var){
return $var->select('name')->where('age', 10)->get();
}
$base = getNames(getPerson());//empty here
$base = getNames(getPet());//empty here
The main problem is I got a lot of different queries and I want to put aliases on them and then prepare data for diagram with another query. It is difficult if aliases diseappear.
Each query can have only one select(). $var being passed into getNames() is a query already has select() so adding more select() will override previous one.
Try remove select() from getNames() and test whether you get your result.
function getNames($var){
return $var->where('age', 10)->get();
}
Remember that you are using 'query builder' which means every query constraint you are adding is being added into the same query, not different one. The entire query will be actually built and executed once you try to get the result data set like calling get(), first(), etc.
I'm using Codeigniter transactions
$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->trans_complete();
This works fine , the problem I have is that inside the trans_start and trans_complete I'm calling other functions and those functions deals with database so they contains inserts and update and some deletes ... ex:
$this->db->trans_start();
$this->utils->insert_function($data);
$this->utils->update_function2($test);
$this->db->trans_complete();
Now if those functions are executed and some errors occur CodeIgniter won't do a rollback.
What is the best way to deal with such issue?
The only solution, I have in mind, is to return an error from those functions and inside those function add (trans_stat and trans_complete) And if it returns an error test an do $this->db->trans_rollback
ex:
$this->db->trans_start();
$result = $this->utils->insert_function($data);
if($result === false){
$this->db->trans_rollback();
}
$this->db->trans_complete();
Is there a better way of doing this?
Update 1:
As requested a sample of the external function i'm calling :
// insert_function contains
$rec = array(
'numero' => $numero,
'transaction_id' => $id,
'debit' => $product_taxes['amount_without_taxes'],
'date' => $data['date_transaction'],
);
$this->addExerciceAccountingRecords($rec);
and addExerciceAccountingRecords contains
function addExerciceAccountingRecords($records) {
$this->db->insert('transactions_exercices', $records);
}
Using transactions means support databases to insert data safely. So in Codeigniter we write every database related functions in the Model not in Controller.. And in your second code(which is not working)you have pointed model on there.(utils). So simple I'm sure this will not work. Because its not a insert data with model and Controller parallel. Transaction should be coded in the Model(I will write in Model in my answer).
Load this stuffs as well
Database Library
Model Class
URL helper
Session
Assumptions
In your code you have used $data and $test as array. So i assume there is two array for inserting and updating data.
Your data sets
$data = array(
'title' => 'My title' ,
'name' => 'My Name' ,
'date' => 'My date'
);
$id = 007;
$test = array(
'title' => $title,
'name' => $name,
'date' => $date
);
Your Code
$this->db->trans_start(); # Starting Transaction
$this->db->trans_strict(FALSE); # See Note 01. If you wish can remove as well
$this->db->insert('table_name', $data); # Inserting data
# Updating data
$this->db->where('id', $id);
$this->db->update('table_name', $test);
$this->db->trans_complete(); # Completing transaction
/*Optional*/
if ($this->db->trans_status() === FALSE) {
# Something went wrong.
$this->db->trans_rollback();
return FALSE;
}
else {
# Everything is Perfect.
# Committing data to the database.
$this->db->trans_commit();
return TRUE;
}
Notes
By default Codeigniter runs all transactions in Strict Mode. When
strict mode is enabled, if you are running multiple groups of transactions, if one group fails all groups will be rolled back. If
strict mode is disabled, each group is treated
independently, meaning a failure of one group will not affect
any others.
What I tried was more of a trick, but it worked for me.
$this->db->trans_begin();
$rst1= $this->utils->insert_function($data);
$rst2 = $this->utils->update_function2($test);
if($this->db->trans_status() === FALSE || !isset($rst1) || !isset($rst2)){
$this->db->trans_rollback();
}else{
$this->db->trans_commit();
}
I suspect the problem has to do with how CodeIgniter is handling objects.
If you go to the CI documentation under the section "Creating Libraries" at:
http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html
and look at the section related to:
$CI =& get_instance();
$CI->load->helper('url');
$CI->load->library('session');
$CI->config->item('base_url');
In your main controller, you have loaded/instantiated the database class either using auto load or explicitly loading the class.
You then go ahead and open the transaction, and then, you access your database
functions through your utils library.
However, once you use $this-db in your library, you are actually accessing another copy of the database instance, NOT the one that is associated with your transaction.
To access the same instance, you need to use the get_instance() function.
I think that should fix your problem. Your original coding style to separate function
into various modules is excellent. You simply need to understand this additional detail.
Please try and confirm that the roll back works as you expect.
The guts of the code consists of the following controller:
$this->db->trans_start();
$this->User_profile_m->create_new_user_profile();
$this->User_profile_m->create_new_user();
$this->db->trans_complete();
and a simple model user_profile_m to deal with data persistence:
function create_new_user()
{
$data['user_name_usr'] = $this->input->post('user_name');
$data['create_date_usr'] = NULL;
$this->db->insert('user_usr', $data);
}
function create_new_user_profile()
{
$data['user_name_pro'] = $this->input->post('user_name');
$data['user_description_pro'] = $this->input->post('user_description');
$data['create_date_pro'] = NULL;
$this->db->insert('user_profile_pro', $data);
}
Essentially, the demonstration tries to do two inserts (one in each of two tables).
If one insert fails, the other is rolled back.
I built this in CodeIgniter 2.1.3 and I can make the application files available through GitHub or zip them up and send them to you.
Try this procedure. It really work for me :)
$this->db->trans_start();
$this->utils->insert_function($data);
$this->utils->update_function2($test);
if($this->db->trans_status() === FALSE){
$this->db->trans_rollback();
}else{
$this->db->trans_complete();
}
Note: Make sure to use $this->db->trans_begin() when running manual transactions, NOT $this->db->trans_start().
$this -> db -> trans_begin();
$this -> utils -> insert_function ( $data );
$this -> utils -> update_function2 ( $test );
$this -> db -> trans_complete ();
Certify in case use MySql, use in InnoDb Format
For single insert or update record you can use affected_rows function
$this->db->insert('table_name', xss_clean($data));
//Check if there is a record affected
if($this->db->affected_rows() > 0)
{
return true;
}
else
{
// if not succeeded
// check your last query
die($this->db->last_query());
}
Okay, so I have been using a PDO wrapper for a project I'm working on, and I'm trying to find out whether a DELETE query was successful or not. Here is the code I am using:
/**
* A pretty straight-forward query to delete a row from the verification
* table where user_id is $user_id and code is $code
*/
$result = $this->database->query("DELETE FROM verification " .
"WHERE user_id = %u AND code = %s",
$user_id,
$code);
/**
* This function will grab the PDO's exec() return, which should
* return the number of rows modified.
*/
if($this->database->getNumAffected($result) > 0)
return true;
else
return false;
The problem is, whether the DELETE query actually deletes a row or not, $this->database->getNumAffected($result) always returns '0'.
You can check out the wrapper, but basically $this->database->getNumAffected($result) simply returns exactly the same value PDO::exec() would return.
I tried this code without the wrapper (directly into PDO,) and I had the same problem but reverse: it always returned '1' (whether a row was deleted or not.)
Any help would be greatly appreciated.
EDIT: Based on this SO question, I'm doing everything right... I don't understand why this isn't working.
$query = $this->database->prepare("DELETE FROM verification WHERE user_id = :user_id AND code = :code", array('user_id' => $user_id, 'code' => $code));
$query->execute();
if ($query->rowCount() > 0) {
return TRUE;
}
return FALSE;
It doesn't work as you expect because the 'wrapper' that you're using doesn't ever use PDO::exec() - it wraps everything in a PDO statement. According to a quick read of the source code for version 2.2.6 of the 'database' class from the URL you provided, the 'query' method should return an array which contains the statement handle:
502 $statement = $this -> getDatabaseConnection () -> prepare ( $query );
...
587 $ret = array ( $statement, func_get_args (), $lastIndex );
588
589 return ( $ret );
So, assuming your $this->database->query() is calling this database class' query method, you should be able to do $result[0]->rowCount().
Note that your assertion to the earlier response that "the wrapper that [you are] using uses a different version of rowCount() because of an error that exists with the rowCount() function" is not true - the wrapper implements a numRows, but this is not the same thing as PDOStatement::rowCount(), which is intact inside of the statement handle returned from database::query().