我可以用一个查询插入/更新到两个表吗?

问题描述:

这是我用于基于Perl的Web应用程序的一大块SQL。我有许多请求,每个请求都有一些加入,并且每个都有一个状态。这段代码用于更新每个accession_analysis的表格,该请求在请求*享每个接入点的所有这些字段。我可以用一个查询插入/更新到两个表吗?

UPDATE accession_analysis 
SET analysis_id = ? , 
    reference_id = ? , 
    status = ? , 
    extra_parameters = ? 
WHERE analysis_id = ? 
AND reference_id = ? 
AND status = ? 
AND extra_parameters = ? 
and accession_id is (
    SELECT accesion_id 
    FROM accessions 
    where request_id = ? 
    ) 

我已经改变了表,以便有一个为accession_analysis一个状态表,所以当我更新,我更新两个accession_analysis和accession_analysis_status,其中有状态,STATUS_TEXT和accession_analysis的ID,这是一个不为空auto_increment变量。

我对如何修改此代码以实现此目标没有强烈的想法。我的第一次通过抓住所有的种子并通过它们循环,然后过滤所有的田地,然后更新。我不喜欢那样,因为我和很短的SQL命令有很多联系,我认为这些命令很糟糕,但我不禁想到真正做到这一点的唯一方法是回到Perl中的循环中,它持有两个简单的SQL语句。

有没有办法在SQL中做到这一点,与我的相对SQL缺乏经验,我只是没有看到?

答案取决于您使用的是哪个DBMS。最简单的方法是在一个表上创建一个触发器,以提供更新其他表的逻辑。 (对于任何DB新手 - 触发器是程序代码附加到DBMS(不是应用程序)层上的表,该表响应于在表上插入,更新或删除而运行)。一个类似的,不太理想的方法是将逻辑放入存储过程并执行,而不是您正在使用的更新语句。

如果您使用的DBMS不支持这两种机制中的任何一种,那么在保证事务完整性的同时,没有一种很好的方法可以完成您的工作。但是,如果您正在解决的问题可以容忍两个表的更新中的时间差异(即其中一个表中的数据仅用于预定时间,例如报表或某种类型的批处理操作),则可以写入一个表(live)并创建一个单独的进程,在需要时(稍后)使用第一个表中的数据更新第二个表时运行。然而,允许数据在不同时间更新的正确性成为一个大而不可移动的设计假设。

+0

虽然我不同意的愿望;-)一个触发器也可能是一个好主意,如果系统仍然可以维护之后... –

+0

很好的解决方案的描述,但学习做存储过程触发器似乎是一个长期的解决方案。我在Perl中通过循环实现了这一点,并将“在MySQL中学习存储过程和触发器”放到我的待办事项列表中。 –

如果这主要是关于连接速度,那么你有一个选择是编写一个存储过程,透明地处理“双重更新或插入”。请参阅手册存储过程:

http://dev.mysql.com/doc/refman/5.5/en/create-procedure.html

否则,你可能做不到在一个声明中,看到了MySQL INSERT语法:

http://dev.mysql.com/doc/refman/5.5/en/insert.html

UPDATE语法允许多台更新(不是与INSERT结合使用):

http://dev.mysql.com/doc/refman/5.5/en/update.html

每个表在查询中都需要自己的INSERT/UPDATE

事实上,即使您通过JOIN荷兰国际集团多个表的视图,当你INSERT到视图,你只能用INSERT属于在时间中的一个表的字段。

由INSERT语句所做的修改不能影响视图的FROM子句中引用的多个基表。例如,插入到多视图中的INSERT必须使用column_list,该列仅引用来自一个基表的列。有关可更新视图的更多信息,请参阅CREATE VIEW。

同样是UPDATE

UPDATE语句不能影响多个中引用的基表进行的修改真视图的FROM子句。有关可更新视图的更多信息,请参阅CREATE VIEW。

但是,每个查询或存储过程可以有多个INSERT s或UPDATE s。

+0

不错。感谢您的澄清... –