I have a function which allow me to delete a row on a table. But the problem is that, for database integrity, I have to delete another row on another table that is in relation with the record I want to delete. This is my function :
public function delete($tab)
{
$this->db->where('id', $tab['id']);
$this->db->delete('agent', $tab);
// Here the query is "DELETE from agent WHERE id = $tab['id']"
$this->db->where('id_agent', $tab['id']);
$this->db->delete('agent_vendeuse', $tab);
// Here the query gives "Delete from agent_vendeuse WHERE id_agent= $tab['id'] AND id=$tab['id'];" Which is where the error comes from
}
I have an error database error on my function :
DELETE FROM `agent_vendeuse` WHERE `id_agent` = '2' AND `id` = '2'
Which means that after I affected the new index 'id_agent' for the where clause, the previous one 'id' is still in cache.
The $tab variable is coming from $_POST of my form. I just changed its name in function.
I guess I have to clean the cache after the first deletion but how to write it ?
The second parameter of the delete function is a where clause, so I'm guessing that probably what happens is that the line $this->db->where('id', $tab['id']); gets ignored on the first delete() call, and for some reason on the second delete() call the 'where clause' you're defining in the parameter as $tab gets ignored and the two where() calls gets used instead.
Just remove the $tab from the parameters passed to delete() and you should be ok:
public function delete($tab)
{
$this->db->where('id', $tab['id']);
$this->db->delete('agent');
$this->db->where('id_agent', $tab['id']);
$this->db->delete('agent_vendeuse');
}
Related
I wanted to let the system to show error message when detect duplicated entry of full_name column without applying unique in the full_name column from public function rules() in model.
My code is like this :
if ($model->load(Yii::$app->request->post()) ) {
$model->full_name = $model->first_name .'' . $model->last_name ;
$name = StudentInfo::find()->select('full_name')->where(['full_name'=> $model->full_name]);
if($name == $model->full_name ){
echo "<script type='text/javascript'>alert('Same student name is detected');</script>";
}
else{
$model->status ="Active";
$model->call_format = Countries::find()->select('phonecode')->where(['name'=> $model->country]);
$model->date_created = new Expression('NOW()');
$user->user_type ='student';
$user->user_name = $model->full_name;
$user->user_status = $model->status;
$user->authKey = Yii::$app->security->generateRandomString(10);
$user->accessToken = Yii::$app->security->generateRandomString(10);
$user->save();
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
}
}
But it shows error like :missing required parameters: id. When i apply model->save(false) ,it seems that the sql statement wont run because of duplicate entry in full_name column. How do i fix it?
Well, there is a construct exists() for such a purposes (see Yii2: check exist ActiveRecord model in database ).
if(StudentInfo::find()->where(['full_name'=> $model->full_name])->exists()){
echo "<script type='text/javascript'>alert('Same student name is detected');</script>";
}
else{...}
it generates the EXISTS query, which is faster and you don't have to load all the data from DB.
If you don't have such a column in your table, then check it by the first/last name.
change it:
$name = StudentInfo::find()->select('full_name')->where(['full_name'=> $model->full_name]);
To:
$name = StudentInfo::find()->select('full_name')->where(['full_name'=> $model->full_name])->one();
Also, if you use the select() method, to use the update() and save() or updateCounters() ... methods, you need the row ID in the same query.
Example:
->select('id') or ->select(['id', 'full_name'])
info: Multi-parameter is an array in select()
:missing required parameters: id
could mean that it couldn't find id, not by duplicate entry in full_name column. please check again
There are two problems with your code.
$name = StudentInfo::find()->select('full_name')->where(['full_name'=> $model->full_name]);
When this line is executed the $name variable will contain instance of yii\db\ActiveQuery. You want to call some method, that will actually execute your query and return result.
You can use scalar() to get the selected value. In that case the $name will contain the content of full_name column from result.
$name = StudentInfo::find()
->select('full_name')
->where(['full_name'=> $model->full_name])
->scalar();
Or you can use count() to get the number of rows that match condition. In that case you may leave out the select() method call but you will need to modify your condition
$count = StudentInfo::find()
->where(['full_name'=> $model->full_name])
->count();
if ($count > 0) {
echo "<script type='text/javascript'>alert('Same student name is detected');</script>";
} else {
// ...
}
The other problem is that you are not checking whether your $model->save() was successful. If your $model is new instance and the id attribute is auto-generated then when $model->save fails the $model->id is empty and then you are trying to redirect user to view with empty id.
Your code should look like this:
if ($user->save() && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
If the save fails because of validation the validation errors will be stored in models and if you are using ActiveForm widget the errors will be displayed. If you are not using ActiveForm you should do something to tell user that operation failed.
Since you are saving two different models you might want to consider use of transactions to prevent a situations where $user model is saved but save of $model fails.
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 have a function that is taking an id as a param, and updates the db using the DB method. however, when i run the code, the variable is not being passed to the method. to test, i replaced $id with an integer and it worked, so i think the DB method can not access the variable from the parameter
public function disable($id)
{
// Update the user status to 0 from 1
DB::table('employees')->where('id', $id)->update(['status' => 0]);
return redirect('/employee')->with('error', 'User is disabled, all related accounts are now shutdown!...');
}
Update:
Forgot to mention that i have already checked, and the param comes inside the function OK, i can return the id outside of the method
SOLUTION
As shown in the comment, the varDump was returning "id=9" where i need "9", i noticed in the form piece of my code, there was an extra "id=" before the id which caused a malfunction.
Use function as disable(Request $request) and get id as $request->id
public function disable(Request $request)
{
// Update the user status to 0 from 1
DB::table('employees')->where('id', $request->id)->update(['status' => 0]);
return redirect('/employee')->with('error', 'User is disabled, all related accounts are now shutdown!...');
}
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.
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.