Suggestions for insert with Foreign key constraint in mysql - sql

I have a table containing 2 entries.
Something like
CREATE TABLE `db`.`main` (
`id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
);
The id for these 2 entries are automatically generated primary keys.
I have another table with a rule linking
CREATE TABLE `db`.`day` (
`main_id` int(10) unsigned NOT NULL,
`day` tinyint(4) NOT NULL,
CONSTRAINT `fk_db_main` FOREIGN KEY (`main_id`) REFERENCES `main` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
);
now I can successfully get a result using
SELECT * FROM main where id='9';
but when I try to run
INSERT INTO day (main_id, day) VALUES (9, 0);
I get
"Cannot add or update a child row: a foreign key constraint fails (db.day, CONSTRAINT fk_db_main FOREIGN KEY (main_id) REFERENCES main (id) ON DELETE NO ACTION ON UPDATE NO ACTION) (1452)"
Any suggestions on what I am missing with the insert?
**I hadn't listed the actual cause of the issue while asking the question. The actual cause was that the main db table was in MyISAM, and the InnoDB tables couldn't create a foreign key connecting to it. In short, MyISAM doesn't support foreign keys, even when they are coming from other tables.

The insert works for me if I remove the db. parts in the CREATE TABLE statements (and insert into main a row with an id of 9). Maybe the problem is that you're using that db. prefix inconsistently, i.e. after TABLE but not in the CONSTRAINT clause...?

The FOREIGN KEY constraint says "there shall be an entry in the 'main` table with an ID value that matches the newly inserted 'main_id' value in the 'day' table".
When you INSERT the value 9 into 'day', is there already a row in 'main' with ID = 9?
The DBMS doesn't think so - that's why it complained.

I hadn't listed the actual cause of the issue while asking the question. The actual cause was that the main db table was in MyISAM, and the InnoDB tables couldn't create a foreign key connecting to it. In short, MyISAM doesn't support foreign keys, even when they are coming from other tables.

Related

How to prevent inserting duplicate rows based on two foreign keys?

If I am manually inserting hundreds of rows, how should I efficiently write the insert statements so that each insert will not run only if both foreign keys are already present together in a record in that database?
Create a constraint on the columns, here is a great reference starting point.
Here is an example of a FOREIGN KEY constraint, and for defining a FOREIGN KEY constraint on multiple columns, use the following SQL syntax:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
)
You can add a unique constraint as described by #BrianAtkins and you can also use a MERGE statement instead of INSERT in order to avoid breaking the entire insert on a unique constraint violation.

create foreign key in oracle

is there anyone who can help me to create a foreign key for my Status table. I need to PLACE a foreign key constraint on the code in the status table, referring to the id in the Building table.
TABLE building
(
build_name VARCHAR2(50,0) NOT NULL,
id NUMBER (38,0) NOT NULL,
mapid NUMBER (10,0) NOT NULL
);
TABLE STATUS
(
code VARCHAR(2 BYTE) NOT NULL,
status_name VARCHAR2(40 BYTE) NOT NULL,
);
Bulding table has constraint building_gmidx with id as primary key.
Here is a quick syntax for your current requirement, however I recommend you to go through the oracle documentation for a proper understanding of what this means.
ALTER TABLE STATUS ADD (
CONSTRAINT status_fk_building FOREIGN KEY (code)
REFERENCES building (id)
ENABLE VALIDATE);
Did you leave out CREATE TABLE *name* to save time when writing the question? The first thing I see is that your Foreign key has to have the same data type and size as your Primary key. If the Tables already exist the code would be:
ALTER TABLE status MODIFY (code NUMBER(38));
From there you would need to
ALTER TABLE status ADD FOREIGN KEY (code) REFERENCES (building_gmidx)
Why is the constraint for building Primary key named building_gmidx and the column plain id?? All Normalized table attributes should be Unique. Wouldn't it be better if you just named the column "id" building_gmidx instead. Just in case there are other types of id's added later you do not have to think about which table "id" pertains to. Let me know if this works.

Problem creating foreign keys in mySql

I created a foreign key in my sql by the following statemnt..
ALTER TABLE `users` ADD FOREIGN KEY ( `id`)
REFERENCES `user_login` (`user_id`)
ON DELETE CASCADE ;
The creation appears to succeed then after that I execute a delete statement
DELETE From user_login WHERE user_id = 1576;
yet in users the row still exists that is referencing that. I open up the mysql workbench and it doesn't show any signs that the foreign key was created. Does anyone know why this would be? Or what I am doing wrong? It is a one-to-one relationship in the two tables.
The table may be in MyISAM format, which does not support foreign keys.
Try converting it to InnoDB first:
alter table users engine=InnoDB;
You have to also make sure that both users.id and user_login.user_id have an index each.
Copy and paste this code in your Mysql script editor and run. You will have two tables categories and products these tables having cat_id as foreign key.
CREATE DATABASE IF NOT EXISTS dbdemo;
USE dbdemo;
CREATE TABLE categories(
cat_id int not null auto_increment primary key,
cat_name varchar(255) not null,
cat_description text
) ENGINE=InnoDB;
CREATE TABLE products(
prd_id int not null auto_increment primary key,
prd_name varchar(355) not null,
prd_price decimal,
cat_id int not null,
FOREIGN KEY fk_cat(cat_id)
REFERENCES categories(cat_id)
ON UPDATE CASCADE
ON DELETE RESTRICT
)ENGINE=InnoDB;

Foreign Key doesn't stop me entering data MySQL

I have a table which has one column as a foreign key joining to another table.
It's a cricket question where I have a table called Fixtures and another called Inning.
Inning table has a FixtureId column relates to the Fixture table.
I would expect that If i do a insert on the inning table using a FixtureId that doesn't relate to a Fixture then it would error but this isn't the case...
Can anyone explain why this is?
Make sure that you are using the InnoDB storage engine when creating the table. Other storage engines will simply ignore foreign key constraints. (Source)
Example:
CREATE TABLE a (
id INT AUTO_INCREMENT PRIMARY KEY
) ENGINE=INNODB;
CREATE TABLE b (
id INT AUTO_INCREMENT PRIMARY KEY,
a_id INT,
FOREIGN KEY (a_id) REFERENCES a(id)
) ENGINE=INNODB;
INSERT INTO b (id, a_id) VALUES(NULL, 1);
The above insert fails with:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails...
im not sure i understand can you elaborate and show your sql statements?
if i understand correctly, ( which i may not ) your foreign key would just be blank if you did not have a value for that field, why would it error out?

Foreign keys in MySQL?

I have been slowly learning SQL the last few weeks. I've picked up all of the relational algebra and the basics of how relational databases work. What I'm trying to do now is learn how it's implemented.
A stumbling block I've come across in this, is foreign keys in MySQL. I can't seem to find much about the other than that they exist in the InnoDB storage schema that MySQL has.
What is a simple example of foreign keys implemented in MySQL?
Here's part of a schema I wrote that doesn't seem to be working if you would rather point out my flaw than show me a working example.
CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY (`pID`),
Foreign Key(`cID`) references categories,
Foreign Key(`uID`) references users
) ENGINE=InnoDB;
Assuming your categories and users table already exist and contain cID and uID respectively as primary keys, this should work:
CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY (`pID`),
Foreign Key(`cID`) references categories(`cID`),
Foreign Key(`uID`) references users(`uID`)
) ENGINE=InnoDB;
The column name is required in the references clause.
Edited: Robert and Vinko state that you need to declare the name of the referenced column in the foreign key constraint. This is necessary in InnoDB, although in standard SQL you're permitted to omit the referenced column name if it's the same name in the parent table.
One idiosyncrasy I've encountered in MySQL is that foreign key declaration will fail silently in several circumstances:
Your MySQL installation doesn't include the innodb engine
Your MySQL config file doesn't enable the innodb engine
You don't declare your table with the ENGINE=InnoDB table modifier
The foreign key column isn't exactly the same data type as the primary key column in the referenced table
Unfortunately, MySQL gives no message that it has failed to create the foreign key constraint. It simply ignores the request, and creates the table without the foreign key (if you SHOW CREATE TABLE posts, you may see no foreign key declaration). I've always thought this is a bad feature of MySQL!
Tip: the integer argument for integer data types (e.g. BIGINT(20)) is not necessary. It has nothing to do with the storage size or range of the column. BIGINT is always the same size regardless of the argument you give it. The number refers to how many digits MySQL will pad the column if you use the ZEROFILL column modifier.
This has some code showing how to create foreign keys by themselves, and in CREATE TABLE.
Here's one of the simpler examples from that:
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
) ENGINE=INNODB;
I agree with Robert. You are missing the name of the column in the references clause (and you should be getting the error 150). I'll add that you can check how the tables got created in reality with:
SHOW CREATE TABLE posts;
The previous answers deal with the foreign key constraint. While the foreign key constraint is definitely useful to maintain referential integrity, the concept of "foreign key" itself is fundamental to the relational model of data, regardless of whether you use the constraint or not.
Whenever you do an equijoin, you are equating a foreign key to something, usually the key it references. Example:
select *
from
Students
inner join
StudentCourses
on Students.StudentId = StudentCourses.StudentId
StudentCourses.StudentId is a foreign key referencing Students.StudentId.