"key column doesn't exist in table" - mysql

I'm making a database in MySQL in class and I'm having trouble adding foreign keys to my tables. I already added most of the foreign keys to my tables when I created the tables but obviously I couldn't add all of them in the creation process. I'm trying to add the remaining foreign keys with the below method.
ALTER TABLE ORDERS
ADD FOREIGN KEY (customer_sid) REFERENCES CUSTOMER(SID);
For some reason the error message listed in the title keeps popping up. The code is below. I can see the tables are coming out a bit funny but if you read them from left to right you can see what it says. What do you think?
mysql> show columns from games;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| gameID | int(11) | NO | PRI | NULL | auto_increment |
| videoGames | varchar(30) | NO | | NULL | |
| year | int(11) | NO | | NULL | |
| genreID | int(11) | NO | MUL | NULL | |
| companyID | int(11) | NO | MUL | NULL | |
| directorID | int(11) | NO | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)
mysql> show columns from consoles;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| consoleID | int(11) | NO | PRI | NULL | auto_increment |
| console | varchar(20) | NO | | NULL | |
| yearReleased | int(11) | NO | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> alter table games
-> add foreign key(consoleID) references consoles(consoleID);
ERROR 1072 (42000): Key column 'consoleID' doesn't exist in table

There is no field consoleID in your table games. You need to create it before trying to add a constraint on it. This will add consoleID and create the constraint:
ALTER TABLE games ADD COLUMN consoleID INTEGER NOT NULL;
ALTER TABLE games ADD FOREIGN KEY (consoleID) REFERENCES consoles(consoleID);
You should think about adding a third table where you associate consoles with games because some games are multiplateform. :)

Related

Properly creating a relational database

I have a database with three tables.
The table Authentication contains the following:
+----------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-----------------+------+-----+---------+----------------+
| id | int(6) unsigned | NO | PRI | NULL | auto_increment |
| userid | varchar(30) | NO | | NULL | |
| password | varchar(30) | NO | | NULL | |
| role | varchar(20) | NO | | NULL | |
| email | varchar(50) | YES | | NULL | |
+----------+-----------------+------+-----+---------+----------------+
Login contains the following:
+--------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-----------------+------+-----+---------+----------------+
| id | int(6) unsigned | NO | PRI | NULL | auto_increment |
| TimeLoggedIn | text | NO | | NULL | |
| sessionid | varchar(255) | NO | | NULL | |
+--------------+-----------------+------+-----+---------+----------------+
And Activity:
+----------+-----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-----------------+------+-----+---------+-------+
| id | int(6) unsigned | NO | PRI | NULL | |
| Torrents | mediumtext | NO | | NULL | |
+----------+-----------------+------+-----+---------+-------+
There is a relation between the id fields of Authentication to id in the other tables.
I need to add multiple rows in Activity, with several values for Torrents for each id. Unfortunately, when I try adding a new row with duplicated id value with:
INSERT INTO `Activity` (`id`, `Torrents`) VALUES ('1', 'dssfsdffdsffs');
it gives me the error: #1062 - Duplicate entry '1' for key 'PRIMARY'
How do I solve it? How did I create the table wrong?
I've read the following apparently duplicate questions:
#1062 - Duplicate entry for key 'PRIMARY'
But though it says to remove it as my primary key, mysql didnt allow me to create a relationship unless I made it a primary key.
You cannot initiate one-to-many relation by referring primary key to primary key. That'll be a one-to-one relationship.
In both your Login and Activity tables you need to have a foreign key to refer back to Authentication's ID. Example:
CONSTRAINT `FK_Login` FOREIGN KEY (`AuthenticationID`) REFERENCES `Authentication` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE

MySQL Workbench; creating intermediate tables and mapping them

I have two tables in MySql Workbench; Categories and Products. I created a third table which contains PK's from the first two tables. How do I sort out which product falls under which category. Do I need to create a fourth table? Also, it is obvious that one category has many products. How do I put this data into the table?
The way I use it in my company is I have a Category table just as you have, a Brands table and a Products table (this is the basic setup, I have more tables for price history, product history, etc).
The Products table is the primary one, containing a foreign key to each of Categories and Brands.
Table tbl_category and tbl_brand has the same structure:
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
Table tbl_product:
+-----------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| category | int(11) | YES | MUL | NULL | |
| brand | int(11) | YES | MUL | NULL | |
| spec | varchar(100) | YES | | NULL | |
| descript | varchar(1000) | YES | | NULL | |
| unit | varchar(10) | YES | | PÇ | |
| cost | decimal(16,2) | YES | | NULL | |
| ..................................................................|
| |
+-----------+---------------+------+-----+---------+----------------+
And I have the following foreign keys:
KEY `product_category_fk` (`category`),
KEY `product_brand_fk` (`brand`),
CONSTRAINT `product_brand_fk` FOREIGN KEY (`brand`) REFERENCES `tbl_brand` (`id`) ON UPDATE CASCADE,
CONSTRAINT `product_category_fk` FOREIGN KEY (`category`) REFERENCES `tbl_category` (`id`) ON UPDATE CASCADE
The reasoning I used is: any given product has only one category and one brand, so I can put that information in the product record itself.
This is a good example starting point (Taken from here)

How to add a foreign key to an existing table?

I am trying to add Category_Name as a foreign key to the ITEM table. Category_Name exists in CATEGORY table and this is what i get:
mysql> use acmeonline;
Database changed
mysql> show tables;
+----------------------+
| Tables_in_acmeonline |
+----------------------+
| category |
| item |
+----------------------+
2 rows in set (0.00 sec)
mysql> describe item;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| Item_Number | int(11) | NO | PRI | 0 | |
| Item_Name | varchar(35) | YES | | NULL | |
| Model_Num | varchar(15) | YES | | NULL | |
| Description | varchar(255) | YES | | NULL | |
| Price | double(8,2) | YES | | NULL | |
+-------------+--------------+------+-----+---------+-------+
5 rows in set (0.07 sec)
mysql> describe category;
+------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-------------+------+-----+---------+-------+
| Category_Name | varchar(35) | NO | PRI | | |
| ShippingPerPound | double(4,2) | YES | | NULL | |
| DiscountAllowed | char(1) | YES | | NULL | |
+------------------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> ALTER TABLE item
-> ADD CONSTRAINT fk_category_name
-> FOREIGN KEY(Category_Name)
-> REFERENCES Category(Category_Name);
ERROR 1072 (42000): Key column 'Category_Name' doesn't exist in table
How do I fix this? Please bear with me because I did look at some sites on how to do it, but I get the same results.
You need to add the CATEGORY_NAME column on ITEM TABLE, or map the foreign key to another existing column in ITEM.
Either:
ALTER TABLE ITEM
ADD CATEGORY_NAME VARCHAR(35) NOT NULL;
ALTER TABLE ITEM
ADD CONSTRAINT FK_CATEGORY_NAME
FOREIGN KEY (CATEGORY_NAME)
REFERENCES CATEGORY (CATEGORY_NAME);
OR
ALTER TABLE ITEM
ADD CONSTRAINT FK_CATEGORY_NAME
FOREIGN KEY (SOME_OTHER_EXISTING_COLUMN)
REFERENCES CATEGORY (CATEGORY_NAME);
You must first add the column in a separate alter statement:
alter table item add column category_name varchar(35);
Foreign key constraints only create a relationship between tables - they don't also create the column(s) involved.

How to create a table that automaticly updates another table when content is changed?

What I try to accomplish is that I want to update rows in tableA when one row from tableB gets deleted.
The layout of tableA is this:
+----------------------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+--------------+------+-----+---------------------+----------------+
| user_id | int(11) | NO | PRI | NULL | auto_increment |
| nickname | varchar(32) | NO | | NULL | |
| password | varchar(129) | NO | | NULL | |
| mafia_id | int(11) | NO | | 0 | |
+----------------------------+--------------+------+-----+---------------------+----------------+
and of tableB this:
+-------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+----------------+
| mafia_id | int(11) | NO | PRI | NULL | auto_increment |
| mafia_name | varchar(32) | NO | | | |
| mafia_tag | varchar(5) | NO | | | |
| mafia_color | int(11) | NO | | 0 | |
| mafia_car | int(11) | NO | | 0 | |
| mafia_base | int(11) | NO | | 0 | |
+-------------+-------------+------+-----+---------+----------------+
I want to set all tableA.mafia_id to 0 when the corresponding mafia_id in tableB is deleted.
I read in the documentation that the database will automaticly do it for you, but you have to specify some stuff at table creation (in CREATE TABLE, create_definition: | CHECK (expr)?). The documentation is a bit unclear to me.
I also read this topic:
Create a trigger that updates a column on one table when a column in another table is updated
but this doesn't apply to me, i think?
So how would I create such a table (create table ...) or delete row statement?
Thanks in advance!
Since you are using InnoDB, you can achieve this with a foreign key constraint:
ALTER TABLE tableA
MODIFY mafia_id INT(11) NULL,
ADD FOREIGN KEY (mafia_id) REFERENCES tableB (mafia_id) ON DELETE SET NULL
As explained in the manual:
SET NULL: Delete or update the row from the parent table and set the foreign key column or columns in the child table to NULL. This is valid only if the foreign key columns do not have the NOT NULL qualifier specified. Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported.
If you specify a SET NULL action, make sure that you have not declared the columns in the child table as NOT NULL.
Note that the constraint has the additional advantage of ensuring that mafia_id values in tableA must always reference an existing record in tableB.

alter table if fields is not already exist

alter table if field is not already exist
ALTER TABLE `table`
ADD( `abc` text NOT NULL,
`xyz` tinyint(1) NOT NULL,
);
if abc or xyz fields are already exist the can not be alter table
if it is possible ?
You can use a SHOW COLUMNS beforehand and construct your query accordingly, adding only fields that are missing.
Example output of SHOW COLUMNS:
mysql> SHOW COLUMNS FROM City;
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| Id | int(11) | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| Country | char(3) | NO | UNI | | |
| District | char(20) | YES | MUL | | |
| Population | int(11) | NO | | 0 | |
+------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
I can't comment yet, so I post answer: try this link for detailed example. It queries information_schema.COLUMNS table for column information about database tables.