I've got a problem which drives me crazy. I searched on the internet but all i could find was: The data on which the foreign key references, is not inserted. Well, I checked it like 100 times, they are inserted.
My tables are:
Stundenanfrage:
CREATE TABLE IF NOT EXISTS Stundenanfrage(
LehrerKuerzel CHAR(10),
Anfangszeit TIMESTAMP,
Endzeit TIMESTAMP,
StundeGehalten TINYINT,
Akzeptiert TINYINT,
Lernprozess TEXT,
Sterne INT, -- 1-5 1 schlecht; 5 gut
BetrauNr INT REFERENCES ILB_Betrauung(BetrauNr),
PRIMARY KEY(LehrerKuerzel, Anfangszeit, Endzeit, BetrauNr),
FOREIGN KEY(LehrerKuerzel, Anfangszeit, Endzeit) REFERENCES Lehrerzeiten(LehrerKuerzel, Anfangszeit, Endzeit)
);
Lehrerzeiten:
CREATE TABLE IF NOT EXISTS Lehrerzeiten(
LehrerKuerzel CHAR(10) REFERENCES ILB_Lehrer,
Anfangszeit TIMESTAMP ,
Endzeit TIMESTAMP ,
Einzelunterricht TINYINT(1) DEFAULT 0,
Thema VARCHAR(100),
PRIMARY KEY(LehrerKuerzel, Anfangszeit, Endzeit)
);
And ilb_betrauung:
CREATE TABLE IF NOT EXISTS ILB_Betrauung(
BetrauNr INT PRIMARY KEY AUTO_INCREMENT,
LehrerKuerzel CHAR(10) REFERENCES ilb_lehrer,
MatNr CHAR(20) REFERENCES fw_schueler,
zweckmaeßig_erachtet_Lehrer TINYINT,
zweckmaeßig_erachtet_Schueler TINYINT,
Betrauung_AV TINYINT,
Eltern_informiert TINYINT
);
The inserted data:
My update query looks like this:
UPDATE stundenanfrage SET Akzeptiert = 1
WHERE LehrerKuerzel = "bb" AND Anfangszeit = "2017-02-20 12:20:00" AND
Endzeit = "2017-02-20 13:00:00";
and threw an error:
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`db_ilb`.`stundenanfrage`, CONSTRAINT `stundenanfrage_ibfk_1` FOREIGN KEY (`LehrerKuerzel`, `Anfangszeit`, `Endzeit`) REFERENCES `lehrerzeiten` (`LehrerKuerzel`, `Anfangszeit`, `Endzeit`)
I also joined all tables and selected that particular record I wanted to update:
SELECT * FROM stundenanfrage s
JOIN lehrerzeiten l ON s.Lehrerkuerzel = l.Lehrerkuerzel AND s.Anfangszeit =
l.Anfangszeit AND s.Endzeit = l.Endzeit
WHERE l.LehrerKuerzel = "bb" AND l.Anfangszeit = "2017-02-20 12:20:00" AND
l.Endzeit = "2017-02-20 13:00:00" AND s.BetrauNr = 1;
The output was that one record I wanted to update. I also asked my teacher about this error and she had no clue either.
Check Extra:
mysql> DESC `Stundenanfrage`;
+----------------+------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------+------+-----+-------------------+-----------------------------+
| LehrerKuerzel | char(10) | NO | PRI | NULL | |
| Anfangszeit | timestamp | NO | PRI | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| Endzeit | timestamp | NO | PRI | NULL | |
| StundeGehalten | tinyint(4) | YES | | NULL | |
| Akzeptiert | tinyint(4) | YES | | NULL | |
| Lernprozess | text | YES | | NULL | |
| Sterne | int(11) | YES | | NULL | |
| BetrauNr | int(11) | NO | PRI | NULL | |
+----------------+------------+------+-----+-------------------+-----------------------------+
8 rows in set (0.00 sec)
See: 12.3.5 Automatic Initialization and Updating for TIMESTAMP and DATETIME.
Try:
CREATE TABLE IF NOT EXISTS Stundenanfrage (
LehrerKuerzel CHAR(10),
Anfangszeit TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
Endzeit TIMESTAMP,
StundeGehalten TINYINT,
Akzeptiert TINYINT,
Lernprozess TEXT,
Sterne INT, -- 1-5 1 schlecht; 5 gut
BetrauNr INT REFERENCES ILB_Betrauung(BetrauNr),
PRIMARY KEY(LehrerKuerzel, Anfangszeit, Endzeit, BetrauNr),
FOREIGN KEY(LehrerKuerzel, Anfangszeit, Endzeit)
REFERENCES Lehrerzeiten(LehrerKuerzel, Anfangszeit, Endzeit)
);
mysql> DESC `Stundenanfrage`;
+----------------+------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------+------+-----+-------------------+-------+
| LehrerKuerzel | char(10) | NO | PRI | NULL | |
| Anfangszeit | timestamp | NO | PRI | CURRENT_TIMESTAMP | |
| Endzeit | timestamp | NO | PRI | NULL | |
| StundeGehalten | tinyint(4) | YES | | NULL | |
| Akzeptiert | tinyint(4) | YES | | NULL | |
| Lernprozess | text | YES | | NULL | |
| Sterne | int(11) | YES | | NULL | |
| BetrauNr | int(11) | NO | PRI | NULL | |
+----------------+------------+------+-----+-------------------+-------+
8 rows in set (0.00 sec)
Related
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
I currently have three tables:
desc products;
+----------------+-------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------------+------+-----+---------+----------------+
| id | int(255) unsigned | NO | PRI | NULL | auto_increment |
| name | text | NO | | NULL | |
| desc_short | text | NO | | NULL | |
+----------------+-------------------+------+-----+---------+----------------+
desc tags;
+------------+-------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+----------------+
| id | int(255) unsigned | NO | PRI | NULL | auto_increment |
| tag | varchar(255) | YES | UNI | NULL | |
| iscategory | tinyint(4) | NO | | 0 | |
+------------+-------------------+------+-----+---------+----------------+
desc products_tags;
+------------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+-------+
| product_id | int(255) unsigned | YES | MUL | NULL | |
| tag_id | int(255) unsigned | YES | MUL | NULL | |
+------------+-------------------+------+-----+---------+-------+
products_tags is actually a reference table that I've created with:
CREATE TABLE product_tags (
product_id INT(255) UNSIGNED,
tag_id INT(255) UNSIGNED,
CONSTRAINT fk_products_id FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT fk_tag_id FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE ON UPDATE CASCADE
);
I'm trying to filter items from the table products by searching for a corresponding tag.
I have already found some similar problems but I couldn't get it to work properly....
Thanks a lot in advance.
Try this join query:
SELECT p.id, p.name, p.desc_short
FROM products p
INNER JOIN products_tag pt
ON p.id = pt.product_id
INNER JOIN tags t
ON t.id = pt.tag_id
WHERE t.tag = 'some tag'
One of my tables is losing the primary key every time I make an update on that particular table.
Describe zizi_card_household
gives me this result after the update.
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | | NULL | auto_increment |
| householdnumber | varchar(45) | NO | | | |
| cardnumber | varchar(45) | YES | MUL | NULL | |
| startdate | datetime | YES | | NULL | |
| enddate | datetime | YES | | NULL | |
| assignedby | int(11) | YES | | NULL | |
| assigneddate | datetime | YES | | NULL | |
Where it should normally be
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| householdnumber | varchar(45) | NO | MUL | | |
| cardnumber | varchar(45) | YES | MUL | NULL | |
| startdate | datetime | YES | | NULL | |
| enddate | datetime | YES | | NULL | |
| assignedby | int(11) | YES | | NULL | |
SHOW CREATE TABLE
will give this statement which shows a primary key was defined. It's possible that entry is updated whenever the table is altered so it shows the table as it was last altered or created.
CREATE TABLE `zizi_card_household` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`householdnumber` varchar(45) NOT NULL DEFAULT '',
`cardnumber` varchar(45) DEFAULT NULL,
`startdate` datetime DEFAULT NULL,
`enddate` datetime DEFAULT NULL,
`assignedby` int(11) DEFAULT NULL,
`assigneddate` datetime DEFAULT NULL,
`deassignedby` int(11) DEFAULT NULL,
.
.
.
.
`modifiedby` int(11) DEFAULT NULL,
`reprintstatus` tinyint(4) DEFAULT NULL,
`printeddate` datetime DEFAULT NULL,
`printedby` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_householdnumber` (`householdnumber`),
KEY `idx_cardnumber` (`cardnumber`),
KEY `idx_deassignedby` (`deassignedby`),
.
.
.
.
KEY `idx_reprintstatus` (`reprintstatus`)
) ENGINE=InnoDB AUTO_INCREMENT=860137 DEFAULT CHARSET=latin1
Attempting to add a primary key
ALTER TABLE `labour`.`zizi_card_household`
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
at this point gives me
ERROR 1068 (42000): Multiple primary key defined
Repair table
repair table zizi_card_household;
Gives me this but it does solve the problem. The primary key returns but will get ruined the next time the table is updated.
+----------------------------+--------+----------+---------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+----------------------------+--------+----------+---------------------------------------------------------+
| labour.zizi_card_household | repair | note | The storage engine for the table doesn't support repair |
+----------------------------+--------+----------+---------------------------------------------------------+
The table and other tables have a trigger that updates a summary table. It deletes related rows and reconstructs them. It does something like
FOR EACH ROW
begin
delete from zizi_card_summary where householdnumber=new.householdnumber;
insert into zizi_card_summary(
cardnumber,cardhouseholdid,householdnumber,startdate,enddate,assignedby
.
.
.
)
select ch.cardnumber,ch.id,b.householdnumber,
ch.startdate,ch.enddate,ch.assignedby,
.
.
.
.
where b.householdnumber=new.householdnumber and b.beneficiary_type=0;
end
All other tables work just fine. Thanks. Been playing around with this for a week. The application is a Zend framework 1.12.
The db version is 10.1.11-MariaDB-log. The operating system is Linux 2.6.32-573.8.1.el6.x86_64 x86_64.
I can confirm the bug and the workaround as described by Timothy : removing the trigger keeps the Primary key after a record update.
Bug resolution progress is on https://jira.mariadb.org/browse/MDEV-9558
I am preparing for an exam and I decided to do some example tasks I made up but I am stuck on one particular. Relationships. I have been hitting my head against the wall of SQL for 3-4 hours with little progress. I have 2 tables in which I want to create a one to one and a one to many relationships.
CREATE TABLE article (
price INT(30) NOT NULL,
published_on DATE NOT NULL
);
CREATE TABLE tag(
descption VARCHAR(30) NOT NULL,
priority INT(30) NOT NULL
);
CREATE TABLE category(
date_created_on DATE NOT NULL,
name VARCHAR(30) NOT NULL
);
INSERT INTO article VALUES (10.0, "2001-01-01", 0);
INSERT INTO article VALUES (20.0, "1992-05-08", 0);
INSERT INTO tag VALUES ("wtf", 1, 1);
INSERT INTO tag VALUES ("is this", 2, 2);
ALTER TABLE article ADD article_id INT(30) NOT NULL;
ALTER TABLE article ADD PRIMARY KEY(article_id);
ALTER TABLE article MODIFY article_id AUTO_INCREMENT;
ALTER TABLE tag ADD tag_id INT(30) NOT NULL;
ALTER TABLE tag ADD PRIMARY KEY(tag_id);
ALTER TABLE tag MODIFY tag_id AUTO_INCREMENT;
ALTER TABLE tag ADD FOREIGN KEY (tag_id) REFERENCES (article_id);
I want to make it so that one article has a one to one with article, then to make it so article has a one to many with category. I can't do the one to one to even try the one to many. Can you please give me some insight as to how to make it happen and how the relationships will work?
Here is the information from inside the database -
mysql> select * from Tag;
+-------------+----------+--------+
| description | priority | tag_id |
+-------------+----------+--------+
| wtf | 1 | 1 |
| is this | 2 | 2 |
+-------------+----------+--------+
mysql> select * from Article;
+-------+--------------+------------+
| price | published_on | article_id |
+-------+--------------+------------+
| 10 | 2001-01-01 | 7 |
| 20 | 1992-05-08 | 8 |
+-------+--------------+------------+
mysql> describe Article;
+--------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+----------------+
| price | decimal(30,0) | YES | | NULL | |
| published_on | date | YES | | NULL | |
| article_id | int(30) | NO | PRI | NULL | auto_increment |
+--------------+---------------+------+-----+---------+----------------+
mysql> describe Tag;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| description | varchar(30) | NO | | NULL | |
| priority | int(30) | NO | | NULL | |
| tag_id | int(30) | NO | PRI | NULL | |
+-------------+-------------+------+-----+---------+-------+ mysql> select * from Tag;
+-------------+----------+--------+
| description | priority | tag_id |
+-------------+----------+--------+
| wtf | 1 | 1 |
| is this | 2 | 2 |
+-------------+----------+--------+
mysql> select * from Article;
+-------+--------------+------------+
| price | published_on | article_id |
+-------+--------------+------------+
| 10 | 2001-01-01 | 7 |
| 20 | 1992-05-08 | 8 |
+-------+--------------+------------+
mysql> describe Article;
+--------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+----------------+
| price | decimal(30,0) | YES | | NULL | |
| published_on | date | YES | | NULL | |
| article_id | int(30) | NO | PRI | NULL | auto_increment |
+--------------+---------------+------+-----+---------+----------------+
mysql> describe Tag;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| description | varchar(30) | NO | | NULL | |
| priority | int(30) | NO | | NULL | |
| tag_id | int(30) | NO | PRI | NULL | |
+-------------+-------------+------+-----+---------+-------+
And this is the error I get for creating the foreign key:
mysql> ALTER TABLE Tag ADD FOREIGN KEY(tag_id) REFERENCES Article(article_id);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`exam_example`.`#sql-2836_1`,
CONSTRAINT `#sql-2836_1_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `Article` (`article_id`))
CREATE TABLE article (
price INT(30) NOT NULL,
published_on DATE NOT NULL,
article_id INT(30) NOT NULL,
CONSTRAINT pk_article_id PRIMARY KEY(article_id)
);
CREATE TABLE tag(
descption VARCHAR(30) NOT NULL,
priority INT(30) NOT NULL,
tag_id INT(30) NOT NULL,
CONSTRAINT pk_tag_article PRIMARY KEY(tag_id),
CONSTRAINT fk_tag_article FOREIGN KEY(tag_id) REFERENCES article(article_id)
);
INSERT INTO article VALUES (10.0, "2001-01-01", 0);
INSERT INTO article VALUES (20.0, "1992-05-08", 1);
INSERT INTO tag VALUES ("wtf", 1, 1);
INSERT INTO tag VALUES ("is this", 2, 2);
This is a relationship one to one.
I'm saying here that the primary key of the tag is the same from article.
I have the tables Players and PlayerMeta
mysql> DESCRIBE Players;
+-------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+----------------+
| ID | int(5) | NO | PRI | NULL | auto_increment |
| PlayerName | varchar(20) | NO | PRI | NULL | |
| Birthdate | date | YES | | NULL | |
| Location | varchar(20) | YES | | NULL | |
| FirstName | varchar(15) | YES | | NULL | |
| Whitelisted | tinyint(1) | NO | | 1 | |
+-------------+-------------+------+-----+---------+----------------+
mysql> DESCRIBE PlayerMeta;
+----------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------+------+-----+---------+-------+
| ID | int(5) | NO | PRI | NULL | |
| JoinDate | date | YES | | NULL | |
| BuildQuota | int(2) | NO | | 2 | |
| RegisteredDate | date | YES | | NULL | |
| HideBirthdate | tinyint(1) | NO | | 0 | |
+----------------+------------+------+-----+---------+-------+
I am trying to execute this command, and it returns Query OK:
ALTER TABLE PlayerMeta
ADD CONSTRAINT fk_PlayerID
FOREIGN KEY (ID)
REFERENCES Players(ID)
ON UPDATE CASCADE
ON DELETE CASCADE;
Yet, when I run SHOW CREATE TABLE PlayerMeta, it does not show the constraint, nor is it in INFORMATION_SCHEMA
Any thoughts? Thanks.
EDIT: Here is SHOW CREATE TABLE PlayerMeta:
mysql> SHOW CREATE TABLE PlayerMeta;
... a bunch of lines ...
| PlayerMeta | CREATE TABLE `PlayerMeta` (
`ID` int(5) NOT NULL,
`JoinDate` date DEFAULT NULL,
`BuildQuota` int(2) NOT NULL DEFAULT '2',
`RegisteredDate` date DEFAULT NULL,
`HideBirthdate` tinyint(1) NOT NULL DEFAULT '0',
UNIQUE KEY `ID` (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
EDIT(2): The problem was ID in PlayerMeta was already a primary key and a foreign key would not apply in conjunction with it.
You cannot create foreign keys for MyISAM.
Only InnoDB supports them.
So the solution for you is to change the storage engine for both tables.
ALTER TABLE Players ENGINE=InnoDB;
ALTER TABLE PlayerMeta ENGINE=InnoDB;
Then re-apply your ALTER with adding a FK constraint.
MySQL will not permit you to create a FOREIGN KEY constraint on a column which is itself a PRIMARY KEY. If your design is such that the two tables share a one-to-one relationship and both hold information about a Player, it may not make sense to separate them and instead combine both tables into one.
In any case, if you wish to keep them separate and enforce a FOREIGN KEY relationship on them, you need to remove the PRIMARY KEY on PlayerMeta.ID. You may still have a UNIQUE, non primary key index on it.