的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
,使其成为主键,把次要唯一约束其他列。
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,如果@id
为NULL,则执行SELECT id
查询。
这似乎比在上面显示的INSERT IGNORE
之后的SELECT id
作为标准动作更加复杂。
感谢您的答案@帐单!但是有可能使用ON DUPLICATE KEY并将重复的ID存储在@id中?跳过第二条语句? –