SQL Error, unable to create table on a certain format - mysql

I am facing an error when creating a table between the following two statement
CREATE TABLE SECTION (
cid varchar(10) not null,
sno varchar(3) not null,
primary key (cid, sno),
foreign key (cid) references COURSE (cid)
);
CREATE TABLE ROUND_RELEASE (
cid varchar(10) not null,
sno varchar(3) not null,
rid int not null,
foreign key (cid) references SECTION (cid),
foreign key (sno) references SECTION (sno),
foreign key (rid) references ROUND (rid)
);
Error Code: 1822. Failed to add the foreign key constraint. Missing index for constraint 'round_release_ibfk_2' in the referenced table 'section'
However, when I try to swap the primary key order in SECTION table, I am able to create both table without error
CREATE TABLE SECTION (
cid varchar(10) not null,
sno varchar(3) not null,
primary key (**sno, cid**),
foreign key (cid) references COURSE (cid)
);
CREATE TABLE ROUND_RELEASE (
cid varchar(10) not null,
sno varchar(3) not null,
rid int not null,
foreign key (cid) references SECTION (cid),
foreign key (sno) references SECTION (sno),
foreign key (rid) references ROUND (rid)
);
The follow code above works, and I only swap the attribute, from my knowledge, the order does not matter, thus I am quite puzzled by why is this occurring.
Any guidance on this? Thanks!

Based on the error message, I assume that you are using MySQL.
What you are seeing is a documented behavior:
In the referenced table, there must be an index where the referenced columns are the first columns in the same order.
Let me pinpoint, however, that your code probably does not do what you really want. You probably should be creating a compound foreign key, that references the tuples of columns, rather than one foreign key per column:
create table round_release (
cid varchar(10) not null,
sno varchar(3) not null,
rid int not null,
foreign key (cid, sno) references section(cid, sno),
foreign key (rid) references round(rid)
);
One last thing to note is that your round_release table has no primary key defined; this is not a good practice, and might hurt you in several ways in the future. So, do create a primary key for the table, either as a separate column (possibly auto-incremented), or as a combination of existing columns.

Related

Mysql Cannot add foreign key constraint weird error [duplicate]

I have to create this table with all these composite keys.
prospect(custname, carmake, carmodel, caryear, carextcolour, cartrim, optioncode)
All the fields above are underlined to show they are primary. So 7 primary composite keys.
For some reason this does not create the table.
CREATE TABLE prospect
(Custname VARCHAR(25) NOT NULL,
Carmake VARCHAR(25) NOT NULL,
Carmodel VARCHAR(20) NOT NULL,
Caryear VARCHAR(4) NOT NULL,
Carextcolour VARCHAR(10) NOT NULL,
Cartrim VARCHAR(10) NOT NULL,
Optioncode CHAR(4),
CONSTRAINT pkprospect PRIMARY KEY (Custname, Carmake, Carmodel, Caryear, Carextcolour, Cartrim, Optioncode),
CONSTRAINT fkprospect FOREIGN KEY (Custname) REFERENCES customer(Custname),
CONSTRAINT fk2prospect FOREIGN KEY (Carmake) REFERENCES car(Carmake),
CONSTRAINT fk3prospect FOREIGN KEY (Carmodel) REFERENCES car(Carmodel),
CONSTRAINT fk4prospect FOREIGN KEY (Caryear) REFERENCES car(Caryear),
CONSTRAINT fk5prospect FOREIGN KEY (Carextcolour) REFERENCES car(Carextcolour),
CONSTRAINT fk6prospect FOREIGN KEY (Cartrim) REFERENCES car(Cartrim),
CONSTRAINT fk7prospect FOREIGN KEY (Optioncode) REFERENCES optiontable(Optioncode)
);
the code i'm using to create this table full of composite keys.
You should make one foreign key constraint referencing the full primary or unique key of each referenced table. You can't make separate foreign keys to individual columns in the middle of the references table's primary key.
CREATE TABLE prospect
(Custname VARCHAR(25) NOT NULL,
Carmake VARCHAR(25) NOT NULL,
Carmodel VARCHAR(20) NOT NULL,
Caryear VARCHAR(4) NOT NULL,
Carextcolour VARCHAR(10) NOT NULL,
Cartrim VARCHAR(10) NOT NULL,
Optioncode CHAR(4),
CONSTRAINT pkprospect PRIMARY KEY (Custname, Carmake, Carmodel, Caryear, Carextcolour, Cartrim, Optioncode),
CONSTRAINT fkprospect FOREIGN KEY (Custname) REFERENCES customer(Custname),
CONSTRAINT fk2prospect FOREIGN KEY (Carmake, Carmodel, Caryear, Carextcolour, Cartrim)
REFERENCES car(Carmake, Carmodel, Caryear, Carextcolour, Cartrim),
CONSTRAINT fk7prospect FOREIGN KEY (Optioncode) REFERENCES optiontable(Optioncode)
);
I used the word should above because InnoDB is actually a bit more lenient than the ANSI/ISO SQL standard when it comes to foreign keys. Standard SQL says the columns of the foreign key must be the full list of columns of the referenced primary or unique key.
InnoDB permits you to use a subset of columns, as long as they're a left-prefix of those columns. But you shouldn't do that, because you get really confusing results when a child row may reference multiple rows in its parent table.
Try this: Creating table with primary key for the first step and then use alter table command for foreign keys and add them.
If you have not created the reference tables, you cannot create this table. You can first create all your reference tables and then enter FK submissions with alter table.

How do I make a column not null and be a foreign key in MySQL

I am trying to create a table that is a foreign key of another table and make it not null, but I am running into trouble making both happen. I was able to successfully get foreign keys working that did not require NOT NULL but I can't get both working.
Here is the line giving me trouble
CONSTRAINT instructor FOREIGN KEY (id) REFERENCES Instructor(id) NOT NULL
then I get the error:
CONSTRAINT instructor FOREIGN KEY (id) REFERENCES Instructor(id) NOT NULL,
*
ERROR at line 5:
ORA-00907: missing right parenthesis
Also, I am getting a weird error when trying to create a table (note, this table is created after creating the table that contains the above error) where it fails at a very trivial part:
CREATE TABLE Enrollment (
CONSTRAINT class_id FOREIGN KEY (id) REFERENCES Class(id) NOT NULL,
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id) NOT NULL,
cost int NOT NULL
);
Then for that command I get this error:
CREATE TABLE Enrollment (
*
ERROR at line 1:
ORA-00904: : invalid identifier
How can I fix these two errors?
You need to create the column before you try creating constraints on the column.
You have:
CREATE TABLE Enrollment (
CONSTRAINT class_id FOREIGN KEY (id) REFERENCES Class(id) NOT NULL,
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id) NOT NULL,
cost int NOT NULL
);
You need:
CREATE TABLE Enrollment (
id INT NOT NULL CONSTRAINT class_id REFERENCES Class(id),
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id),
cost INT NOT NULL
);
Note that in the first line, the FOREIGN KEY isn't necessary because the column is implied. In the second line, the id is identified. You could also write:
CREATE TABLE Enrollment
(
id INT NOT NULL,
CONSTRAINT class_id FOREIGN KEY (id) REFERENCES Class(id),
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id),
cost INT NOT NULL
);
It is unusual, though not automatically wrong, to make a single column (id) be a foreign key of two tables simultaneously. It isn't clear if you actually want three columns in your table — and if you do, which column names are in your table.
You could also use the appropriate notation for an automatically allocated type in MySQL syntax (SERIAL instead of INT NOT NULL, or add AUTO_INCREMENT, etc).
Maybe you're really after:
CREATE TABLE Enrollment
(
id SERIAL,
class_id INT NOT NULL CONSTRAINT class_id REFERENCES Class(id),
member_id INT NOT NULL CONSTRAINT member_id REFERENCES RecCenterMember(id),
cost INT NOT NULL
);
This makes more sense in general. You're creating a new enrollment record for a pre-existing class, and for a pre-existing recreation centre member, and recording its cost.
Syntax diagrams vs actual behaviour
If, as Michael - sqlbot suggests — and I've no reason whatsoever to disbelieve him — MySQL recognizes but does not respond to the REFERENCES clause in a column definition in a CREATE TABLE statement but only acts on full FOREIGN KEY clauses, then you have to adjust my suggested answers from their syntactically correct but semantically ignored form to something like:
Option 1 (minimally changing the SQL from the question):
CREATE TABLE Enrollment (
id INT NOT NULL,
CONSTRAINT class_id FOREIGN KEY (id) REFERENCES Class(id),
CONSTRAINT member_id FOREIGN KEY (id) REFERENCES RecCenterMember(id),
cost int NOT NULL
);
Option 2 (what I consider the most plausible version):
CREATE TABLE Enrollment
(
id SERIAL,
class_id INT NOT NULL,
CONSTRAINT fk_class_id FOREIGN KEY (class_id) REFERENCES Class(id),
member_id INT NOT NULL,
CONSTRAINT fk_member_id FOREIGN KEY (member_id) REFERENCES RecCenterMember(id),
cost INT NOT NULL
);
Or some other variant of this syntax based on the desired table schema ignoring the FK constraints, then adding the constraints along the lines shown.
Key Point
You must define the columns before you define the foreign keys based on those columns.

MySQL - Error Code 1215, cannot add foreign key constraint

i got these two succesfull queries:
create table Donors (
donor_id int not null auto_increment primary key,
gender varchar(1) not null,
date_of_birth date not null,
first_name varchar(20) not null,
middle_name varchar(20),
last_name varchar(30) not null,
home_phone tinyint(10),
work_phone tinyint(10),
cell_mobile_phone tinyint(10),
medical_condition text,
other_details text );
and
create table Donors_Medical_Condition (
donor_id int not null,
condition_code int not null,
seriousness text,
primary key(donor_id, condition_code),
foreign key(donor_id) references Donors(donor_id) );
but when i try this one:
create table Medical_Conditions (
condition_code int not null,
condition_name varchar(50) not null,
condition_description text,
other_details text,
primary key(condition_code),
foreign key(condition_code) references Donors_Medical_Condition(condition_code) );
i get "Error Code: 1215, cannot add foreign key constraint"
i dont know what am i doing wrong.
In MySql, a foreign key reference needs to reference to an index (including primary key), where the first part of the index matches the foreign key field. If you create an an index on condition_code or change the primary key st that condition_code is first you should be able to create the index.
To define a foreign key, the referenced parent field must have an index defined on it.
As per documentation on foreign key constraints:
REFERENCES tbl_name (index_col_name,...)
Define an INDEX on condition_code in parent table Donors_Medical_Condition and it should be working.
create table Donors_Medical_Condition (
donor_id int not null,
condition_code int not null,
seriousness text,
KEY ( condition_code ), -- <---- this is newly added index key
primary key(donor_id, condition_code),
foreign key(donor_id) references Donors(donor_id) );
But it seems you defined your tables order and references wrongly.
You should have defined foreign key in Donors_Medical_Condition table but not in Donors_Medical_Conditions table. The latter seems to be a parent.
Modify your script accordingly.
They should be written as:
-- create parent table first ( general practice )
create table Medical_Conditions (
condition_code int not null,
condition_name varchar(50) not null,
condition_description text,
other_details text,
primary key(condition_code)
);
-- child table of Medical_Conditions
create table Donors_Medical_Condition (
donor_id int not null,
condition_code int not null,
seriousness text,
primary key(donor_id, condition_code),
foreign key(donor_id) references Donors(donor_id),
foreign key(condition_code)
references Donors_Medical_Condition(condition_code)
);
Refer to:
MySQL Using FOREIGN KEY Constraints
[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name, ...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION
A workaround for those who need a quick how-to:
FYI: My issue was NOT caused by the inconsistency of the columns’ data types/sizes, collation or InnoDB storage engine.
How to:
Download a MySQL workbench and use it’s GUI to add foreign key. That’s it!
Why:
The error DOES have something to do with indexes. I learned this from the DML script automatically generated by the MySQL workbench. Which also helped me to rule out all those inconsistency possibilities.It applies to one of the conditions to which the foreign key definition subject. That is: “MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan.” Here is the official statement: http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html
I did not get the idea of adding an index ON the foreign key column(in the child table), only paid attention to the referenced TO column(in the parent table).
Here is the auto-generated script(PHONE.PERSON_ID did not have index originally):
ALTER TABLE `netctoss`.`phone`
ADD INDEX `personfk_idx` (`PERSON_ID` ASC);
ALTER TABLE `netctoss`.`phone`
ADD CONSTRAINT `personfk`
FOREIGN KEY (`PERSON_ID`)
REFERENCES `netctoss`.`person` (`ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
I think you've got your tables a bit backwards. I'm assuming that Donors_Medical_Condtion links donors and medical conditions, so you want a foreign key for donors and conditions on that table.
UPDATED
Ok, you're also creating your tables in the wrong order. Here's the entire script:
create table Donors (
donor_id int not null auto_increment primary key,
gender varchar(1) not null,
date_of_birth date not null,
first_name varchar(20) not null,
middle_name varchar(20),
last_name varchar(30) not null,
home_phone tinyint(10),
work_phone tinyint(10),
cell_mobile_phone tinyint(10),
medical_condition text,
other_details text );
create table Medical_Conditions (
condition_code int not null,
condition_name varchar(50) not null,
condition_description text,
other_details text,
primary key(condition_code) );
create table Donors_Medical_Condition (
donor_id int not null,
condition_code int not null,
seriousness text,
primary key(donor_id, condition_code),
foreign key(donor_id) references Donors(donor_id),
foreign key(condition_code) references Medical_Conditions(condition_code) );
I got the same issue and as per given answers, I verified all datatype and reference but every time I recreate my tables I get this error. After spending couple of hours I came to know below command which gave me inside of error-
SHOW ENGINE INNODB STATUS;
LATEST FOREIGN KEY ERROR
------------------------
2015-05-16 00:55:24 12af3b000 Error in foreign key constraint of table letmecall/lmc_service_result_ext:
there is no index in referenced table which would contain
the columns as the first columns, or the data types in the
referenced table do not match the ones in table. Constraint:
,
CONSTRAINT "fk_SERVICE_RESULT_EXT_LMC_SERVICE_RESULT1" FOREIGN KEY ("FK_SERVICE_RESULT") REFERENCES "LMC_SERVICE_RESULT" ("SERVICE_RESULT") ON DELETE NO ACTION ON UPDATE NO ACTION
I removed all relation using mysql workbench but still I see same error. After spending few more minutes, I execute below statement to see all constraint available in DB-
select * from information_schema.table_constraints where
constraint_schema = 'XXXXX'
I was wondering that I have removed all relationship using mysql workbench but still that constraint was there. And the reason was that because this constraint was already created in db.
Since it was my test DB So I dropped DB and when I recreate all table along with this table then it worked. So solution was that this constraint must be deleted from DB before creating new tables.
Check that both fields are the same size and if the referenced field is unsigned then the referencing field should also be unsigned.

MySQL error 1215 Cannot add Foreign key constraint - FK in different tables

im new on mysql workbench, and i tried so many things to put my script working but i simply cant... Ive got these tables:
CREATE TABLE Utilizador (email varchar(40) not null, nome varchar(50)
not null, dataNascimento date, profissao varchar(50) not null,
reputacao double(3,2) unsigned not null, constraint pk_Utilizador
primary key(email))
This is the first table created!
CREATE TABLE POI (email varchar(40) not null, designacaoPOI
varchar(10) not null, coordenadaX int, coordenadaY int,
descricaoPOI varchar(200), constraint pk_POI primary key(email,
designacaoPOI), constraint fk_POI foreign key(email) references
Utilizador(email) on delete cascade)
This is the second table created!
CREATE TABLE Utilizador_POI (email varchar(40) not null, designacaoPOI
varchar(10) not null, constraint pk_Utilizador_POI primary key(email,
designacaoPOI), constraint fk1_Utilizador_POI foreign key(email)
references Utilizador(email) on delete cascade, constraint
fk2_Utilizador_POI foreign key(designacaoPOI) references
POI(designacaoPOI) on delete cascade)
This table gives me the error: Error Code: 1215. Cannot add foreign key constraint
I did some tests and im almost sure that the problem is in the foreign key "designacaoPOI". The other FK ("email") dont give me any error, so maybe the problem is in the Table POI?
Thanks in advanced!
The problem here is twofold:
1/ Use IDs for PRIMARY KEYs
You should be using IDs for primary keys rather than VARCHARs or anything that has any real-world "business meaning". If you want the email to be unique within the Utilizador table, the combination of email and designacaoPOI to be unique in the POI table, and the same combination (email and designacaoPOI) to be unique in Utilizador_POI, you should be using UNIQUE KEY constraints rather than PRIMARY KEY constraints.
2/ You cannot DELETE CASCADE on a FOREIGN KEY that doesn't reference the PRIMARY KEY
In your third table, Utilizador_POI, you have two FOREIGN KEYs references POI. Unfortunately, the PRIMARY KEY on POI is a composite key, so MySQL has no idea how to handle a DELETE CASCADE, as there is not a one-to-one relationship between the FOREIGN KEY in Utilizador_POI and the PRIMARY KEY of POI.
If you change your tables to all have a PRIMARY KEY of ID, as follows:
CREATE TABLE blah (
id INT(9) AUTO_INCREMENT NOT NULL
....
PRIMARY KEY (id)
);
Then you can reference each table by ID, and both your FOREIGN KEYs and DELETE CASCADEs will work.
I think the problem is that Utilizador_POI.email references POI.email, which itself references Utilizador.email. MySQL is probably upset at the double-linking.
Also, since there seems to be a many-to-many relationship between Utilizador and POI, I think the structure of Utilizador_POI isn't what you really want. Instead, Utilizador_POI should reference a primary key from Utilizador, and a matching primary key from POI.
The problem is in your second table. Your primary key is (email,designacaoPOI), when you try to reference that in your table it gives you error because of this:
InnoDB permits a foreign key to reference any index column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
For it to work, either change the order of your second tale PRIMARY KEY :
CREATE TABLE POI (
email VARCHAR(40) NOT NULL,
designacaoPOI VARCHAR(10) NOT NULL,
coordenadaX INT,
coordenadaY INT,
descricaoPOI VARCHAR(200),
CONSTRAINT pk_POI PRIMARY KEY (designacaoPOI,email), -- changed the order
CONSTRAINT fk_POI FOREIGN KEY (email)
REFERENCES Utilizador(email) ON DELETE CASCADE
);
sqlfiddle demo
or add an index for designacaoPOI:
CREATE TABLE POI (
email VARCHAR(40) NOT NULL,
designacaoPOI VARCHAR(10) NOT NULL,
coordenadaX INT,
coordenadaY INT,
descricaoPOI VARCHAR(200),
CONSTRAINT pk_POI PRIMARY KEY (designacaoPOI,email),
KEY key_designacaoPOI(designacaoPOI), -- added index for that column
CONSTRAINT fk_POI FOREIGN KEY (email)
REFERENCES Utilizador(email) ON DELETE CASCADE
);
sqlfiddle demo
Either of these solutions will let you create your third table without errors.

Please assist me in locating my error in this MySQL code

I'm not sure what I'm doing wrong here, but I get an error:
Error Code: 1005. Can't create table 'erm.section' (emo:150)
Here is the code. The 'course' table is created successfully. I tried modifying the name of the course_number attritube in the 'section' table but that didn't work.
USE erm;
CREATE TABLE course
(
course_name VARCHAR(30) NOT NULL,
course_number VARCHAR(20) NOT NULL,
credit_hours INT NOT NULL,
department VARCHAR(10),
CONSTRAINT course_pk PRIMARY KEY (course_name)
);
CREATE TABLE section
(
section_identifier INT NOT NULL,
course_number VARCHAR(20),
semester VARCHAR(10) NOT NULL,
school_year VARCHAR(4) NOT NULL,
instructor VARCHAR(25),
CONSTRAINT section_pk PRIMARY KEY (section_identifier),
CONSTRAINT section_fk FOREIGN KEY (course_number)
REFERENCES course (course_number)
ON DELETE SET NULL
ON UPDATE CASCADE
);
course_number is not a primary key in the table course.
the foreign key in the table section must reference a primary key form another table.
You have to create an index on the column referenced by the foreign key:
alter table course add index (course_number);
(It doesn't have to be a primary key index.) From the MySQL documentation:
InnoDB permits a foreign key to reference any index column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
A FOREIGN KEY in one table points to a PRIMARY KEY in another table.
AFAIK, dropping the CONSTRAINT, then rename, then add the CONSTRAINT back is the only way. Backup first!
to drop it use this
ALTER TABLE section
DROP FOREIGN KEY course_number
and to add it again use this
ALTER TABLE section
ADD FOREIGN KEY (course_number)
REFERENCES course (course_number)