2012-11-29 121 views
1

我需要同步來自不同Firebird數據庫的兩個表中的數據。確切地說,我需要使用表Users(第二DB)的記錄更新表Person(1st DB)中的記錄。不僅「名稱」,「電子郵件」,「生日」,但ID也(!)。問題在於 - 有些表通過FOREIGN KEY約束依賴於Person的ID。外鍵參考目標不存在

我試圖做到這一點:

  1. 刪除外的從屬表鍵約束。
  2. 同步兩個表(這意味着更新/更改表Person中的ID)
  3. 更改從屬表中的相應ID。
  4. 在從屬表中添加外鍵約束。

最後一步會導致錯誤(日誌從Java應用程序,但它是相同的,如果我執行這些步驟直接IBExpert):

com.bssys.db.jdbc.DBSQLException: GDS Exception. 335544466. violation of FOREIGN KEY constraint "FK_EMPLOYEE_PERSON" on table "EMPLOYEE" 
Foreign key reference target does not exist, error code: HY000 
Reason: violation of FOREIGN KEY constraint "FK_EMPLOYEE_PERSON" on table "EMPLOYEE" 

(員工 - 是從屬表之一)

我的問題是,我是否可以避免這個錯誤。或者,也許有關於如何更改相關表中的ID的一些想法。可能有特殊的RDBMS工具來同步數據庫,但我需要通過Java應用程序同步它們,因此只使用sql和java。我使用Firebird 2.5.1。

完整的SQL語句(例如):

  1. ALTER TABLE employee DROP CONSTRAINT fk_employee_person 
    
  2. UPDATE person SET id = 555555 WHERE id = 3000005 
    
  3. UPDATE employee SET person_id = 555555 WHERE person_id = 3000005 
    
  4. ALTER TABLE employee ADD CONSTRAINT fk_employee_person FOREIGN KEY (person_id) REFERENCES person(id) 
    

一些新的信息:它看起來像有時IBExpert讓我去通過這些步驟。實際上,如果我在其中一個表處於「數據」模式(我想,它也是某種交易,如CREATE VIEW)中更改了所有ID,則會發生錯誤。

我還發現,刪除/添加外鍵,需要整個數據庫至少到上排它鎖火鳥2.1(甚至2.5)

+0

請向我們展示您正在執行的完整SQL語句 –

+0

您是在一個事務中執行步驟2和3還是使用自動提交? –

回答

3

您應該創建表,以便外鍵確實有ON UPDATE CASCADE條款 - 那麼當您更新ID時,它也會在從屬表中更新,而您無需付出任何額外的努力。因此,對於每個參考Person表的表,你需要做以下幾點:

-- delete the original FK constraint 
ALTER TABLE _table_ DROP CONSTRAINT _fk_constraint_name_; 
-- (re)add the FK constraint with ON UPDATE CASCADE 
ALTER TABLE _table_ ADD CONSTRAINT _fk_constraint_name_ FOREIGN KEY (person_id) REFERENCES person(id) ON UPDATE CASCADE; 
+0

我個人喜歡「ON UPDATE CASCADE」,但我只是一個新手,並且正在與一個已經很大的項目合作,因爲某些原因,這個建設並沒有被使用。我實際上試圖放棄我的fk_ constrainsts,添加新的選擇「ON UPDATE CASCADE」選項,然後更新Person(id),然後再次刪除fk_約束,然後在沒有「ON UPDATE CASCADE」選項的情況下重新創建它們(非常蹩腳,我知道^^)。但它不起作用:/ IBExpert在最後一步仍然給我一個錯誤。 Wierdo。 – Tekiteki

1

而是重編的主鍵,插入新記錄到person用正確的主鍵,然後更新的employee外鍵值和刪除舊的person記錄。

注意:下面的部分是主觀的,更多的是意見而非事實。

順便說一句:需要重新編號您的主鍵通常是一個設計問題的跡象。主鍵在數據庫之外應該沒有意義,並且在給定記錄的整個生命週期中它們通常應該保持穩定。在你的情況下,顯然關鍵還意味着你的數據庫以外的東西,也是不穩定的。

如在答案艾因,你可以使用ON UPDATE CASCADE表示,但恕我直言,通常是這個問題的補丁,而不是解決辦法。解決方法是:如果主鍵不穩定:使這些唯一鍵並添加無意義的主鍵,而不需要更改。

+0

謝謝!我期待着實施您的解決方案^^這對於設計問題的數據庫應用程序來說是一個很好的解決方案。我會在稍後寫出結果。至於ID同步,我也有一種感覺,這很奇怪,並詢問老年開發人員,但他們說這是需要的。 – Tekiteki