我有两个正在使用的表,定义如下。
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)
)
我想做的是:
- 如果 dns_addresses_resolved.id 和 dns_addresses_resolved.resolved_address 不存在,则插入行
- ON DUPLICATE KEY {in dns_addresses_resolved} UPDATE last_resolved = NOW()
- 这是我卡住的部分。当 dns_addresses_resolved.resolved_address 发生变化时,将该行中当前的数据移动到
dns_addresses_resolved_archive
. 我一直在考虑使用触发器来完成最后一部分,但我遇到困难的地方是当 resolve_address 发生变化时。我想我想出了三个部分中的两个,如下所示,我只是想知道任何人都可以为我阐明这一点!我知道我可以在代码中使用逻辑来做到这一点,但我让自己的生活变得艰难,因为……嗯,学习很有趣!
INSERT INTO dns_addresses_resolved (id, type, ttl, resolved_address, first_resolved, last_resolved) VALUES ( ?, ?, ?,
?, NOW(), NOW() ) ON DUPLICATE KEY UPDATE 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 值($oldTable.id、$oldTable.malware_id、$oldTable.type、$oldTable.ttl、$oldTable.resolved_address、$oldTable.first_resolved、NOW());结尾
如果有人有更合乎逻辑的方式来做我想做的事情,我也非常愿意接受建议。我会喜欢你的意见!
编辑:我想出了一个触发器,尽管对“地址”的更新失败,并导致一个 mysql 错误,我不知道为什么。错误是
错误 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 错误?