更新到加入复合键的表

时间:2012-03-21 02:55:20

标签: mysql join composite-key

我正在尝试更新数据表中与较小索引表中的行相交的行。这两个表在数据表的复合PK上连接,并且使用相同条件的explain-select显示索引正在正确使用,并且获取了正确的唯一行 - 但是我仍然遇到更新问题。

当临时表中只有1行时,联接表的更新工作正常,但是当我有更多行时,我得到MySql Error 1175,并且没有识别出我指定的WHERE条件。

我知道我可以用SET SQL_SAFE_UPDATES = 0关闭安全模式,但是有人能告诉我我在这里不理解的是什么吗?为什么我的WHERE条件不被接受,为什么它甚至需要在我进行自然连接时的位置 - 为什么这只能在右侧表(MyTempTable)中只有一行?

守则

以下是大大简化,但结构相同的创建表&代表我的问题的更新。

-- The Data Table.
Create Table MyDataTable
(
    KeyPartOne int not null,
    KeyPartTwo varchar(64) not null,
    KeyPartThree int not null,
    RelevantData varchar(200) null,
    Primary key (KeyPartOne, KeyPartTwo, KeyPartThree)
) Engine=InnoDB;

-- The 'Temp' table.
Create Table MyTempTable
(
    KeyPartOne int not null,
    KeyPartTwo varchar(64) not null,
    KeyPartThree int not null,
    Primary key (KeyPartOne, KeyPartTwo, KeyPartThree)
)Engine=Memory;

-- The Update Query (works fine with only 1 row in Temp table)
update MyDataTable natural join MyTempTable 
set RelevantData = 'Something Meaningful';

-- Specifying 'where' - roduces same effect as the other update query
update MyDataTable mdt join MyTempTable mtt
on mdt.KeyPartOne = mtt.KeyPartOne
and mdt.KeyPartTwo = mtt.KeyPartTwo
and mdt.KeyPartThree = mtt.KeyPartThree
set RelevantData = 'Something Meaningful'
where mdt.KeyPartOne = mtt.KeyPartOne
and mdt.KeyPartTwo = mtt.KeyPartTwo
and mdt.KeyPartThree = mtt.KeyPartThree;

P.S。当临时表只包含一行时,上述两个更新语句都按预期工作,但在有多行时给出错误。我非常好奇为什么!

2 个答案:

答案 0 :(得分:2)

在您的第一个UPDATE查询中,您使用的NATURAL JOINNATURAL LEFT JOIN相同。

在您的第二个UPDATE查询中,您使用的JOININNER JOIN相同。

LEFT JOININNER JOIN不同,NATURAL JOINJOIN不同。

不确定您要做什么,但如果您尝试更新MyDataTable中MyTempTable中存在相应条目的所有行,则此查询应该可以解决问题:

UPDATE
    myDataTable mdt
    INNER JOIN MyTempTable mtt ON
        mdt.KeyPartOne = mtt.KeyPartOne
        AND mdt.KeyPartTwo = mtt.KeyPartTwo
        AND mdt.KeyPartThree = mtt.KeyPartThree
SET
    mdt.RelevantData = 'Something Meaningful'

如果那不是你想要做的,请澄清,我会更新我的答案。

答案 1 :(得分:1)

根据MySql论坛,更新查询是有效的,并且他们在Workbench中无法启用安全更新模式的事实并不表示索引有任何问题。这只是Workbench的一个怪癖,并且不会自己动手拍摄#34;模式。 : - )