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
Related
I usually work with foreign key for good practices and to maintain data integrity but I always face the following "problem" when trying to delete some data:
I have a scenario with a main group table: groups
And I have several other tables that relate to groups, for example:
user_group (relationship table between users and groups)
course_group (relationship table between courses and groups)
When deleting a group I always need to delete the reference to that group in the related tables before ... but currently I have several relationship tables and my exclusion code ends up getting quite large.
My question is: is there any function or library that I could use so that this work could be done more automatically? A function that may check for me all these references and already exclude. If anyone has any idea how to make it faster and with the smallest possible number of code thanks. Note: I am currently working with PHP
You want on delete cascade as an option in the foreign key constraint in the children table.
Say that table groups looks like:
create table groups (
id int primary key,
... -- other columns here
);
You would then declare child table user_groups as:
create table user_groups (
... -- some columns here
group_id int,
foreign key (group_id) references groups(id) on delete cascade
)
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
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
I am new to php and mysql. I created a database named 'students' which contain two tables as 'student_details' which have fields like 'ID, Name, Age, Tel#, Address' and another table as 'fee_details' which have fields like 'ID(student_details table ID), Inst Id, Date, Receipt No'.
I want to set a foreign key and retrieve data from both tables when a student paid their fees and if a student passed out or discontinued I want a delete option to delete his all records from my tables. So please help me to solve this by PHP code and displays it in HTML while using a search form.
Enforcing referential integrity at the database level is the way to go. I believe when you said you wanted the delete "to delete his all records from my tables" you meant deleting the row and all its child records. You can do that by using foreign keys and ON DELETE CASCADE.
CREATE TABLE students
(
student_id INT NOT NULL,
name VARCHAR(30) NOT NULL,
PRIMARY KEY (student_id)
) ENGINE=INNODB;
CREATE TABLE fee_details
(
id INT,
date TIMESTAMP,
student_id INT,
FOREIGN KEY (student_id) REFERENCES students(student_id)
ON DELETE CASCADE
) ENGINE=INNODB;
With this, when a student is deleted from the students table, all its associated records will be deleted from fee_details.
you can try mysql_query() and mysql_assoc_array()