2011-08-17 65 views
2

這是我用於基於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缺乏經驗,我只是沒有看到?

回答

2

答案取決於您使用的是哪個DBMS。最簡單的方法是在一個表上創建一個觸發器,以提供更新其他表的邏輯。 (對於任何DB新手 - 觸發器是程序代碼附加到DBMS(不是應用程序)層上的表,該表響應於在表上插入,更新或刪除而運行)。一個類似的,不太理想的方法是將邏輯放入存儲過程並執行,而不是您正在使用的更新語句。

如果您使用的DBMS不支持這兩種機制中的任何一種,那麼在保證事務完整性的同時,沒有一種很好的方法可以完成您的工作。但是,如果您正在解決的問題可以容忍兩個表的更新中的時間差異(即其中一個表中的數據僅用於預定時間,例如報表或某種類型的批處理操作),則可以寫入一個表(live)並創建一個單獨的進程,在需要時(稍後)使用第一個表中的數據更新第二個表時運行。然而,允許數據在不同時間更新的正確性成爲一個大而不可移動的設計假設。

+0

雖然我不同意的願望;-)一個觸發器也可能是一個好主意,如果系統仍然可以維護之後... –

+0

很好的解決方案的描述,但學習做存儲過程觸發器似乎是一個長期的解決方案。我在Perl中通過循環實現了這一點,並將「在MySQL中學習存儲過程和觸發器」放到我的待辦事項列表中。 –

2

如果這主要是關於連接速度,那麼你有一個選擇是編寫一個存儲過程,透明地處理「雙重更新或插入」。請參閱手冊存儲過程:

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

1

每個表在查詢中都需要自己的INSERT/UPDATE

事實上,即使您通過JOIN荷蘭國際集團多個表的視圖,當你INSERT到視圖,你只能用INSERT屬於在時間中的一個表的字段。

由INSERT語句所做的修改不能影響視圖的FROM子句中引用的多個基表。例如,插入到多視圖中的INSERT必須使用column_list,該列僅引用來自一個基表的列。有關可更新視圖的更多信息,請參閱CREATE VIEW。

同樣是UPDATE

UPDATE語句不能影響多個中引用的基表進行的修改真視圖的FROM子句。有關可更新視圖的更多信息,請參閱CREATE VIEW。

但是,每個查詢或存儲過程可以有多個INSERT s或UPDATE s。

+0

不錯。感謝您的澄清... –

相關問題