I have a table called custom_carts and I have a table called custom_cart_items.
custom_cart_items has a foreign key called custom_cart_id that is set to custom_cart.id
According to the Cake Manual, when you call Model->delete() the first param is the id of the entry you want to delete and the second param is whether or not to cascade delete the dependent entries.
So when I call $this->CustomCart->delete(7,true) I get this error:
SQL Error: 1451: Cannot delete or
update a parent row: a foreign key
constraint fails
(`krake`.`custom_cart_items`,
CONSTRAINT `custom_cart_items_ibfk_1`
FOREIGN KEY (`custom_cart_id`)
REFERENCES `custom_carts` (`id`))
Here is the query:
DELETE `CustomCart`
FROM `custom_carts` AS `CustomCart`
LEFT JOIN `users` AS `User`
ON (`CustomCart`.`user_id` = `User`.`id`)
WHERE `CustomCart`.`id` = 25
Shouldn't it cascade and dlete the other entry too?
So why am I getting an error?
You must set the dependent parameter to true in the model with the hasmany relationship in order to enable cascading deletion.
Your model would look something like this:
class CustomCart extends AppModel {
var $name = 'CustomCart';
var $hasMany = array(
'CustomCartItem' => array(
'dependent'=> true
)
);
}
Please see http://book.cakephp.org/view/82/hasMany
Just adding fields to a table (regardless of the field name) does not tell CakePHP that they're associated, nor does it link them for cascading deletion.
You need to set the associations in your model: SEE DETAILS HERE.
On the other hand, if you want to delete a record from a table A, and there is another table B which as a FOREIGN KEY constraint on table A, you must set the option on that foreign key of the table B in the Database like this
"SET NULL ON DELETE".
I usually do this in MySqlWorkbench, but you can also use legacy SQL queries to create a table with such an option.
Related
I want both id's to auto increment:
I get this error when synchronizing the model:
Executing SQL script in server
ERROR: Error 3780: Referencing column 'taskList_id' and referenced column 'id' in foreign key constraint 'fk_task_taskList' are incompatible.
SQL Code:
ALTER TABLE `easyManage`.`task`
ADD CONSTRAINT `fk_task_taskList`
FOREIGN KEY (`taskList_id`)
REFERENCES `easyManage`.`taskList` (`id`)
ON DELETE CASCADE
ON UPDATE NO ACTION
tasklist_id in table task is varchar(55). It has to be int to hold id from table tasklist
Your task.tasklist_id is VARCHAR(55).
And your tasklist.id is an INT.
They should be of the same data type.
And - if you say: "I want both id's to auto increment" - I take it you mean task.id and tasklist.id - and not task.tasklist_id - and then everything should work just fine.
I have two tables that look like the following :
Table 1 :
invoices
Table 2 :
invoice_details
public function deleteInvoice($id='')
{
if( !empty( $id ) ){
$query = "DELETE FROM invoices where uuid ='$id'";
if(mysqli_query($this->_con, $query))return true;
else return false;
}else{
return false;
}
}
Table 2 contains a column called "invoice_id" that relates to the "id" of Table 1
Whenever I remove an invoice using the above function, I also want to remove the invoice_details at the same time. Is there an easy way to modify the above code to do that?
First you need to put a foreign key constraint on invoice_details
ALTER TABLE invoice_details
ADD CONSTRAINT fk_invoice
FOREIGN KEY(invoice_id)
REFERENCES invoices(id)
ON DELETE CASCADE;
Then you can delete your invoice and it will delete the details automatically
Don't modify the code. Have a foreign key relationship between the tables with an ON DELETE CASCADE option.
ALTER TABLE invoice_details ADD CONSTRAINT fk_invoice FOREIGN KEY invoice_id REFERENCES invoices(invoice_id) ON DELETE CASCADE;
Now the database does the job for you.
You could do this using foreign key constraints, forcing a CASCADE on delete. See https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html for additional details.
Whenever I try to delete a survey from table "survey" like this:
DELETE FROM surveys WHERE survey_id = 77
It prompts me an error stated below:
#1451 - Cannot delete or update a parent row: a foreign key constraint fails ('user_surveys_archive', CONSTRAINT
'user_surveys_archive_ibfk_6' FOREIGN KEY ('user_access_level_id')
REFERENCES 'user_surveys' ('user_access_level_id') ON DELETE NO ACTION
)
First thing: I do not have any such table with this name "user_surveys_archive_ibfk_6"
2nd thing: There is no record of this survey in other tables.
Any idea on how can I delete this record of fix this issue?
Edit
This is the line I found when I export the table Constraints for table surveys
ALTER TABLE `surveys`
ADD CONSTRAINT `surveys_ibfk_1` FOREIGN KEY (`survey_type_id`) REFERENCES `survey_types` (`survey_type_id`) ON DELETE CASCADE ON UPDATE NO ACTION;`
You will need to first remove or update some rows in table user_surveys_archive.
Those rows are related to rows in the user_surveys table.
Likely, there's a foreign key constraint defined on table user_surveys that references rows in surveys you are attempting to delete.
(You'd need to check the foreign key definition, quickest way to get that is a
SHOW CREATE TABLE user_surveys
And look for REFERENCES surveys. (Likely, its a column named survey_id, but we're just guessing without looking at the definitions of the foreign key constraints.)
To find the rows in user_surveys_archive that are preventing the DELETE from happening...
SELECT a.*
FROM user_surveys_archvive a
JOIN user_surveys u
ON u.user_access_level_id = a.user_access_level_id
JOIN surveys s
ON s.survey_id = u.survey_id -- change this to whatever the FK is
WHERE s.survey_id = 77
It's likely that the foreign key constraint from user_surveys to surveys is defined with ON DELETE CASCADE. The attempt to delete rows from surveys identifies rows in user_surveys that should automatically be removed.
The attempt to automatically remove the rows from user_surveys is what's violating the foreign key constraint defined in user_surveys_archive. And that foreign key is not defined with ON DELETE CASCADE.
(The other possibility is that there's a trigger defined that's doing some DML operations, but that would be odd.)
Once you identify the rows, you need to decide what changes to make to allow you to remove rows from surveys.
You can either DELETE the rows, or UPDATE them.
To delete the rows from user_surveys_archive, modify the query above and replace SELECT with DELETE. If the user_access_level_id column in user_surveys_archive allows for NULL values, you can do an update.
Replace SELECT a.* FROM with UPDATE, and add SET a.user_access_level_id = NULL on a line above the WHERE clause...
UPDATE user_surveys_archvive a
JOIN user_surveys u
ON u.user_access_level_id = a.user_access_level_id
JOIN surveys s
ON s.survey_id = u.survey_id -- change this to whatever the FK is
SET a.user_access_level_id = NULL
WHERE s.survey_id = 77
(It seems strange to me that name of the foreign key column is user_access_level_id. But its just a column name, it could be named anything... seems odd to me because of the conventions and patterns that we follow in naming foreign key columns.)
You should allow the foreign key to be NULL and then choose ON DELETE SET NULL.
Personally I would recommend using both "ON UPDATE CASCADE" as well as "ON DELETE SET NULL" to avoid unnecessary complications, however your setup may dictate a different approach.
Hope this helps.
The survey_id of 77 must be referenced in a table possibly named user_surveys_archive. The error is saying the name of the foreign key restraint which is the user_surveys_archive_ibfk_6. If you need to delete survey_id = 77 you will have to delete any child records or other records that reference it as a foreign key.
Edit After posting my answer I saw the comments above. atif the foreign key in the user_surveys_archive table may be named differently but still equal the value of 77 that you are trying to delete, and/or be referencing the survey_id. If that is not the case then there are some other problems within the database. You could try and look at the code for the FK to see how it was made and what fields it is referencing, or run a query to see if there are any records in the user_surveys_archive where the user_access_level_id is = 77.
Edit 2 spencer7593's answer lays out how to run some of the queries mentioned in my answer.
I have a pivot table set up as follows:
user_roles
user_id //fk->users.id
assoc_id //nullable fk->association.id
role //varchar
I set my database up this way because roles represent a many to many relationship: an association has many users, and a user may be in many associations. every user has a role within an association.
However, there are some roles that exist that can exist outside of an association. The database is configured to accept a null value in the assoc_id field and I can manually insert one from the command line, but when I attempt to execute
$user->roles()->attach(NULL, "outside contractor");
in my seed file, I get an error saying
[Illuminate\Database\QueryException]
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update
a child row: a foreign key constraint fails (`database`.`user_roles`, CONSTR
AINT `user_roles_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users
` (`id`)) (SQL: insert into `user_roles` () values ())
this is particularly confusing because shouldn't the first argument here be referring to the assoc_id? When I replace the NULL with a valid assoc_id,
$user->roles()->attach(1, "outside contractor");
the insert works fine, and the first argument refers to the assoc_id in the table.
What is going wrong?
If you don't provie a key/keys for attach/sync, Eloquent will not insert anything. It's rather expected behaviour, since what you are trying to do is:
Create a link between X and null
this is not what ORM is supposed to do.
Instead insert those rows manually:
$data = [
'user_id' => 99,
'assoc_id' => null,
'role' => 'outside contractor'
];
DB::table('user_roles')->insert($data);
I have a pretty standard MySQL-query in my winform application like this:
SELECT * FROM tblTable WHERE tblTable.tableID = " & variable
One of the fields is a foreign key. And when I try to add a record to my datagridview I get the error:
Cannot add or update a child row: a foreign key constraint fails
Can't MySQLCommandBuilder make INSERT-commands with tables containing foreign keys?
A foreign key constraint is there to prevent behavior like this (for the sake of the integrity of the database). You are probably trying to insert a value that reference another table by a primary key that doesn't exist.
Try changing your foreign key value to a existing primary key within the other table.
You can force the insert the record with this, but is not recommended
SET FOREIGN_KEY_CHECKS = 0;
your select statement;
SET FOREIGN_KEY_CHECKS = 1;
Foreign key check is to avoid inconsistency between tables, the correct way to do this is: first insert the foreing key in the main table then add the record on the child table