I'm trying to create a MySQL schema for a simple online shop. My existing tables are as follows:
user — user info
address — address info for users
product — product info
purchase — a shopping chart created and purchased by a user
I've created these tables using the following SQL code:
CREATE TABLE user(
user_id INT AUTO_INCREMENT,
first_name VARCHAR(20) NOT NULL,
middle_name VARCHAR(20) NOT NULL,
last_name VARCHAR(20) NOT NULL,
email VARCHAR(40) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
registered BOOLEAN NOT NULL,
phone VARCHAR(12),
PRIMARY KEY(user_id)
);
CREATE TABLE product(
product_id INT AUTO_INCREMENT,
name VARCHAR(40) NOT NULL UNIQUE,
price DECIMAL(5,2) NOT NULL,
description VARCHAR(100) UNIQUE,
PRIMARY KEY(product_id)
);
CREATE TABLE address(
user_id INT,
address_id INT,
city VARCHAR(15) NOT NULL,
district VARCHAR(20) NOT NULL,
details VARCHAR(50) NOT NULL,
is_default BOOLEAN NOT NULL,
FOREIGN KEY(user_id) REFERENCES user(user_id) ON DELETE CASCADE,
PRIMARY KEY(user_id, address_id)
);
CREATE TABLE purchase(
purchase_id INT AUTO_INCREMENT,
user_id INT,
total_price DECIMAL(8,2) NOT NULL,
state ENUM('placed', 'paid', 'shipped', 'received', 'completed', 'cancelled') DEFAULT 'placed',
user_name VARCHAR(40) NOT NULL,
full_address VARCHAR(85) NOT NULL,
FOREIGN KEY(user_id) REFERENCES user(user_id) ON DELETE SET NULL,
PRIMARY KEY(purchase_id)
);
Now I'm trying to create a final table to store individual items in a shopping chart like this:
CREATE TABLE purchase_item(
purchase_id INT,
product_id INT,
product_name VARCHAR(40) NOT NULL,
amount DECIMAL(4,2) NOT NULL,
price DECIMAL(8,2) NOT NULL,
FOREIGN KEY(purchase_id) REFERENCES purchase(purchase_id) ON DELETE CASCADE,
FOREIGN KEY(product_id) REFERENCES product(product_id) ON DELETE SET NULL,
PRIMARY KEY(purchase_id, product_id)
);
But I get the following error:
ERROR 1215 (HY000): Cannot add foreign key constraint
I don't any errors if I update the foreign key for products as follows:
FOREIGN KEY(product_id) REFERENCES product(product_id) ON DELETE CASCADE,
I want the purchase_item to be deleted if the corresponding purchase gets deleted, but not when the corresponding product gets deleted.
https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html says:
If you specify a SET NULL action, make sure that you have not declared the columns in the child table as NOT NULL.
But your purchase_item.product_id column is part of that table's primary key, which implicitly makes the column NOT NULL.
You cannot use the SET NULL action for the primary key on that column.
Related
I'm working on building a small database and am running into a syntax error on these two lines in my last table.
They're foreign keys and those lines didn't produce any errors in the tables where they originally appeared.
INVOICE_ID INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
DONUT_ID VARCHAR(10) NOT NULL UNIQUE,
These two lines are the PK and FK in the table, and I think this is where I'm running into the problem because I used the same syntax as I did in earlier tables that aren't generating any errors.
Here is the full code for four tables:
CREATE TABLE CUSTOMER (
CUST_ID INT NOT NULL AUTO_INCREMENT UNIQUE,
CUST_LNAME VARCHAR(25) NOT NULL,
CUST_FNAME VARCHAR(25) NOT NULL,
CUST_INITIAL CHAR(1),
CUST_STREET_NO VARCHAR(6),
CUST_STREET_NAME VARCHAR(25),
CUST_APT_NO VARCHAR(10),
CUST_CITY VARCHAR(25),
CUST_STATE CHAR(2),
CUST_ZIP_CODE CHAR(5),
CUST_HOME_AC CHAR(3),
CUST_HOME_PHONE CHAR(8),
PRIMARY KEY (CUST_ID)
)ENGINE = InnoDB;
CREATE TABLE INVOICE (
INVOICE_ID INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
CUST_ID INTEGER NOT NULL,
INV_DATE DATE NOT NULL,
SPECIAL_HANDLING VARCHAR(35),
PRIMARY KEY (INVOICE_ID),
FOREIGN KEY (CUST_ID) REFERENCES CUSTOMER(CUST_ID) ON UPDATE CASCADE
)ENGINE = InnoDB;
CREATE TABLE PRODUCT (
DONUT_ID VARCHAR(10) NOT NULL UNIQUE,
DONUT_NAME VARCHAR(25) NOT NULL,
DONUT_DESC VARCHAR(35) NOT NULL,
DONUT_PRICE DECIMAL(13,2) NOT NULL,
PRIMARY KEY (DONUT_ID)
)ENGINE = InnoDB;
CREATE TABLE INVOICE LINE ITEM (
INVOICE_ID INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
DONUT_ID VARCHAR(10) NOT NULL UNIQUE,
DONUT_QTY INTEGER NOT NULL,
PRIMARY KEY (INVOICE_ID, DONUT_ID),
FOREIGN KEY (INVOICE_ID) REFERENCES INVOICE(INVOICE_ID) ON UPDATE CASCADE,
FOREIGN KEY (DONUT_ID) REFERENCES PRODUCT(DONUT_ID) ON UPDATE CASCADE
)ENGINE = InnoDB;
The fourth CREATE TABLE statement will fail because of the spaces in the table name:
CREATE TABLE INVOICE LINE ITEM ...
You should use a different name, without spaces. For example you could replace the spaces with underscores and use snake-case:
CREATE TABLE INVOICE_LINE_ITEM ...
I am trying to do inserts into my database to "populate" it, and all inserts work fine, except for the "reservation" insert...
When I try to insert my reservation table:
Insert Into Reservation
(ReservNum, ReserveDate, NumOfPassengers, sheduledTime, ActualPickupTime, ActualTime, PricePaid, HourlyRate, SalaryEarned)
VALUES
('24333', '2015-10-15', '6', '20', '7:04', '22', '$15', '34', '$12.47');
I get this error:
Cannot add or update a child row: a foreign key constraint fails (`oma`.`Reservation`, CONSTRAINT `Reservation_ibfk_1` FOREIGN KEY (`Customer_CustomerID`) REFERENCES `Customer` (`CustomerID`))
Here are my create tables:
CREATE TABLE Customer (
CustomerID INT AUTO_INCREMENT,
Name VARCHAR(90) NOT NULL,
Phone VARCHAR(45) NULL,
PRIMARY KEY (CustomerID));
CREATE TABLE Location (
Address VARCHAR(100) NOT NULL,
Latitude VARCHAR(45) NOT NULL DEFAULT ' ',
Longitude VARCHAR(45) NOT NULL,
PRIMARY KEY (Address));
CREATE TABLE Employee (
EmployeeID INT AUTO_INCREMENT,
Name VARCHAR(90) NOT NULL,
PRIMARY KEY (EmployeeID));
CREATE TABLE Truck (
LicensePlate CHAR(20) NOT NULL,
color VARCHAR(45) NULL,
capacity VARCHAR(45) NULL,
PRIMARY KEY (LicensePlate));
CREATE TABLE Shifts (
ShiftTime DATETIME NOT NULL,
PRIMARY KEY (ShiftTime));
CREATE TABLE EmployeeShifts (
DesiredShift DATETIME NOT NULL,
EmployeeWorking INT NULL,
DateOfShift DATE,
PRIMARY KEY(DesiredShift, EmployeeWorking),
FOREIGN KEY (EmployeeWorking) REFERENCES Employee(EmployeeID),
FOREIGN KEY (DesiredShift) REFERENCES Shifts(ShiftTime));
CREATE TABLE Reservation (
ReservNum INT NOT NULL,
ReserveDate DATE NULL,
PickupTime VARCHAR(45) NOT NULL,
NumOfPassengers INT NULL,
sheduledTime VARCHAR(45) NULL,
ActualPickupTime VARCHAR(45),
ActualTime VARCHAR(45),
SalaryEarned VARCHAR(10),
PricePaid VARCHAR(45),
HourlyRate DECIMAL(7,2) NOT NULL,
Customer_CustomerID INT AUTO_INCREMENT,
Truck_LicensePlate char(20) NOT NULL,
Employee_EmployeeID_Driver INT,
Location_Address_Pickup VARCHAR(100),
Employee_EmployeeID_Passenger INT,
Location_Address_Drop VARCHAR(100),
PRIMARY KEY (ReservNum),
FOREIGN KEY (Customer_CustomerID) REFERENCES Customer (CustomerID),
FOREIGN KEY (Truck_LicensePlate) REFERENCES Truck (LicensePlate),
FOREIGN KEY (Employee_EmployeeID_Driver) REFERENCES Employee (EmployeeID),
FOREIGN KEY (Location_Address_Pickup) REFERENCES Location (Address),
FOREIGN KEY (Employee_EmployeeID_Passenger) REFERENCES Employee (EmployeeID),
FOREIGN KEY (Location_Address_Drop) REFERENCES Location (Address));
The Customer_Customer_ID column in Reservation is an AUTO INCREMENT:
Customer_CustomerID INT AUTO_INCREMENT,
meaning that if you don't specify the value when INSERT-ing, one will be automatically assigned to it. You didn't specify it in the INSERT and so the value automatically assigned to it didn't exist in the Customers table, which violated the FOREIGN KEY constraint:
FOREIGN KEY (Customer_CustomerID) REFERENCES Customer (CustomerID),
To solve this,
Remove the AUTO_INCREMENT from the Customer_CustomerID column. You should be able to insert now, since the column can be NULL, in which case the FOREIGN KEY is not an issue.
Or, if you want to assign a Customer to the Reservation, make sure a row exists in the Customer table, and pass the Customer_Id to the INSERT INTO Reservation. For instance, like this:
INSERT INTO Customers( Name ) VALUES ('Test');
INSERT INTO Reservation (
ReservNum, Customer_Customer_ID,
ReserveDate, NumOfPassengers,
sheduledTime, ActualPickupTime, ActualTime,
PricePaid, HourlyRate, SalaryEarned
)
VALUES (
'24333', LAST_INSERT_ID(),
'2015-10-15', '6',
'20', '7:04', '22',
'$15', '34', '$12.47'
);
The LAST_INSERT_ID() gets the value from the AUTO_INCREMENT column in the last INSERT.
When I try to source these tables into MySQL, and it created all the tables. Then I start to populate the tables, and it will not let me populate the last table Rental_Invoice. Any suggestions?
The error is
ERROR 1452 (23000): Cannot add or update a child row: a foreign key
constraint fails (SFRC_HIDDEN.Rental_Invoice, CONSTRAINT
Rental_Invoice_fk_Client_Contact FOREIGN KEY (Client_ID)
REFERENCES Client_Contact (Client_ID))
create table Client_Contact
(
Client_ID int Primary Key Auto_Increment,
Client_First_Name varchar(50) Not Null,
Client_Last_Name varchar(50) Not Null,
Client_Address varchar(50),
Client_City varchar(50) Not Null,
Client_State Char(2) Not Null,
Client_Zip_Code varchar(20) Not Null,
Client_Phone varchar(20),
Client_Email varchar(30)
);
create table Owner_Contact
( Owner_ID int Primary Key,
Owner_First_Name varchar(50) Not Null,
Owner_Last_Name varchar(50) Not Null,
Owner_Address varchar(50),
Owner_City varchar(50) Not Null,
Owner_State varchar(2) Not Null,
Owner_Zip_Code varchar(20) Not Null,
Owner_Phone varchar(20),
Owner_Email varchar(30)
);
create table Property_Info
(Property_ID varchar(20) Primary Key,
Owner_ID int Not Null,
Property_Type varchar(30) Not Null,
Pets set('Yes','No') Not Null,
Internet set('yes','No') Not Null,
constraint Property_Info_fk_Owner_Contact
foreign key (Owner_ID)
references Owner_Contact (Owner_ID));
create table Rental_Invoice
( Invoice_ID int Primary Key,
Property_ID varchar(10) Not Null,
Client_ID int Not Null,
Arrival_Date date Not Null,
Departure_Date date Not Null,
Deposit_Amount decimal(5,2) Not Null,
Pet_Deposit_Amount decimal(7,2),
Pet_Type enum('cat', 'dog', ''),
Cleaning_Fee decimal(5,2) Not Null,
Rental_Rate decimal(5,2) Not Null,
Method_Of_Payment varchar(20) Not Null,
constraint Rental_Invoice_fk_Client_Contact foreign key (Client_ID) references Client_Contact (Client_ID)
);
Initial problem
Just a random guess since I don't have MySQL installed anywhere at the moment. But Client_ID in the dependent table is a VARCHAR and it refers to an INTEGER column in the parent table.
After Edit
The foreign key constraint is caused by inserting a row into Rental_Invoice that does not have a corresponding row in Client_Contact. In other words, your data violates the Rental_Invoice_fk_Client_Contact foreign key constraint that requires that Rental_Invoice.Client_ID refers to an existing row in Client_Contact with a matching Client_ID.
I am having trouble adding a customer and their order to an order table once they have checked out.
Here is my SQL for creating the four tables I am using:
CREATE TABLE IF NOT EXISTS Product(
ID int NOT NULL AUTO_INCREMENT,
Name varchar(255) NOT NULL,
Description text(65535) NOT NULL,
Quantity int NOT NULL,
Photo varchar(255),
Price float NOT NULL,
Category varchar(50),
PRIMARY KEY (ID)
) ENGINE=innoDB;
CREATE TABLE IF NOT EXISTS Customer(
ID int NOT NULL AUTO_INCREMENT,
FirstName varchar(255) NOT NULL,
LastName varchar(255) NOT NULL,
Email varchar(255) NOT NULL,
PhoneNumber varchar(11) NOT NULL,
Address varchar(50),
Town varchar(50),
County varchar(50),
PostCode varchar(50),
PRIMARY KEY (ID)
) ENGINE=innoDB;
CREATE TABLE IF NOT EXISTS OrderTable(
ID int NOT NULL AUTO_INCREMENT,
Date date NOT NULL,
PRIMARY KEY (ID),
TotalPrice float NOT NULL,
Customer_ID int NOT NULL,
CONSTRAINT fk_Order_1
FOREIGN KEY (Customer_ID)
REFERENCES coursework_db.Customer (ID)
) ENGINE=innoDB;
CREATE TABLE IF NOT EXISTS OrderItem(
ID int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (ID),
Product_ID int NOT NULL,
Order_ID int NOT NULL,
Quantity int NOT NULL,
TotalPrice float NOT NULL,
CONSTRAINT fk_OrderItem_1
FOREIGN KEY (Product_ID)
REFERENCES coursework_db.Product(ID),
CONSTRAINT fk_OrderItem_2
FOREIGN KEY (Order_ID)
REFERENCES coursework_db.OrderTable(ID)
) ENGINE=innoDB;
The problem I am having is how to select the customer from the table once they have been added to the database to use as a foreign key in the OrderTable table.
At the moment I have the details of the customer stored in local storage which can easily be accessed, but once the customer is added to the database they will get an ID. This is the only way I could think to select a unique customer.
Insert the customer details first. Then get the ID of the newly inserted customer and use it while inserting the order details!
You could use the LAST_INSERT_ID() after you insert the user details to the db to get the ID of the customer.
Or if you are using PHP, then:
if you're using PDO, use PDO::lastInsertId
if you're using Mysqli, use mysqli::$insert_id
Hope this helps.
I am having trouble with mapping things on separate tables of data. There will be tables for DEPARTMENT_LOCATIONS, DEPARTMENT, EMPLOYEE, and PROJECT.
So far all of the tables are created other that PROJECT, because I am receiving the error message for the title of my question.
Below is the information that I used to create the tables that were created without errors:
EMPLOYEE Table:
CREATE TABLE EMPLOYEE
(FNAME VARCHAR(25) NOT NULL,
MINIT CHAR(1),
LNAME VARCHAR(25) NOT NULL,
SSN NUMBER(10) NOT NULL,
BDATE DATE NOT NULL,
ADDRESS VARCHAR(30) NOT NULL,
SEX CHAR(1) NOT NULL,
SALARY DECIMAL(6,2) NOT NULL,
SUPERSSN NUMBER(10),
DNO NUMBER (1) NOT NULL,
PRIMARY KEY (SSN),
FOREIGN KEY (DNO) REFERENCES DEPT_LOCATIONS(DNUMBER));
DEPARTMENT_LOCATIONS Table:
CREATE TABLE DEPT_LOCATIONS
(DNUMBER NUMBER(1) NOT NULL,
DLOCATION VARCHAR(25) NOT NULL,
PRIMARY KEY (DNUMBER));
DEPARTMENT Table:
CREATE TABLE DEPARTMENT
(DNUMBER NUMBER(1) NOT NULL,
DNAME VARCHAR(25) NOT NULL,
MGRSTARTDATE DATE NOT NULL,
MGRSSN NUMBER(10) NOT NULL,
PRIMARY KEY (DNUMBER),
FOREIGN KEY (DNUMBER) REFERENCES DEPT_LOCATIONS(DNUMBER),
FOREIGN KEY (MGRSSN) REFERENCES EMPLOYEE(SSN));
Now when I enter the following information for the PROJECT Table, I receive the error message "ORA-02270: no matching unique or primary key for this column-list.)
CREATE TABLE PROJECT
(PNUMBER NUMBER(2,1) NOT NULL PRIMARY KEY,
PNAME VARCHAR(25) NOT NULL,
PLOCATION VARCHAR(25) NOT NULL,
DNUM NUMBER(1) NOT NULL,
FOREIGN KEY (PLOCATION) REFERENCES DEPT_LOCATIONS(DLOCATION),
FOREIGN KEY (DNUM) REFERENCES DEPT_LOCATIONS(DNUMBER));
Why is this error occurring and what do I need to do to correct it? Thank you.
You have to declare dlocation as unique, inorder to reference it in another table.
CREATE TABLE DEPT_LOCATIONS
(DNUMBER NUMBER(1) NOT NULL,
DLOCATION VARCHAR(25) UNIQUE,
PRIMARY KEY (DNUMBER));