我有以下问题: 每个作者都有此名称的名称和n个别名。每个别名都来自一个来源。每个别名都有m个来源。例如
AUTHOR| ALIAS | SOURCE
-------------------------
Will| Willy |George
Will| Bill | Jenny
William| Will| Francis
William| Bill| Maya
我有一张表给作者和他的名字,一张表用于他的所有别名:
CREATE TABLE alias (
authors_id INT NOT NULL,
alias VARCHAR(150) NOT NULL,
id INT NOT NULL AUTO_INCREMENT
PRIMARY KEY (author_id,alias);
id用作外键。 这是源的第二个表
CREATE TABLE alias_source (
id INT NOT NULL AUTO_INCREMENT
source VARCHAR(150) NOT NULL,
alias_id INT NOT NULL,
PRIMARY KEY (id)
FOREIGN KEY (alias_id) REFERENCES alias(id);
现在我需要一个MySQL插入语句来插入 作者,别名,源代码将源插入alias_source。 并且在重复别名上不仅添加了新的源。
答案 0 :(得分:0)
SQL中的INSERT语句只能插入一个表中,并且只能列出该表的列。您无法在INSERT语句中包含source
列,因为它不是alias
表的列。
触发器可以允许您插入辅助表,但触发器需要知道要插入的值。在这种情况下,触发器无法获取source
的值。
这是一个使用两个INSERT语句更容易完成的任务。
INSERT IGNORE INTO alias SET author_id = ?, alias = ?;
INSERT INTO alias_source ...
但是您遇到问题,因为您的alias
表格有一个自动增量列id
,但此列不是键的一部分。在InnoDB中,必须将自动增量列设置为键的第一列。
您的alias_source
表的外键引用alias(id)
,但不允许这样做。外键必须引用父表的键。它应该引用唯一键或主键,并且应该引用键的所有列(否则你在子表中得到一行可能引用父表中的多行,这没有意义)。
如果要为alias
表使用自动增量列,请将其设为主键,并在其他列上添加辅助UNIQUE约束。
CREATE TABLE alias (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
authors_id INT NOT NULL,
alias VARCHAR(150) NOT NULL,
UNIQUE KEY (author_id,alias));
然后在插入后查询id
。无论您是插入新行还是已存在的行,您都会获得包含所选作者和别名的行的id
。
INSERT IGNORE INTO alias SET author_id = ?, alias = ?;
SELECT id FROM alias WHERE author_id = ? AND alias = ? INTO @id;
INSERT INTO alias_source SET alias_id = @id, source = ?;
在评论中重新提出你的后续问题:
好主意,但它没有像你想象的那样工作。您可以执行id=id
的虚拟集合,并将会话变量设置为副作用。
mysql> insert into alias set author_id=1, alias='alias'
on duplicate key update id = @id:=id;
mysql> select @id;
+------+
| @id |
+------+
| NULL |
+------+
但为什么没有将会话变量设置为id?因为此插入不重复,所以它是一个新行。因此,在IODKU执行时,自动递增尚未生成id
值。
如果您随后对 重复的行执行相同的IODKU,则id
值先前已添加到该行中,因此您可以获得副作用中的值:
mysql> insert into alias set author_id=1, alias='alias'
on duplicate key update id = @id:=id;
mysql> select @id;
+------+
| @id |
+------+
| 1 |
+------+
因此,您必须编写应用程序代码以检查@id
是否为NULL,如果SELECT id
为NULL,则执行@id
查询。
这似乎比SELECT id
作为INSERT IGNORE
之后的标准操作更复杂,如上所示。