首页 > 解决方案 > 如何使用引用复合键的外键插入行

问题描述

我有一个带有复合主键的 mysql 表,以及一个用外键引用第一个的子表。

插入一行子表的正确语法是什么?

复合键的两个部分如何在插入语句中给出?

我有这些桌子;

CREATE TABLE IF NOT EXISTS parent (
    p_id    INT NOT NULL,
    p_org   INT NOT NULL,
    PRIMARY KEY(p_id, p_org),
    p_name  VARCHAR(12))
ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS child (
    c_id    INT NOT NULL PRIMARY KEY,
    c_org   INT NOT NULL,
    c_p_id  INT NOT NULL, FOREIGN KEY(c_p_id, c_org) REFERENCES parent(p_id, p_org),
    c_info  VARCHAR(12))
ENGINE=InnoDB;

将两行插入父级后;

insert into parent values(100, 1, 'name-1'), (100, 2, 'name-2');

我想在孩子中插入一行。

insert into child values(1000, 2, 100, 'info-for-2');

但我不知道如何指定复合键。我想指定 (100 and 2)而不是100 ,以便我的子行仅使用 (100 2) 引用父行。

使用上面的插入语句,我的查询返回两行而不是一行;

select * from parent join child on c_p_id = p_id;

返回;

p_id    p_org   p_name  c_id    c_org   c_p_id  c_info
100     1       name-1  1000    2       100     info-for-2
100     2       name-2  1000    2       100     info-for-2

但想得到 (100 2) 的行。

我真的必须在连接上指定 c_org 吗?

标签: mysqlsqlforeign-keyssql-insertcomposite-primary-key

解决方案


您应该开始养成在INSERT语句中明确提及目标列的习惯。

然后,如果您将一行插入parentwith

INSERT INTO parent
            (p_id,
             p_org)
            VALUES (2,
                    100,
                    'name-2');

您通过将主键元组的确切值插入到外键元组的列中来插入child引用该行的行,例如parentparentchilds

INSERT INTO child
            (c_id,
             c_org,
             c_p_id,
             c_info)
            VALUES (1000,
                    2,
                    100,
                    'info-for-2');

ON要连接行,您需要检查主键中的所有值是否与子句中的外键值匹配。在这里您可以使用AND.

SELECT *
       FROM parent p
            INNER JOIN child c
                       ON c.c_p_id = p.p_id
                          AND c.c_org = p.p_org;

推荐阅读