Allow only unique combination of values for a composite primary key - mysql

I created the following table called books:
CREATE TABLE IF NOT EXISTS `books` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` TEXT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I created another tablet called compare to compare any 2 books from the books table:
CREATE TABLE IF NOT EXISTS `compare` (
`id_1` BIGINT UNSIGNED NOT NULL,
`id_2` BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (`id_1`,`id_2`),
FOREIGN KEY (`id_1`) REFERENCES books(`id`),
FOREIGN KEY (`id_2`) REFERENCES books(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The previous works as expected but I need to force MYSQL to allow ONLY unique combination of values in the compare table.
For example if I have the following row in compare table:
id_1 | id_2
------------
1 | 2
I want to force MYSQL to NOT allow me to insert the following row:
id_1 | id_2
------------
2 | 1
So I want MYSQL to allow only either 1,2 or 2,1 NOT both.

Another way would be to swap the values in a before-insert trigger to make sure id_1 < id_2:
CREATE TRIGGER `compare_before_insert` BEFORE INSERT ON `compare` FOR EACH ROW
BEGIN
DECLARE t BIGINT;
IF(NEW.id_1 > NEW.id_2) THEN
SET t = NEW.id_1;
SET NEW.id_1 = NEW.id_2;
SET NEW.id_2 = t;
END IF;
END
This will allow you to use the key to make the pairs unique.

In MySQL (at least prior to version 8), you need to do this using a trigger if you want the database to enforce the constraint.
delimiter $$
create trigger compare_insert_trigger before insert on compare
for each row
begin
if (exists (select 1
from compare c
where c.id2 = new.id1 and c.id1 = new.id2
)
) then
signal sqlsate '45000'
set message_text = 'Book pair already exists in compare';
end if;
end;$$
delimiter ;
Of course, you still need the unique constraint.

Related

MYSQL BETWEEN operator [duplicate]

I am having trouble with this table
CREATE TABLE `Participants` (
`meetid` int(11) NOT NULL,
`pid` varchar(15) NOT NULL,
`status` char(1) DEFAULT NULL,
PRIMARY KEY (`meetid`,`pid`),
CONSTRAINT `participants_ibfk_1` FOREIGN KEY (`meetid`) REFERENCES `Meetings` (`meetid`) ON DELETE CASCADE
CONSTRAINT `participants_ibfk_2` CHECK (status IN ('a','d','u'))
CONSTRAINT `participants_ibfk_3` CHECK (pid IN (SELECT name FROM Rooms) OR pid IN (SELECT userid FROM People))
);
I want to have a foreign key constraint, and that works. Then, I also want to add a constraint to the attribute status so it can only take the values 'a', 'd' and 'u'. It is not possible for me to set the field as Enum or set.
Can anyone tell me why this code does not work in MySQL?
CHECK constraints are not supported by MySQL. You can define them, but they do nothing (as of MySQL 5.7).
From the manual:
The CHECK clause is parsed but ignored by all storage engines.
The workaround is to create triggers, but they aren't the easiest thing to work with.
If you want an open-source RDBMS that supports CHECK constraints, try PostgreSQL. It's actually a very good database.
I don't understand why nobody here has mentioned that VIEW WITH CHECK OPTION can be a good alternative to the CHECK CONSTRAINT in MySQL:
CREATE VIEW name_of_view AS SELECT * FROM your_table
WHERE <condition> WITH [LOCAL | CASCADED] CHECK OPTION;
There is a doc on the MySQL site: The View WITH CHECK OPTION Clause
DROP TABLE `Participants`;
CREATE TABLE `Participants` (
`meetid` int(11) NOT NULL,
`pid` varchar(15) NOT NULL,
`status` char(1) DEFAULT NULL check (status IN ('a','d','u')),
PRIMARY KEY (`meetid`,`pid`)
);
-- should work
INSERT INTO `Participants` VALUES (1,1,'a');
-- should fail but doesn't because table check is not implemented in MySQL
INSERT INTO `Participants` VALUES (2,1,'x');
DROP VIEW vParticipants;
CREATE VIEW vParticipants AS
SELECT * FROM Participants WHERE status IN ('a','d','u')
WITH CHECK OPTION;
-- should work
INSERT INTO vParticipants VALUES (3,1,'a');
-- will fail because view uses a WITH CHECK OPTION
INSERT INTO vParticipants VALUES (4,1,'x');
P.S.: Keep in mind that your view should be updatable! See MySQL Updatable Views
(thanks Romeo Sierra for clarification in comments).
Beside triggers, for simple constraints like the one you have:
CONSTRAINT `participants_ibfk_2`
CHECK status IN ('a','d','u')
you could use a Foreign Key from status to a Reference table (ParticipantStatus with 3 rows: 'a','d','u' ):
CONSTRAINT ParticipantStatus_Participant_fk
FOREIGN KEY (status)
REFERENCES ParticipantStatus(status)
Starting with version 8.0.16, MySQL has added support for CHECK constraints:
ALTER TABLE topic
ADD CONSTRAINT post_content_check
CHECK (
CASE
WHEN DTYPE = 'Post'
THEN
CASE
WHEN content IS NOT NULL
THEN 1
ELSE 0
END
ELSE 1
END = 1
);
ALTER TABLE topic
ADD CONSTRAINT announcement_validUntil_check
CHECK (
CASE
WHEN DTYPE = 'Announcement'
THEN
CASE
WHEN validUntil IS NOT NULL
THEN 1
ELSE 0
END
ELSE 1
END = 1
);
Previously, this was only available using BEFORE INSERT and BEFORE UPDATE triggers:
CREATE
TRIGGER post_content_check BEFORE INSERT
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Post'
THEN
IF NEW.content IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Post content cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER post_content_update_check BEFORE UPDATE
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Post'
THEN
IF NEW.content IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Post content cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER announcement_validUntil_check BEFORE INSERT
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Announcement'
THEN
IF NEW.validUntil IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Announcement validUntil cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER announcement_validUntil_update_check BEFORE UPDATE
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Announcement'
THEN
IF NEW.validUntil IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Announcement validUntil cannot be NULL';
END IF;
END IF;
END;
Here is a way of getting the checks you wanted quickly and easily:
drop database if exists gtest;
create database if not exists gtest;
use gtest;
create table users (
user_id integer unsigned not null auto_increment primary key,
username varchar(32) not null default '',
password varchar(64) not null default '',
unique key ix_username (username)
) Engine=InnoDB auto_increment 10001;
create table owners (
owner_id integer unsigned not null auto_increment primary key,
ownername varchar(32) not null default '',
unique key ix_ownername (ownername)
) Engine=InnoDB auto_increment 5001;
create table users_and_owners (
id integer unsigned not null primary key,
name varchar(32) not null default '',
unique key ix_name(name)
) Engine=InnoDB;
create table p_status (
a_status char(1) not null primary key
) Engine=InnoDB;
create table people (
person_id integer unsigned not null auto_increment primary key,
pid integer unsigned not null,
name varchar(32) not null default '',
status char(1) not null,
unique key ix_name (name),
foreign key people_ibfk_001 (pid) references users_and_owners(id),
foreign key people_ibfk_002 (status) references p_status (a_status)
) Engine=InnoDB;
create or replace view vw_users_and_owners as
select
user_id id,
username name
from users
union
select
owner_id id,
ownername name
from owners
order by id asc
;
create trigger newUser after insert on users for each row replace into users_and_owners select * from vw_users_and_owners;
create trigger newOwner after insert on owners for each row replace into users_and_owners select * from vw_users_and_owners;
insert into users ( username, password ) values
( 'fred Smith', password('fredSmith')),
( 'jack Sparrow', password('jackSparrow')),
( 'Jim Beam', password('JimBeam')),
( 'Ted Turner', password('TedTurner'))
;
insert into owners ( ownername ) values ( 'Tom Jones'),( 'Elvis Presley'),('Wally Lewis'),('Ted Turner');
insert into people (pid, name, status) values ( 5001, 'Tom Jones', 1),(10002,'jack Sparrow',1),(5002,'Elvis Presley',1);

Creating custom (user defined) constraints in mysql [duplicate]

I am having trouble with this table
CREATE TABLE `Participants` (
`meetid` int(11) NOT NULL,
`pid` varchar(15) NOT NULL,
`status` char(1) DEFAULT NULL,
PRIMARY KEY (`meetid`,`pid`),
CONSTRAINT `participants_ibfk_1` FOREIGN KEY (`meetid`) REFERENCES `Meetings` (`meetid`) ON DELETE CASCADE
CONSTRAINT `participants_ibfk_2` CHECK (status IN ('a','d','u'))
CONSTRAINT `participants_ibfk_3` CHECK (pid IN (SELECT name FROM Rooms) OR pid IN (SELECT userid FROM People))
);
I want to have a foreign key constraint, and that works. Then, I also want to add a constraint to the attribute status so it can only take the values 'a', 'd' and 'u'. It is not possible for me to set the field as Enum or set.
Can anyone tell me why this code does not work in MySQL?
CHECK constraints are not supported by MySQL. You can define them, but they do nothing (as of MySQL 5.7).
From the manual:
The CHECK clause is parsed but ignored by all storage engines.
The workaround is to create triggers, but they aren't the easiest thing to work with.
If you want an open-source RDBMS that supports CHECK constraints, try PostgreSQL. It's actually a very good database.
I don't understand why nobody here has mentioned that VIEW WITH CHECK OPTION can be a good alternative to the CHECK CONSTRAINT in MySQL:
CREATE VIEW name_of_view AS SELECT * FROM your_table
WHERE <condition> WITH [LOCAL | CASCADED] CHECK OPTION;
There is a doc on the MySQL site: The View WITH CHECK OPTION Clause
DROP TABLE `Participants`;
CREATE TABLE `Participants` (
`meetid` int(11) NOT NULL,
`pid` varchar(15) NOT NULL,
`status` char(1) DEFAULT NULL check (status IN ('a','d','u')),
PRIMARY KEY (`meetid`,`pid`)
);
-- should work
INSERT INTO `Participants` VALUES (1,1,'a');
-- should fail but doesn't because table check is not implemented in MySQL
INSERT INTO `Participants` VALUES (2,1,'x');
DROP VIEW vParticipants;
CREATE VIEW vParticipants AS
SELECT * FROM Participants WHERE status IN ('a','d','u')
WITH CHECK OPTION;
-- should work
INSERT INTO vParticipants VALUES (3,1,'a');
-- will fail because view uses a WITH CHECK OPTION
INSERT INTO vParticipants VALUES (4,1,'x');
P.S.: Keep in mind that your view should be updatable! See MySQL Updatable Views
(thanks Romeo Sierra for clarification in comments).
Beside triggers, for simple constraints like the one you have:
CONSTRAINT `participants_ibfk_2`
CHECK status IN ('a','d','u')
you could use a Foreign Key from status to a Reference table (ParticipantStatus with 3 rows: 'a','d','u' ):
CONSTRAINT ParticipantStatus_Participant_fk
FOREIGN KEY (status)
REFERENCES ParticipantStatus(status)
Starting with version 8.0.16, MySQL has added support for CHECK constraints:
ALTER TABLE topic
ADD CONSTRAINT post_content_check
CHECK (
CASE
WHEN DTYPE = 'Post'
THEN
CASE
WHEN content IS NOT NULL
THEN 1
ELSE 0
END
ELSE 1
END = 1
);
ALTER TABLE topic
ADD CONSTRAINT announcement_validUntil_check
CHECK (
CASE
WHEN DTYPE = 'Announcement'
THEN
CASE
WHEN validUntil IS NOT NULL
THEN 1
ELSE 0
END
ELSE 1
END = 1
);
Previously, this was only available using BEFORE INSERT and BEFORE UPDATE triggers:
CREATE
TRIGGER post_content_check BEFORE INSERT
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Post'
THEN
IF NEW.content IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Post content cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER post_content_update_check BEFORE UPDATE
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Post'
THEN
IF NEW.content IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Post content cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER announcement_validUntil_check BEFORE INSERT
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Announcement'
THEN
IF NEW.validUntil IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Announcement validUntil cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER announcement_validUntil_update_check BEFORE UPDATE
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Announcement'
THEN
IF NEW.validUntil IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Announcement validUntil cannot be NULL';
END IF;
END IF;
END;
Here is a way of getting the checks you wanted quickly and easily:
drop database if exists gtest;
create database if not exists gtest;
use gtest;
create table users (
user_id integer unsigned not null auto_increment primary key,
username varchar(32) not null default '',
password varchar(64) not null default '',
unique key ix_username (username)
) Engine=InnoDB auto_increment 10001;
create table owners (
owner_id integer unsigned not null auto_increment primary key,
ownername varchar(32) not null default '',
unique key ix_ownername (ownername)
) Engine=InnoDB auto_increment 5001;
create table users_and_owners (
id integer unsigned not null primary key,
name varchar(32) not null default '',
unique key ix_name(name)
) Engine=InnoDB;
create table p_status (
a_status char(1) not null primary key
) Engine=InnoDB;
create table people (
person_id integer unsigned not null auto_increment primary key,
pid integer unsigned not null,
name varchar(32) not null default '',
status char(1) not null,
unique key ix_name (name),
foreign key people_ibfk_001 (pid) references users_and_owners(id),
foreign key people_ibfk_002 (status) references p_status (a_status)
) Engine=InnoDB;
create or replace view vw_users_and_owners as
select
user_id id,
username name
from users
union
select
owner_id id,
ownername name
from owners
order by id asc
;
create trigger newUser after insert on users for each row replace into users_and_owners select * from vw_users_and_owners;
create trigger newOwner after insert on owners for each row replace into users_and_owners select * from vw_users_and_owners;
insert into users ( username, password ) values
( 'fred Smith', password('fredSmith')),
( 'jack Sparrow', password('jackSparrow')),
( 'Jim Beam', password('JimBeam')),
( 'Ted Turner', password('TedTurner'))
;
insert into owners ( ownername ) values ( 'Tom Jones'),( 'Elvis Presley'),('Wally Lewis'),('Ted Turner');
insert into people (pid, name, status) values ( 5001, 'Tom Jones', 1),(10002,'jack Sparrow',1),(5002,'Elvis Presley',1);

Reserve/Assign a new row in another table with each row added in one

I'll like to find out if it's possible to do the following:
after insertion of data into table a, a row will be created automatically in table b and the Note_Id (its primary key) will be stored in one of the attributes (which is a foreign key that references to the primary key in table b) in table a.
CREATE TABLE table_a ( D_Id int(5) NOT NULL AUTO_INCREMENT,
User_Id int(8) not null,
Note_Id int(5) not null, -- this is the foreign key that points to table b
PRIMARY KEY (D_Id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE table_b ( Note_Id int(5) NOT NULL AUTO_INCREMENT,
Note_Description varchar(50) null,
PRIMARY KEY (Note_Id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Thanks!
delimiter $$
CREATE TRIGGER ins_Document
AFTER INSERT ON TABLE_A FOR EACH ROW
BEGIN
set #notenum=(Select max(Note_Id) from TABLE_B);
if(#notenum=0) then begin new.Note_Id=1;
end;
else
new.Note_Id=#notenum+1;
end if;
INSERT INTO TABLE_B (Note_Id) VALUES (NEW.Note_Id);
END$$
delimiter ;
Have a look into triggers: Create Trigger
Here you can react on events like inserts into a table and define respective actions for that.

How do I add a custom CHECK constraint on a MySQL table?

I am having trouble with this table
CREATE TABLE `Participants` (
`meetid` int(11) NOT NULL,
`pid` varchar(15) NOT NULL,
`status` char(1) DEFAULT NULL,
PRIMARY KEY (`meetid`,`pid`),
CONSTRAINT `participants_ibfk_1` FOREIGN KEY (`meetid`) REFERENCES `Meetings` (`meetid`) ON DELETE CASCADE
CONSTRAINT `participants_ibfk_2` CHECK (status IN ('a','d','u'))
CONSTRAINT `participants_ibfk_3` CHECK (pid IN (SELECT name FROM Rooms) OR pid IN (SELECT userid FROM People))
);
I want to have a foreign key constraint, and that works. Then, I also want to add a constraint to the attribute status so it can only take the values 'a', 'd' and 'u'. It is not possible for me to set the field as Enum or set.
Can anyone tell me why this code does not work in MySQL?
CHECK constraints are not supported by MySQL. You can define them, but they do nothing (as of MySQL 5.7).
From the manual:
The CHECK clause is parsed but ignored by all storage engines.
The workaround is to create triggers, but they aren't the easiest thing to work with.
If you want an open-source RDBMS that supports CHECK constraints, try PostgreSQL. It's actually a very good database.
I don't understand why nobody here has mentioned that VIEW WITH CHECK OPTION can be a good alternative to the CHECK CONSTRAINT in MySQL:
CREATE VIEW name_of_view AS SELECT * FROM your_table
WHERE <condition> WITH [LOCAL | CASCADED] CHECK OPTION;
There is a doc on the MySQL site: The View WITH CHECK OPTION Clause
DROP TABLE `Participants`;
CREATE TABLE `Participants` (
`meetid` int(11) NOT NULL,
`pid` varchar(15) NOT NULL,
`status` char(1) DEFAULT NULL check (status IN ('a','d','u')),
PRIMARY KEY (`meetid`,`pid`)
);
-- should work
INSERT INTO `Participants` VALUES (1,1,'a');
-- should fail but doesn't because table check is not implemented in MySQL
INSERT INTO `Participants` VALUES (2,1,'x');
DROP VIEW vParticipants;
CREATE VIEW vParticipants AS
SELECT * FROM Participants WHERE status IN ('a','d','u')
WITH CHECK OPTION;
-- should work
INSERT INTO vParticipants VALUES (3,1,'a');
-- will fail because view uses a WITH CHECK OPTION
INSERT INTO vParticipants VALUES (4,1,'x');
P.S.: Keep in mind that your view should be updatable! See MySQL Updatable Views
(thanks Romeo Sierra for clarification in comments).
Beside triggers, for simple constraints like the one you have:
CONSTRAINT `participants_ibfk_2`
CHECK status IN ('a','d','u')
you could use a Foreign Key from status to a Reference table (ParticipantStatus with 3 rows: 'a','d','u' ):
CONSTRAINT ParticipantStatus_Participant_fk
FOREIGN KEY (status)
REFERENCES ParticipantStatus(status)
Starting with version 8.0.16, MySQL has added support for CHECK constraints:
ALTER TABLE topic
ADD CONSTRAINT post_content_check
CHECK (
CASE
WHEN DTYPE = 'Post'
THEN
CASE
WHEN content IS NOT NULL
THEN 1
ELSE 0
END
ELSE 1
END = 1
);
ALTER TABLE topic
ADD CONSTRAINT announcement_validUntil_check
CHECK (
CASE
WHEN DTYPE = 'Announcement'
THEN
CASE
WHEN validUntil IS NOT NULL
THEN 1
ELSE 0
END
ELSE 1
END = 1
);
Previously, this was only available using BEFORE INSERT and BEFORE UPDATE triggers:
CREATE
TRIGGER post_content_check BEFORE INSERT
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Post'
THEN
IF NEW.content IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Post content cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER post_content_update_check BEFORE UPDATE
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Post'
THEN
IF NEW.content IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Post content cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER announcement_validUntil_check BEFORE INSERT
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Announcement'
THEN
IF NEW.validUntil IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Announcement validUntil cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER announcement_validUntil_update_check BEFORE UPDATE
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Announcement'
THEN
IF NEW.validUntil IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Announcement validUntil cannot be NULL';
END IF;
END IF;
END;
Here is a way of getting the checks you wanted quickly and easily:
drop database if exists gtest;
create database if not exists gtest;
use gtest;
create table users (
user_id integer unsigned not null auto_increment primary key,
username varchar(32) not null default '',
password varchar(64) not null default '',
unique key ix_username (username)
) Engine=InnoDB auto_increment 10001;
create table owners (
owner_id integer unsigned not null auto_increment primary key,
ownername varchar(32) not null default '',
unique key ix_ownername (ownername)
) Engine=InnoDB auto_increment 5001;
create table users_and_owners (
id integer unsigned not null primary key,
name varchar(32) not null default '',
unique key ix_name(name)
) Engine=InnoDB;
create table p_status (
a_status char(1) not null primary key
) Engine=InnoDB;
create table people (
person_id integer unsigned not null auto_increment primary key,
pid integer unsigned not null,
name varchar(32) not null default '',
status char(1) not null,
unique key ix_name (name),
foreign key people_ibfk_001 (pid) references users_and_owners(id),
foreign key people_ibfk_002 (status) references p_status (a_status)
) Engine=InnoDB;
create or replace view vw_users_and_owners as
select
user_id id,
username name
from users
union
select
owner_id id,
ownername name
from owners
order by id asc
;
create trigger newUser after insert on users for each row replace into users_and_owners select * from vw_users_and_owners;
create trigger newOwner after insert on owners for each row replace into users_and_owners select * from vw_users_and_owners;
insert into users ( username, password ) values
( 'fred Smith', password('fredSmith')),
( 'jack Sparrow', password('jackSparrow')),
( 'Jim Beam', password('JimBeam')),
( 'Ted Turner', password('TedTurner'))
;
insert into owners ( ownername ) values ( 'Tom Jones'),( 'Elvis Presley'),('Wally Lewis'),('Ted Turner');
insert into people (pid, name, status) values ( 5001, 'Tom Jones', 1),(10002,'jack Sparrow',1),(5002,'Elvis Presley',1);

Fill MySQL records one-to-many related tables in one action

I have two MySQL tables with an one-to-many relationship between them. For example:
CREATE TABLE test1 (
pk1 INTEGER AUTO_INCREMENT PRIMARY KEY,
testvalue1 INTEGER
);
CREATE TABLE test2 (
pk2 INTEGER AUTO_INCREMENT PRIMARY KEY,
testvalue2 VARCHAR(50),
fk2 INTEGER NOT NULL,
FOREIGN KEY (fk2) REFERENCES test1 (pk1)
);
If I want to insert records in both tables I can first insert a record in the PK table (e.g. INSERT INTO test1 SET testvalue1=100), determine the PK value (e.g. SELECT MAX(pk1) AS LastId FROM test1 or use LAST_INSERT_ID())
and finally use that value to fill the FK column in the second table.
But is it possible to achieve this all in 1 command/query/action? So let's MySQL fill in the PK- and FK-values using the AUTO INCREMENTs?
You should use two INSERT commands; or try to use an INSERT-trigger.
EDIT:
--An example with trigger:
CREATE TABLE dept(
id INT(11) NOT NULL AUTO_INCREMENT,
dept_name VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (id)
)
ENGINE = INNODB;
CREATE TABLE emp(
id INT(11) NOT NULL AUTO_INCREMENT,
emp_name VARCHAR(255) DEFAULT NULL,
dept_id INT(11) DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT FK_emp_dept_id FOREIGN KEY (dept_id)
REFERENCES dept (id) ON DELETE RESTRICT ON UPDATE RESTRICT
)
ENGINE = INNODB;
DELIMITER $$
CREATE TRIGGER trigger1
AFTER INSERT
ON dept
FOR EACH ROW
BEGIN
INSERT INTO emp VALUES (NULL, 'Someone', NEW.id);
END
$$
DELIMITER ;
-- Try to add new department.
INSERT INTO dept VALUES(NULL, 'Sales');
-- Is there new default employee?
SELECT * FROM emp;
+----+----------+---------+
| id | emp_name | dept_id |
+----+----------+---------+
| 1 | Someone | 1 |
+----+----------+---------+