I'm designing a website of book library for my project in php.
Anyways I have three tables named books,users and savebook.
Table book has following columns: "bookid", "title","author" "genre" and "summary".
And table users has following columns userid, username, password, and name.
Users can save books as favorites and those saved books are saved in the table named savebook with columns bookid and userid which are foreign key to table book and users
I used following query for that:
ALTER TABLE savebook
ADD CONSTRAINT bkid_usid
FOREIGN KEY (bookid)
REFERENCES books (bookid);
and
ALTER TABLE savebook
ADD CONSTRAINT usid_bkid
FOREIGN KEY (userid)
REFERENCES users(userid);
Now the problem is whenever i try to delete a book from table book using query
DELETE FROM books
WHERE bookid=1;
I get this message:
1451 - Cannot delete or update a parent row: a foreign key constraint fails (booklibrary.savebook, CONSTRAINT bkid_usid FOREIGN KEY (bookid) REFERENCES books (bookid))
How do i delete a book from table book which also deletes the related row in table savebook?
To get the behavior you describe, you can specify
ON DELETE CASCADE
as part of the foreign key definition.
Reference: http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html
If you were to modify your foreign key constraint bkid_usid (on the booksave table), then the delete statement that you show
DELETE FROM books WHERE ...
Would cause MySQL to delete the rows in booksave that have a foreign key values that reference rows being removed from books.
ALTER TABLE savebook
ADD CONSTRAINT bkid_usid
FOREIGN KEY (bookid)
REFERENCES books (bookid)
ON DELETE CASCADE
;
Make note of that last line I added to the ALTER from the original question, it is an optional part of the foreign key definition (there is also ON UPDATE ...). By default, when not specified, I believe MySQL treats it as NO ACTION or RESTRICT (those two are effectively the same as far as I know) instead of CASCADE. Full documentation found at http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
An interesting question :)
I think the problem is caused by the so called "referential integrity".
That means, that you are not able to delete a dataset, which primary key is used in another tables dataset as foreign key. If you could do this, some foreign keys of the table savebook would refer to a dataset in table books, that doesn't exist anymore.
So first you have to delete all datasets in savebook, where the bookid is the same one as of the book you want to delete and after that, you can delete this dataset from books. ;)
You have applied constraints to the tables. You need to tell MySQL to delete referenced entries from "savebook" table if any entry is deleted from "book" table.
ALTER TABLE savebook ADD CONSTRAINT bkid_usid FOREIGN KEY (bookid) REFERENCES books (bookid) ON DELETE CASCADE
Related
i have three tabs in my Db:
1.pers_info(id(primary), name ,....)
2.contacts(c_id(primary), phone, email, ...)
now 1 person can have multiple rows in contacts tab.
thus to minimize redundancy i made another tab contact_relation(id (foregin key references pers_info(id), c_id (foregin key references contacts(c_id))
i successfully created the relation and also was able to insert apt entries(related id and c_id) to it "using last_insert_id();" to extract id and c_id required.
now the problem..
i dropped tab contacts_rel. and created it this way :
CREATE TABLE contacts_relation (
id INT NOT NULL,
cid INT NOT NULL,
FOREIGN KEY (id)
REFERENCES pers_info(id)
ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (c_id)
REFERENCES contacts(c_id)
);
if now i try to insert into tab cont_rel, it gives error :
cannot add or update a child row foreign key constraint fails.
which makes sense..
i was hoping that adding constraints in the defn of tab cont_rel would save the hassle of inserting entries in it manually using "last_insert_id();"
so is there a way, i could maintain ref integrity with new data
coming.. thanks.
Why the third table? When you many to many relation you need intermediate table. You have one to many relation so two tables are sufficient. Table contacts need FK to table pers_info. Add it if you don't have already.
Here's a simple transaction example with LAST_INSERT_ID(): SQL INSERT INTO multiple tables
Some info about foreign keys and altering table:
Add Foreign Key to existing table
http://dev.mysql.com/doc/refman/5.0/en/alter-table.html
I am relatively new in php and mysql.The problem that i am facing while i inserting value in my leave table.My leave table containing following column..
1.lid(INT primary key)
2.empname(varchar)
3.username(varchar)
4.nod(INT)
5.sdate(DATE)
6.edate(DATE)
7.reason(varchar)
8.action(varchar)
9.empID (INT FOREIGN KEY)
here empID is the foreign key references from users table. The problem that im facing while inserting values into the leave table.ERROR is given below
Cannot add or update a child row: a foreign key constraint fails (db_attendance1.leave, CONSTRAINT leave_ibfk_1 FOREIGN KEY (empID) REFERENCES users (empID))
here i just send the query and here it is..
mysql_query("INSERT INTO `leave`
(`empname`, `username`,
`nod`, `sdate`, `edate`,
`reason`,`action`)
VALUES ('$empname', '$username',
'$nod', '$sdate',
'$edate', '$reason','');",
$dbCon) or die(mysql_error());
You can put
SET FOREIGN_KEY_CHECKS=0;
and run your query. Once you are done again set it back to 1 by
SET FOREIGN_KEY_CHECKS=1;
A foreign key constraint means that you one table doesn't accept inserts, updates or deletes that would 'break' the foreign key. This means, you can't update a EmpID if the new EmpID doesn't exist in the users. You can't add a new EmpID if it doesn't exist in the users table, etcetera.
So to solve this issue, you need to make sure that the EmpID you're trying to add to table 'leave', first exists in table 'users'.
Foreign keys can be a real powerful item, but can be a real pain too. Since the DB you're working on had foreign key constraints, I suggest you read on them a bit: http://en.wikipedia.org/wiki/Foreign_key
Borniet, you helped me solve my similar problem.
#OP - All I had to do to fix this was create a corresponding row in the table so that the foreign key would exist.
E.g. Table 1 has column Name
Table 2 has column friends_name, a foreign key tied to Name in table 1.
I got this error because I was trying to insert a row into table 2, where the friends_name referenced a non existing Name in table 1. So I created the name and we're off to the races :).
I have two table: users and 'bills'. In bills as a foreign key to users.
I want to automatically delete rows from the bills table when I delete from the users table. For that I alter table with following query, still it doesn't delete entry from bills table.
My alter statement is:
ALTER TABLE bills
ADD CONSTRAINT fk_pid
FOREIGN KEY (pid)
REFERENCES users(id)
ON DELETE CASCADE
here pid is foreign key in bills table, whereas id primary key in users table
Please help me to resolve above issue, thank you in advance.
Use create instead of alter,Otherwise your syntax is ok
Create TABLE bills(
Your columns details
------
------
ADD CONSTRAINT fk_pid
FOREIGN KEY (pid)
REFERENCES users(id)
ON DELETE CASCADE
)
Try this..
If it's doesn't work then try for this thing as well.
if your both tables having mismatch primary key and foreign key problem then you cannot add Delete Cascade.For that you need to fix that key problem.like you don't have primary key value in your user table and you are using that same id in your bills table as a foreign key then you cannot add cascade in bills table.For that remove that key from bills table and then try your adding cascade script with Alter.I had same problem but i use this way and it worked.Hope it will work for you as well.Thanks
I think this solution for create can help you in figuring out what actually you are missing.
Go thru it and try customizing it as per your need, as you haven't provided enough detail
along with your question.
I suspect it has to do something with your create table statement
OR try this for ALTER1
OR ALTER2
That is the primary table field (tasks table):
task_id int(10) UNSIGNED No None AUTO_INCREMENT
This is my foreign table field (url_error_stats table):
task_id int(10) UNSIGNED No None
url_error_stats doesnt present the "relation view" option to connect between the keys..why?
SQL query:
ALTER TABLE url_error_stats ADD FOREIGN KEY ( task_id )
REFERENCES aws_backlinks.tasks (
task_id ) ON DELETE CASCADE ON UPDATE CASCADE ;
MySQL said:
1452 - Cannot add or update a child row: a foreign key constraint
fails (aws_backlinks., CONSTRAINT #sql-6f0_3bd_ibfk_1 FOREIGN KEY
(task_id) REFERENCES tasks (task_id) ON DELETE CASCADE ON UPDATE
CASCADE)
you have to use innodb and index the primary key if you want to create the foreign keys. and I will recommend you to use NAVICAT . its much easier to create foreign keys and quick too. but for a quick phpmyadmin guide see
Setting up foreign keys in phpMyAdmin?
Another reason can be the unrelated data in your tables. I mean you may have a foreign key that doesn't exist in parent table.
in this , click on url_error_stats table, then on right hand side it will show all the fields list, so now check on checkbox of that particular field which u wanted to be foreign and click on the link relation view (which is provided by phpmyadmin below to the table fields with blue color hyperlink).
it will open relationship screen , there You can select the field of the primary table.
Thanks
How can I delete duplicate rows from a MySQL table when a foreign key relationship has already been setup up on those rows.
Can the duplicates be merged somehow and then foreign key updated with the new value?
If the foreign key is ON DELETE CASCADE, then deleting the duplicate rows will also delete the dependent rows, e.g., if you have a table customers and a table orders, and a foreign key like ALTER TABLE orders ADD FOREIGN KEY customer_id REFERENCES customers (id) ON DELETE CASCADE, then deleting a customer will also delete that customer's orders. Similarly, if the foreign key has ON DELETE SET NULL, then the orders will not be deleted, but their customer_id values will be set to NULL.
If neither of these is the desired behaviour, craft a query that resolves the foreign key conflicts by altering the foreign key columns so that they reference the row you want to keep (i.e., update all orders to reference non-duplicate customers), then delete the offending rows.
Yet another alternative is to disable foreign key checks temporarily, but this will leave you with an inconsistent database, so I wouldn't recommend this.