adding constraint to column using another table's column - mysql

So I'm trying to add a constraint from one column in a table using another column's value in a separate table.
I tried:
ALTER TABLE BOOK_STORES
ADD CONSTRAINT Rep_ID
CHECK(Rep_ID IN (SELECT Rep_ID FROM STORE_REPS));
These are my two tables:
Store_Reps
Rep_ID INT(5) (PK), Last VARCHAR(15) NOT NULL, First VARCHAR(10) NOT NULL, Comm CHAR(1)
Book_Stores
Store_ID INT(8), Name VARCHAR(30) UNIQUE NOT NULL, Contact VARCHAR(20), Rep_ID(5)
I'm trying to add the constraint to the book stores rep_id using the store_reps rep_id

I think you want a foreign key constraint:
ALTER TABLE BOOK_STORES
ADD FOREIGN KEY (Rep_ID) REFERENCES STORE_REPS(Rep_Id);
You can also do this directly in the create table statement quite succinctly:
create table book_stores (
. . .
Rep_Id int references store_reps(rep_id),
);

Related

Error Code 3078 - Foreign Key not compatible - what does this even mean?

I keep getting this Error code:
Alter Table PAYMENT add FOREIGN KEY (CustomerId)REFERENCES CUSTOMER(CustomerId) Error Code: 3780. Referencing column 'CustomerId' and referenced column 'CustomerId' in foreign key constraint 'payment_ibfk_7' are incompatible. 0.0010 sec
I don't know how to fix it. Please Help.
Create Schema IF NOT EXISTS AUTOMOBILE_COMPANY;
USE AUTOMOBILE_COMPANY;
CREATE TABLE IF NOT EXISTS CUSTOMER(
CustomerId INT NOT NULL PRIMARY KEY,
CustomerFname VARCHAR(30) NOT NULL,
CustomerLname VARCHAR(30) NOT NULL,
CustomerPhone VARCHAR(15) NOT NULL UNIQUE,
CustomerGender VARCHAR(10),
CustomerYearly_salary VARCHAR(15),
CustomerStreet VARCHAR (30),
CustomerCity VARCHAR (30),
CustomerState VARCHAR(30),
CustomerPostcode VARCHAR(6),
ProductId INT NOT NULL,
PaymentId INT
);
CREATE TABLE IF NOT EXISTS DEALERS(
DealerName VARCHAR (10)NOT NULL PRIMARY KEY,
DealerBrand VARCHAR (7),
DealerModel VARCHAR (4),
DealerColour VARCHAR (5),
DealerAvailability VARCHAR (12),
DealerSalesByDate Date,
DealerCarEngine VARCHAR (17),
DealerTransmission VARCHAR (16),
DealerBodyStyle VARCHAR (20)
);
CREATE TABLE IF NOT EXISTS EMPLOYEE(
EmployeeSsn INT NOT NULL PRIMARY KEY,
EmployeeFirst_name VARCHAR(20) NOT NULL,
EmployeeLast_name VARCHAR(20) NOT NULL,
EmployeeBirthday INT NOT NULL,
EmployeeStreet VARCHAR (30),
EmployeeCity VARCHAR (30),
EmployeePostcode VARCHAR(6),
EmployeeState VARCHAR(30),
EmployeeSalary DECIMAL(6) NOT NULL,
EmplyeeSex VARCHAR(6)
);
CREATE TABLE IF NOT EXISTS PAYMENT(
PaymentId INT PRIMARY KEY,
Bank VARCHAR (30) NOT NULL,
CustomerId INT,
EmployeeSsn INT ,
Amount DECIMAL(7)NOT NULL,
PaymentDate DATETIME NOT NULL,
ProductId INT NOT NULL
);
CREATE TABLE IF NOT EXISTS PRODUCT(
ProductId INT NOT NULL PRIMARY KEY,
ArticleNumber VARCHAR (30)NOT NULL,
brand VARCHAR (7),
model VARCHAR (4),
colour VARCHAR (5),
availability VARCHAR (12),
CustomerId INT NOT NULL,
StoreId INT NOT NULL,
CarEngine VARCHAR (17),
Transmission VARCHAR (16),
BodyStyle VARCHAR (20)
);
ALTER TABLE CUSTOMER ADD FOREIGN KEY (productid) REFERENCES PRODUCT(productid);
ALTER TABLE CUSTOMER ADD FOREIGN KEY (paymentid) REFERENCES PAYMENT(paymentid);
CREATE TABLE IF NOT EXISTS RENTAL(
RentalId INT NOT NULL PRIMARY KEY,
RentalDate DATETIME NOT NULL,
ReturnDate DATETIME NOT NULL,
CustomerId INT NOT NULL,
EmployeeSsn INT NOT NULL
);
CREATE TABLE IF NOT EXISTS MANUFACTURER(
StoreId INT NOT NULL PRIMARY KEY,
Street VARCHAR (30)NOT NULL,
City VARCHAR (30)NOT NULL,
State VARCHAR(30)NOT NULL,
Postcode VARCHAR(6)NOT NULL,
ArticleNumber VARCHAR (30)NOT NULL,
SupplierParts VARCHAR (20) NOT NULL
);
CREATE TABLE IF NOT EXISTS STORE (
StoreId INT NOT NULL PRIMARY KEY,
StoreStreet VARCHAR (30)NOT NULL,
StoreCity VARCHAR (30)NOT NULL,
StoreState VARCHAR(30)NOT NULL,
StorePostcode VARCHAR(6)NOT NULL,
StoreManager_staff VARCHAR(30)
);
CREATE TABLE IF NOT EXISTS SUPPLIER(
SupplierParts VARCHAR (20) NOT NULL PRIMARY KEY,
SupplierArticle_number INT NOT NULL
);
Alter Table PAYMENT add FOREIGN KEY (ProductId) REFERENCES PRODUCT(ProductId);
Alter Table PAYMENT add FOREIGN KEY (CustomerId)REFERENCES CUSTOMER(CustomerId);
Alter Table PAYMENT add FOREIGN KEY (EmployeeSsn)REFERENCES EMPLOYEE(EmployeeSsn);
ALTER TABLE RENTAL ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmplyeeSsn);
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (ArticleNumber)REFERENCES PRODUCT(ArticleNumber);
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (SupplierParts) REFERENCES SUPPLIER(SupplierParts) ;
ALTER TABLE SUPPLIERS ADD FOREIGN KEY (SupplierParts)REFERENCES MANUFACTURER(SupplierParts);
ALTER TABLE STORE ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmployeeSsn) ;
ALTER TABLE STORE ADD FOREIGN KEY (SupplierParts) REFERENCES SUPPLIER(SupplierParts) ;
ALTER TABLE PRODUCT ADD FOREIGN KEY (CustomerId) REFERENCES CUSTOMER(CustomerId);
ALTER TABLE PRODUCT ADD FOREIGN KEY (StoreId) REFERENCES MANUFACTURER (StoreId);
ALTER TABLE RENTAL ADD FOREIGN KEY (CustomerId) REFERENCES CUSTOMER(CustomerId);
ALTER TABLE RENTAL ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmployeeSsn);
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (ArticleNumber)REFERENCES PRODUCT(ArticleNumber);
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (SupplierParts)REFERENCES SUPPLIER(SupplierParts);
The code you have posted has a few typo's/errors:
-- references "EmplyeeSsn" instead of "EmployeeSsn"
ALTER TABLE RENTAL ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmplyeeSsn);
-- ArticleNumber is not defined as unique in PRODUCT, can be resolved by adding a unique
-- constraint to PRODUCT on the column ArticleNumber
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (ArticleNumber)REFERENCES PRODUCT(ArticleNumber);
-- Supplier parts is not unique in MANUFACTURER, it is the primary key of SUPPLIERS though
-- So this may be the wrong way round
ALTER TABLE SUPPLIERS ADD FOREIGN KEY (SupplierParts)REFERENCES MANUFACTURER(SupplierParts);
-- STORE contains neither a column called "EmployeeSsn" or "SupplierParts"
ALTER TABLE STORE ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmployeeSsn) ;
ALTER TABLE STORE ADD FOREIGN KEY (SupplierParts) REFERENCES SUPPLIER(SupplierParts) ;
Once all of the above errors are corrected, your code does not through an error, and the foreign key on customer is created correctly:
https://www.db-fiddle.com/f/dVrG7Re6r68jaqYJ8HfR4P/0
From what I am seeing through your script you have 2 issues:
1st - You have a circular reference between the Payment and Customer tables. The Customer table is referencing the Payment table using the PaymentId foreign key, and the Payment table is referencing the Customer table using the CustomerId foreign key. You need to remove one of them so you'll eliminate the circular reference. If I were you I would remove the 1st one since you will most probably have multiple payments per customer but only one customer per payment. So keep the following script:
ALTER TABLE PAYMENT ADD FOREIGN KEY (CustomerId) REFERENCES CUSTOMER(CustomerId);
And remove this:
ALTER TABLE CUSTOMER ADD FOREIGN KEY (paymentid) REFERENCES PAYMENT(paymentid);
2nd - You are creating another circular reference when using the Product table because you are combining the product table with the customer and the payment tables twice. Here again you ideally would have a scenario where 1 customer uses multiple payments to pay for multiple products they are buying. So you don't need the following foreign key:
ALTER TABLE PRODUCT ADD FOREIGN KEY (CustomerId) REFERENCES CUSTOMER(CustomerId);
The reason for doing is because you only need one key to build a relationship between two tables. With regards to the 2nd point, you don't need to create a reference between the customer and the product because is already inferred in the two previous relationships you created; that between the Customer and the Payment and the other between the Payment and the Product. So there is a chained relationship which correlates the Customer to the Product they bought.

Not sure why this syntax error is happening

Hi I'm not very familiar with MySQL as I have only started using it today and I keep getting this syntax error and am not really sure what the problem is. I have attached a screenshot of the code and also pasted it below with the error in bold.
I'm sorry if this is a silly error that is easily fixed I'm just not sure how to fix it and would be very appreciative of any help.
CREATE TABLE copy (
`code` INT NOT NULL,
isbn CHAR(17) NOT NULL,
duration TINYINT NOT NULL,
CONSTRAINT pkcopy PRIMARY KEY (isbn, `code`),
CONSTRAINT fkcopy FOREIGN KEY (isbn) REFERENCES book (isbn));
CREATE TABLE student (
`no` INT NOT NULL,
`name` VARCHAR(30) NOT NULL,
school CHAR(3) NOT NULL,
embargo BIT NOT NULL,
CONSTRAINT pkstudent PRIMARY KEY (`no`));
CREATE TABLE loan (
`code` INT NOT NULL,
`no` INT NOT NULL,
taken DATE NOT NULL,
due DATE NOT NULL,
`return` DATE NULL,
CONSTRAINT pkloan PRIMARY KEY (taken, `code`, `no`),
CONSTRAINT fkloan FOREIGN KEY (`code`, `no`) REFERENCES copy, student **(**`code`, `no`));
Create the tables first, then use the ALTER TABLE statement to add the foreign keys one by one. You won't be able to call two different tables on the foreign key, so you'll have to use an ID that maps to both. Here is an example to add the foreign keys after the table has been created:
Add a new table named vendors and change the products table to include the vendor id field:
USE dbdemo;
CREATE TABLE vendors(
vdr_id int not null auto_increment primary key,
vdr_name varchar(255)
)ENGINE=InnoDB;
ALTER TABLE products
ADD COLUMN vdr_id int not null AFTER cat_id;
To add a foreign key to the products table, you use the following statement:
ALTER TABLE products
ADD FOREIGN KEY fk_vendor(vdr_id)
REFERENCES vendors(vdr_id)
ON DELETE NO ACTION
ON UPDATE CASCADE;

MySQL - Update cell value using foreign key

I've got a problem creating a database.
I'd like to update children table using it's foreign key referencing to mother table automatically.
It means that when data values are inserted into the mother table, the children table gets updated on the column that is the foreign key.
Here's the code i wrote:
drop database domowa_biblioteka;
create database domowa_biblioteka;
use domowa_biblioteka;
create table pozycje
(
lp_p mediumint NOT NULL auto_increment,
nazwisko_autora char(30),
tytul char(60),
ilosc_stron int(4),
cena_oryginalna int(4),
na_sprzedaz enum('NIE','TAK'),
sprzedana enum('NIE','TAK'),
nr_pokoju mediumint,
PRIMARY KEY (lp_p)
)
;
create table kod_miedzynarodowy
(
lp_km mediumint,
ISBN char(20),
FOREIGN KEY (lp_km) REFERENCES pozycje (lp_p)
ON UPDATE CASCADE
)
;
create table pokoje
(
nr_pokoju mediumint NOT NULL auto_increment,
opis char(30),
PRIMARY KEY (nr_pokoju)
)
;
alter table pozycje ADD FOREIGN KEY (nr_pokoju) REFERENCES pokoje (nr_pokoju);
The thing is that the values of columns remain NULL after inserting data to rows.
Thanks for help!

mysql foreign key to compound primary key [duplicate]

This question already has answers here:
Composite key as foreign key (sql)
(2 answers)
Closed 6 years ago.
I try to achive the following using MySQL Server 5.x.
I have a table named Customer created like this:
CREATE TABLE Customer(
Title VARCHAR(30) NOT NULL,
Name VARCHAR(100) NOT NULL,
FirstName VARCHAR(100) NOT NULL,
Street VARCHAR(300) NOT NULL,
HouseNumber VARCHAR(30) NOT NULL,
ZipCode VARCHAR(30) NOT NULL,
City VARCHAR(100) NOT NULL,
Telephone VARCHAR(30) NOT NULL,
EMail VARCHAR(300) NULL,
CONSTRAINT PK_Customer PRIMARY KEY(Title,Name,FirstName),
INDEX Index_Name(Name));
And a second table Named 'Order' created like this:
CREATE TABLE `Order`(
Number BIGINT NOT NULL AUTO_INCREMENT,
Customer VARCHAR(230) NOT NULL,
Issued DATETIME NOT NULL,
PRIMARY KEY(Number),
CONSTRAINT FK_Customer FOREIGN KEY(Customer)
REFERENCES Customer(PK_Customer));
But I get an error with the number:
ERROR 1005 (HY000): Can't create table 'SBZ.Order' (errno: 150)
The innodb engine status shows me this:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
160317 16:05:29 Error in foreign key constraint of table SBZ/Order:
FOREIGN KEY(Customer) REFERENCES Customer(PK_Customer)):
Cannot resolve column name close to:
))
Is it possible to create a foreign key to a compound primary key using constraint?
Any help appriciated. :)
First, you should have a CustomerId column in the first table. It should be auto-incremented. So the right definitions are:
CREATE TABLE Customer (
CustomerId int auto_increment primary key,
. . .
unique (title, firstname, name)
);
Then you can create a correct foreign key relationship to CustomerId:
CustomerId int,
. . .
CONSTRAINT FK_Customer FOREIGN KEY(CustomerId) REFERENCES Customer(CustomerId)
This is "right" because such synthetic keys have several advantages:
Foreign key references are much simpler.
You can change the components easily (changing part of a foreign key requires understanding cascading constraints).
Integers in indexes are more efficient than strings.
Of course, you can do the same with a composite primary key. You just need all three columns in the second table:
Title VARCHAR(30),
Name VARCHAR(100),
FirstName VARCHAR(100),
CONSTRAINT FK_Customer FOREIGN KEY(Title, Name, Firstname) REFERENCES Customer(Title, Name, Firstname)
Your child table's foreign key must contain the same columns, in the same order, as the primary key of the parent table. In your case it would look like
CREATE TABLE `Order`(
Number BIGINT NOT NULL AUTO_INCREMENT,
Title VARCHAR(30) NOT NULL,
Name VARCHAR(100) NOT NULL,
FirstName VARCHAR(100) NOT NULL,
...
CONSTRAINT FK_Customer FOREIGN KEY (Title, Name, FirstName)
REFERENCES Customer (Title, Name, FirstName)
);
Note the columns don't have to be in the same order in the table, just in the constraint's column list.

MySQL multiple fields foreign key referencing to single field

I have languages table which looks like that:
-id
-name
-iso
and in multiple tables I need to reference this iso field as foreign key. The problem is, I can't do it even if I give completely unique FK names. What is problem?
Here is how my Languages table contructed:
CREATE TABLE `Languages` (
`id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
`iso` char(2) NOT NULL,
`name` varchar(255) NOT NULL,
`description` varchar(255) NOT NULL,
`order` tinyint(3) NOT NULL DEFAULT '0',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
Ensure that you have the same column datatype in your parent and child tables. Also create an index on your parent table's iso column. In absence of details in your question about tables you currently have and SQL you used for them, let's take some examples that you can compare with your database.
Example of different datatype:
create table languages (
id int,
name varchar(100),
iso char(3),
primary key(id)
);
create index ix_countries_iso on languages(iso);
create table countries (
id int,
iso int,
foreign key(iso) references languages(iso)
);
ERROR 1215 (HY000): Cannot add foreign key constraint
Example of missing index on parent table:
create table languages (
id int,
name varchar(100),
iso char(3),
primary key(id)
);
-- notice that we aren't creating an index on iso
create table countries (
id int,
iso char(3), -- notice correct datatype in child and parent table
foreign key(iso) references languages(iso)
);
ERROR 1215 (HY000): Cannot add foreign key constraint
What if you have the same datatype in parent and child but lengths are different? I'd recommend keeping the datatype and the length same but the following statements will work:
create table languages (
id int,
name varchar(100),
iso char(3),
primary key(id)
);
create index ix_countries_iso on languages(iso);
create table countries (
id int,
iso char(10), -- will work, but don't do this
foreign key(iso) references languages(iso)
);
create table countries2 (
id int,
iso char(1), -- will work also, but don't do this
foreign key(iso) references languages(iso)
);
Let's take an example of a working solution of foreign keys that you can compare with your database structure:
create table languages (
id int,
name varchar(100),
iso char(3),
primary key(id)
);
create index ix_countries_iso on languages(iso);
create table countries (
id int,
iso char(3), -- same datatype
foreign key fq_countries_languages(iso) references languages(iso)
);
create table boundaries (
id int,
iso char(3), -- same datatype
foreign key fq_boundaries_languages(iso) references languages(iso)
);
I'd also recommend that your child tables that rely on foreign key should be indexed also. Check out a nice little article on foreign keys.