2017-02-19 49 views
0

我有以下问题: 每一位作者都对这个名称的名称和正别名。每个别名都来自一个源。每个别名都有m个来源。例如的MySQL对重复插入到另一个表

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。 并且在重复的别名上不只添加新的源。在SQL

回答

0

的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作为标准动作更加复杂。

+0

感谢您的答案@帐单!但是有可能使用ON DUPLICATE KEY并将重复的ID存储在@id中?跳过第二条语句? –

相关问题