Validate Record Data from Records in another table - mysql

I have 2 tables: Employee, and Regions. Each Employee can be assigned to one region, and each region can have multiple employees. However, I only want the data entered into the Employee record for 'Region' to be one that exists in the Region table. How do I do this?
List of Regions: Northeast, Southeast, Central, Northwest, Southwest
Using MySQL, MySQL Workbench, and Amazon RDS

you add a foreign key constraint to the region table
CREATE tABLE Region (region VARCHAR(55) Primary KEY NOT NULL)
INSERT INTO Region VALUES ('Northeast'), ('Southeast'), ('Central'), ('Northwest'), ('Southwest')
CREATE tABLE employee (id bigint Primary KEY auto_increment
, refregion VARCHAR(55) NOT NULL
,
CONSTRAINT FK_RmploxxRegion FOREIGN KEY (refregion)
REFERENCES Region(region))
INSERT INTO employee VALUES (NULL,'Northpole')
Cannot add or update a child row: a foreign key constraint fails (`db_1115468314`.`employee`, CONSTRAINT `FK_RmploxxRegion` FOREIGN KEY (`refregion`) REFERENCES `Region` (`region`))
INSERT INTO employee VALUES (NULL,'Northeast')
✓
SELECT * FROM employee
id | refregion
-: | :--------
2 | Northeast
db<>fiddle here

Related

Why are my sql foreign key values == null?

Im new to sql, I wrote these create table statements and inserted data into them. in the coffee table shop_id and supplier_id are foreign keys for tables I have already inserted data into. When I do my select statement these two values are null. why is this?
shop_id and supplier_id are null
# CREATE TABLES
CREATE TABLE COFFEE_SHOP (
shop_id int NOT NULL ,
shop_name varchar(50),
city varchar(50),
state CHAR (2),
PRIMARY KEY (shop_id)
);
CREATE TABLE SUPPLIER (
supplier_id int NOT NULL ,
company_name varchar(50),
country varchar(30),
sales_contact_name varchar (50),
email varchar(50) NOT NULL,
PRIMARY KEY (supplier_id)
);
CREATE TABLE COFFEE (
coffee_id int NOT NULL ,
shop_id int,
supplier_id int,
coffee_name VARCHAR (30),
price_per_pound numeric(5,2),
PRIMARY KEY (coffee_id),
FOREIGN KEY (shop_id) REFERENCES COFFEE_SHOP(shop_id),
FOREIGN KEY (supplier_id) REFERENCES SUPPLIER(supplier_id)
);
CREATE TABLE EMPLOYEE (
employee_id int NOT NULL ,
FirstName varchar(30),
LastName varchar(30),
hire_date date,
job_title varchar(30),
shop_id int,
PRIMARY KEY(employee_id),
FOREIGN KEY (shop_id) REFERENCES COFFEE_SHOP(shop_id)
);
# INSERTION QUERIES
INSERT INTO COFFEE_SHOP (shop_id, shop_name, city,state)
VALUES ('45', 'Stavanger', 'Norway','fl');
INSERT INTO SUPPLIER (supplier_id, company_name, country,sales_contact_name,email)
VALUES ('25', 'lovanger', 'Forway','Tl','sql#gmail.com');
INSERT INTO COFFEE (coffee_id,coffee_name,price_per_pound )
VALUES ('15','espresso','15');
SELECT *
FROM COFFEE
Hey you are missing the concept of Foreign Key.
It is never for Foreign key to have the values directly from another table when you have defined Foreign key in first table.
what it simply means that you are tying two tables in order to make sure that no data is inserted in another table which doesn't have a reference key in first table.
To make it easier for you to understand, lets take your coffee table example.
Let's suppose you are trying to insert a row in Coffee table with a supplier Id which is not present in Supplier Table.
INSERT INTO COFFEE (coffee_id,coffee_name,price_per_pound,supplier_id )
VALUES ('15','espresso','15','111');
This will error out as
Schema Error: Error: ER_NO_REFERENCED_ROW_2: Cannot add or update a child row: a foreign key
constraint fails (`test`.`COFFEE`, CONSTRAINT `COFFEE_ibfk_2` FOREIGN KEY
(`supplier_id`) REFERENCES `SUPPLIER` (`supplier_id`))
Which means you can't insert any row in coffee table with Supplier Id which is not already present in Supplier table.
That's the whole fundamental of Foreign Key and it's use.
So that no corrupt data is inserted in tables.
This foreign key establishes referential integrity between Supplier and Coffee tables, thus, restricting the insertion of a new row when the SupplierId value of the inserted row does not match the ID column values of the Supplier's table.
Let me know if you have any further doubt
Simply because you don't insert shop_id and supplier_id values to the table, you should also insert these values as well.
Here:
INSERT INTO COFFEE (coffee_id,coffee_name,price_per_pound,shop_id,supplier_id)
VALUES ('15','espresso','15','45','25');

ERROR 1452: Cannot add or update a child row for A3ENROLL

I have created the following tables:
A3STUDENT
CREATE TABLE A3STUNDENT(
STD_ID INTEGER NOT NULL,
STD_NAME VARCHAR(30),
STD_MAJOR CHAR(4),
STD_RANK CHAR(2),
CONSTRAINT PK_A3STUDENT PRIMARY KEY (STD_ID)
);
CREATE TABLE A3COURSE(
CRS_TIME VARCHAR(10),
CRS_ROOM CHAR(5),
CRS_ID CHAR(7) NOT NULL,
CONSTRAINT PK_A3COURSE PRIMARY KEY (CRS_ID)
);
CREATE TABLE A3ENROLL(
ENR_GRADE CHAR(1),
STD_ID INTEGER NOT NULL,
CRS_ID CHAR(7) NOT NULL,
CONSTRAINT PK_A3ENROLL PRIMARY KEY (STD_ID, CRS_ID),
CONSTRAINT FK_STD_ENR FOREIGN KEY (STD_ID) REFERENCES A3STUDENT(STD_ID),
CONSTRAINT FK_CRS_ENR FOREIGN KEY (CRS_ID) REFERENCES A3COURSE(CRS_ID)
);
When I go to insert values such as this:
INSERT INTO A3ENROLL VALUES ('A', 100, 'MGMT445');
I receive this error:
#1452 - Cannot add or update a child row: a foreign key constraint fails (Hess.A3ENROLL, CONSTRAINT FK_CRS_ENR FOREIGN KEY
(CRS_ID) REFERENCES A3COURSE (CRS_ID))
I have can't seem to understand why my data won't insert. What am I overlooking?
This usually happens because have not data in the A3STUNDENT andA3COURSE tables.
The foreign key relationships means that a primary table that contains the central data values and a child table with identical values pointing to the parent, any INSERT or UPDATE operation that attempts to create a foreign key value in a child table is rejected if there is no matching candidate key value in the parent table.
The table A3ENROLL is taking as reference100 and MGMT445 that does not exist in the tables mentioned above.
Before inserting data in the A3ENROLL table, you must be sure that there are data in the other tables A3STUNDENT and A3COURSE, because the tableA3ENROLL has a foreign key of A3STUNDENT andA3COURSE, this means that you must have these data in those tables, for example:
Select * from A3STUNDENT;
STD_ID | STD_NAME | STD_MAJOR | STD_RANK
100 | 'Zack' | ... | ....
Select * from A3COURSE;
CRS_ID | CRS_ROOM | CRS_TIME
MGMT445 | ... | ....
You can try to insert data in the previous tables and then insert in the table A3ENROLL.
Here you have more info: https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html

Can a foreign key refer to the primary key of its own table?

I am creating a MySQL employee database for work and I want it to store the supervisor of the employee.
Suppose I have a table called 'employee' with the fields 'id', 'first_name', 'last_name', and 'supv_id' where 'id' is the primary key and 'supv_id' is a foreign key that refers to and employee ID.
Currently I have 'supv_id' as a foreign key that points to a separate table 'supervisor'. This table simply consists of 'id' and 'empl_id' which points back to the employee table. However, if there is a way to simply make 'supv_id' in 'employee' to point to 'employee.id', this would eliminate the need of my 'supervisor' table altogether. Here is an example:
+----+--------+-----------+---------+
| id | f_name | l_name | supv_id |
+----+--------+-----------+---------+
| 1 | Han | Solo | NULL | //Or 0?
| 2 | Luke | Skywalker | 1 |
+----+--------+-----------+---------+
In short, I want 'supv_id' to point to another employee. Does this make sense? How would I go about doing this?
Thanks!
Edit: fixed table
You can create such a table as following:
CREATE TABLE laya2 (
id INT NOT NULL PRIMARY KEY,
f_name VARCHAR(20),
l_name VARCHAR(20),
supv_id INT,
INDEX supv_id_idx (supv_id),
FOREIGN KEY (supv_id)
REFERENCES laya2(id)
ON DELETE SET NULL -- example for an action
) ENGINE=INNODB;
My example sets the reference option to SET NULL, because I think it's the logical one here. If an employee who supervises others left, then those employees have no supervisor first. Another option would be to have NO ACTION because you could easily identify those employees without a valid supervisor and find a new supervisor for them. ON DELETE CASCADE would be wrong here, because those employees won't leave at the same time ...
You could insert employees with
INSERT INTO laya2 VALUES
(1, 'Han', 'Solo', NULL),
(2, 'Luke', 'Skywalker', 1);
(two successful inserts), but not with
INSERT INTO laya2 VALUES
(3, 'Anakin', 'Skywalker', 0);
This statement will fail because the foreign key constraint fails.
Deleting Han Solo will change the supv_id for Luke Skywalker to NULL, because of the reference option ON DELETE SET NULL
DELETE FROM laya2 WHERE id = 1; -- this will set the supv_id for Luke Skywalker to NULL
Yes, join the table to itself. Here's one of many ways:
SELECT a.l_name AS employee, b.l_name AS supervisor
FROM employee AS a, employee AS b
WHERE a.supv_id = b.id -- link tables
AND a.id = 2 -- get employee
Returns:
employee | supervisor
----------+-----------
Skywalker | Solo
Yes, you can define a foreign key that refers to the primary key of its own table.
create table employee (id int(10),
f_name varchar(10),
l_name varchar(10),
supv_id int(10)) ENGINE=InnoDB;
alter table employee add primary key (id);
alter table employee add foreign key (supv_id) references employee (id);
Employees without supervisor must have NULL in the supv_id column.

query with foreign key

project assignment is n to n relationship where n can be zero.
pid is primary key for the project table
eid is primary key for the employee table
a project may not be assigned to any employee.similary an employee may not have any project in his hand.
how to write this query? eid should take value as null or the value from the emp table.
pid should either take null or the value from the table project.
IS IT CORRECT.
CREATE TABLE Proj_Assign
(
eid VARCHAR(25),
pid VARCHAR(25),
PRIMARY KEY(eid,pid),
FOREIGN KEY eid REFERENCES employee(eid),
FOREIGN KEY pid REFERENCES project(pid)
);
Give this way:
FOREIGN KEY (t_eid) REFERENCES parent(eid)
ON DELETE CASCADE
Instead of using same eid twice. It is explained in the documentation.
Also, the original parent table should be there before you create this table and you need to manually insert the queries this way:
INSERT INTO `Proj_Assign` (`eid`, `pid`) VALUES (1, 1);
Whatever query you have written is right as per documentation.

Working with foreign keys - cannot insert

Doing my first tryouts with foreign keys in a mySQL database and are trying to do a insert, that fails for this reason: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
Does this mean that foreign keys restrict INSERTS as well as DELETES and/or UPDATES on each table that is enforced with foreign keys relations?
Thanks!
Updated description:
Products
----------------------------
id | type
----------------------------
0 | 0
1 | 3
ProductsToCategories
----------------------------
productid | categoryid
----------------------------
0 | 0
1 | 1
Product table has following structure
CREATE TABLE IF NOT EXISTS `alpha`.`products` (
`id` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT ,
`type` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 ,
PRIMARY KEY (`id`) ,
CONSTRAINT `funkyfunky`
FOREIGN KEY (`id` )
REFERENCES `alpha`.`ProductsToCategories` (`productid` )
ON DELETE CASCADE,
ON UPDATE CASCADE)
ENGINE = InnoDB;
Your insert is failing because the foreign key in the row you are inserting doesn't match a valid key in the constraint table. For example:
Assume you've got these two tables:
Employees
----------------------------
EmpID | Name
----------------------------
0 | John
1 | Jane
OfficeAssignments
----------------------------
OfficeID | EmpID
----------------------------
0 | 0
1 | 1
If you have a foreign key constraint on OfficeAssignments.EmpID -> Employees.EmpID, and you try to execute:
INSERT INTO OfficeAssignments (OfficeID, EmpID) VALUES (2,2)
The statement will fail because there is no entry in the Employees table with an EmpID of 2.
Constraints are designed to ensure that your dependent table always has valid data with regard to the parent table -- in this example, you will never have an office which is listed as assigned to an employee who doesn't exist in the system, either because they never existed (as in this case) or because they've been deleted (because the constraint will prevent the employee record from being deleted until the office assignment record has been deleted first).
Edit: Now that you've posted the constraint, it indeed looks like it might be set up backwards. By placing the constraint in the definition of the Products table, you are making it the child, and ProductsToCategories the parent. The constraint you've written can be read as, "a Product must be assigned to a category before it can be created". I suspect what you meant is the other way around: "a Product must be created before it can be assigned to a category." To get that result, you need to place the constraint on the ProductsToCategories table, setting the foreign key to productid and referencing Products.id.
You cannot delete a row from the parent table while there is a foreign key reference to it from a child table. Also you cannot insert/update in the child table with invalid id's in the foreign key column.
Edit: The "CONSTRAINT funkyfunky FOREIGN KEY (id)" must be declared in the "ProductsToCategories" table not in the "Products" table, because "ProductsToCategories" is referencing "Products" not the opposite as you have did.
Your products table is slightly wrong, as you don't need to reference anything from it. References go in the "other" tables, and point to the main, e.g:
create table products (
id int auto_increment,
type int,
primary key (id)
);
create table categories (
id int auto_increment,
name varchar(128),
primary key (id)
)
create table products_to_categories (
product_id int references products,
category_id int references categories
);
A foreign key enforces a valid relation between the rows in two tables. In order to be able to insert a row into a table containing a foreign key, there must be a row in the referenced table containing that key or the insert will fail. The same with delete, you can't delete the row in the referenced table while there are still rows in the table with the foreign key that still reference it. The prevents ending up with rows in the dependent table that have data, but don't have associated rows in the referenced table, i.e., a violation of referential integrity.