2013-06-03 39 views
0

我有兩個表,我正在使用,定義如下。MySQL插入新行,在重複鍵上更新,如果一個鍵更改,觸發

CREATE TABLE dns_addresses_resolved (
    id INT(13) NOT NULL REFERENCES dns_addresses(id), 
    malware_id INT(13) REFERENCES malware_families(id), 
    type VARCHAR(10), 
    ttl int(10), 
    address VARCHAR(50), 
    first_resolved DATETIME, 
    last_resolved DATETIME, 
     PRIMARY KEY (id, address) 

) 

CREATE TABLE dns_addresses_resolved_archive (
    id INT(13) NOT NULL REFERENCES dns_addresses(id), 
    malware_id INT(13) REFERENCES malware_families(id), 
    type VARCHAR(10), 
    ttl int(10), 
    address VARCHAR(50), 
    first_resolved DATETIME, /* When was this IP first seen */ 
    archived_date DATETIME,  /* The date that the IP changes, and the 'old' IP is archived */ 
     PRIMARY KEY (id, address) 

) 

我試圖做的是:

  1. 插入行如果dns_addresses_resolved.id和dns_addresses_resolved.resolved_address不存在
  2. ON last_resolved重複鍵{中} dns_addresses_resolved UPDATE = NOW()
  3. 下面是我卡住的部分。當dns_addresses_resolved.resolved_address更改時,將當前該行中的數據 移動到dns_addresses_resolved_archive。我是 看着使用觸發器來做這最後一部分,但我卡住的地方 是剛剛resolved_address更改。

我在想,我想出了兩個三個部分,如圖下面 ,我只是想知道的任何人都可以提供一些線索就此對 我!我知道我可以在代碼中使用邏輯來做到這一點,但我是 使自己的生活變得艱難,因爲..好吧,學習很有趣!

INSERT INTO dns_addresses_resolved (id, type, ttl, resolved_address, first_resolved, last_resolved)  VALUES (?, ?, ?, 

?,NOW(),NOW())對重複密鑰更新last_resolved = NOW()

CREATE TRIGGER dns_resolved_archive BEFORE UPDATE ON dns_addresses_resolved.resolved_address FOR EACH ROW BEGIN  INSERT 

INTO dns_addresses_resolved_archive VALUES($ oldTable.id, $ oldTable.malware_id,$ oldTable .type,$ oldTable.ttl, $ oldTable.resolved_address,$ oldTable.first_resolved,NOW()); END

我也比開放的建議,如果任何人有更多的邏輯 做我想做的事情的方式。我很喜歡你的輸入!

編輯:我想出了一個觸發器,雖然更新到'地址'失敗,並導致一個mysql錯誤,我不知道爲什麼。該錯誤是

ERROR 1054(42S22):在 '字段列表'

起初似乎完全是直線前進未知列 'dns_addresses_resolved.id'。當我運行以下更新觸發器,我得到錯誤。當我運行相同的查詢沒有觸發器時,更新正常。

update dns_addresses_resolved set address = 'google.com' where id = 1; 

下面是我的觸發器。

CREATE TRIGGER archive_old_dns_resolution 
BEFORE UPDATE ON dns_addresses_resolved 
FOR EACH ROW 
BEGIN 
    IF NEW.address <> OLD.address THEN 
     INSERT INTO dns_addresses_resolved_archive 
     VALUES ($oldTable.id, $oldTable.malware_id, $oldTable.type, $oldTable.ttl, $oldTable.address, $oldTable.first_resolved, NOW()); 
    END IF; 
END 

所以考慮到觸發似乎是最合理的解決方案,我想要做的,爲什麼會發生這種觸發引起更新SQL錯誤?

回答

0

如果更改爲resolved_address,您將不會獲得重複項,因爲該組合的主鍵不會存在。在這種情況下會發生直插。我也不認爲UPDATE觸發器可以爲你工作,因爲即使你只爲id尋址一個單獨的索引以便觸發更新,你也無法知道更新是否觸發了時間戳應該更新或者提供新的resolved_address時。

我猜你試圖用一個查詢來完成這項工作,但我不知道你是否有一個乾淨的解決方案,因爲本質上你有兩個獨特的索引(一個在id和一個在id,resolved_address),你想提供不同的行爲,如果嘗試執行插入時條目已經存在。

我的猜測是你需要創建一個存儲過程(如果你想單個數據庫調用),或者你需要使用多個查詢來實現你想要做的事情。

+0

謝謝,邁克。這或多或少是我會來的結論。我只是希望有人會對我有一個神奇的答案:) – geudrik

+0

我找到了一個解決方案,但當觸發器觸發時更新失敗。 OP已更新爲包含我的觸發器。 – geudrik

相關問題