MariaDB 触发器执行更新,然后在同一个 table 上执行插入
MariaDB trigger to perform an UPDATE and then an INSERT on the same table
我目前有一个 account
table 和一个 account_audit
table(所有代码都可以在 fiddle here 上找到)。
我有两个触发器,它们根据插入帐户 table 的数据将记录插入 account_audit table。
1 个触发器是一个 ON INSERT 触发器,它只插入这些值 - 工作正常。
因此,在我的审核中插入 2 条记录后 table - 我在两个 table 中都有两条记录,如下所示。
SELECT * FROM account;
给予
acct_id acct_name acct_balance tax_rate acct_opened
1 Bill 100.00 0.10 2019-11-01
2 Ben 1000.00 0.10 2019-11-01
和
SELECT * FROM account_audit;
给予
acct_id txn_id acct_name acct_balance tax_rate valid_from valid_to
1 1 Bill 100.00 0.10 2021-11-07 2038-01-19
2 2 Ben 1000.00 0.10 2021-11-07 2038-01-19
一切都很好 - 2038 年是 MariaDB 无限 - 至少在时间上 tables!
但是,我的UPDATE触发器如下:
CREATE TRIGGER testtrigger_upd
AFTER UPDATE ON account
FOR EACH ROW BEGIN
UPDATE account_audit SET valid_to = NOW()
WHERE ((valid_to = '2038-01-19') AND (OLD.acct_name = NEW.acct_name));
INSERT INTO
account_audit (acct_id, acct_name, acct_balance, tax_rate)
VALUES
(
OLD.acct_id,
OLD.acct_name,
NEW.acct_balance,
OLD.tax_rate
-- valid_from - NOW()!
-- valid_to DEFAULTs to '2038-01-19' which is what we want for updates to balance
);
END;
因此,当我更新帐户余额时,我希望 account_audit 跟踪反映这一点,然后将最近(插入之前)的余额记录转到 valid_to
(今天)和今天的新记录 valid_from
到 2038 年的 valid_to
(MariaDB 的无穷大?)。
问题是当我运行这个语句
UPDATE account
SET acct_balance = acct_balance + 50 WHERE acct_name = 'Bill'; -- name is UNIQUE
account_audittable中的记录变为:
acct_id txn_id acct_name acct_balance tax_rate valid_from valid_to
1 1 Bill 100.00 0.10 2021-11-07 2021-11-07
1 3 Bill 150.00 0.10 2021-11-07 2038-01-19
2 2 Ben 1000.00 0.10 2021-11-07 2021-11-07
您可以看到 Bill 的记录已被插入,但 问题 Ben 的记录也已更新为今天的插入日期 - 我只希望 Bill 发生这种情况很明显!
我的触发器中有 WHERE ((valid_to = '2038-01-19') AND (OLD.acct_name = NEW.acct_name));
并且我尝试了很多其他的 - WHERE OLD.acct_id = NEW.acct_id
我尝试更改更新以使用 acct_id 而不是名称 - 没有任何效果。我尝试交换旧的。和新的。订单 - 在更新之前或之后尝试 - 我真的疯了!
我如何重写触发器来更新 account_audit table 仅 其帐户所在的人而不是所有帐户 - 也就是说比如,只更新 Bill 的帐户而不更新 Ben 的帐户?
我知道临时 table 功能 - 我不想使用它,因为这是为了研究,我必须使用触发器!
Fiddle 是 here.
那是因为你的 where 子句对所有行都是 true
因此更改更新查询以检查 table
CREATE TRIGGER testtrigger_upd
AFTER UPDATE ON account
FOR EACH ROW BEGIN
UPDATE account_audit SET valid_to = NOW()
WHERE ((valid_to = '2038-01-19') AND (acct_name = NEW.acct_name));
INSERT INTO
account_audit (acct_id, acct_name, acct_balance, tax_rate)
VALUES
(
OLD.acct_id,
OLD.acct_name,
NEW.acct_balance,
OLD.tax_rate
-- valid_from - NOW()!
-- valid_to DEFAULTs to '2038-01-19' which is what we want for updates to balance
);
END;
UPDATE account
SET acct_balance = acct_balance + 50 WHERE acct_name = 'Bill';
SELECT * FROM account_audit
acct_id | txn_id | acct_name | acct_balance | tax_rate | valid_from | valid_to
------: | -----: | :-------- | -----------: | -------: | :--------- | :---------
1 | 1 | Bill | 100.00 | 0 | 2021-11-07 | 2021-11-07
2 | 2 | Ben | 1000.00 | 0 | 2021-11-07 | 2038-01-19
1 | null | Bill | 150.00 | 0 | null | null
db<>fiddle here
在我看来,where 子句
WHERE ((valid_to = '2038-01-19') AND (OLD.acct_name = NEW.acct_name));
对 Ben 和 Bill 都有效。所以它会为他们两个更新。
一个解决方案可能是将其稍微更改为:
WHERE ((valid_to = '2038-01-19') AND (acct_name = OLD.acct_name));
我目前有一个 account
table 和一个 account_audit
table(所有代码都可以在 fiddle here 上找到)。
我有两个触发器,它们根据插入帐户 table 的数据将记录插入 account_audit table。
1 个触发器是一个 ON INSERT 触发器,它只插入这些值 - 工作正常。
因此,在我的审核中插入 2 条记录后 table - 我在两个 table 中都有两条记录,如下所示。
SELECT * FROM account;
给予
acct_id acct_name acct_balance tax_rate acct_opened
1 Bill 100.00 0.10 2019-11-01
2 Ben 1000.00 0.10 2019-11-01
和
SELECT * FROM account_audit;
给予
acct_id txn_id acct_name acct_balance tax_rate valid_from valid_to
1 1 Bill 100.00 0.10 2021-11-07 2038-01-19
2 2 Ben 1000.00 0.10 2021-11-07 2038-01-19
一切都很好 - 2038 年是 MariaDB 无限 - 至少在时间上 tables!
但是,我的UPDATE触发器如下:
CREATE TRIGGER testtrigger_upd
AFTER UPDATE ON account
FOR EACH ROW BEGIN
UPDATE account_audit SET valid_to = NOW()
WHERE ((valid_to = '2038-01-19') AND (OLD.acct_name = NEW.acct_name));
INSERT INTO
account_audit (acct_id, acct_name, acct_balance, tax_rate)
VALUES
(
OLD.acct_id,
OLD.acct_name,
NEW.acct_balance,
OLD.tax_rate
-- valid_from - NOW()!
-- valid_to DEFAULTs to '2038-01-19' which is what we want for updates to balance
);
END;
因此,当我更新帐户余额时,我希望 account_audit 跟踪反映这一点,然后将最近(插入之前)的余额记录转到 valid_to
(今天)和今天的新记录 valid_from
到 2038 年的 valid_to
(MariaDB 的无穷大?)。
问题是当我运行这个语句
UPDATE account
SET acct_balance = acct_balance + 50 WHERE acct_name = 'Bill'; -- name is UNIQUE
account_audittable中的记录变为:
acct_id txn_id acct_name acct_balance tax_rate valid_from valid_to
1 1 Bill 100.00 0.10 2021-11-07 2021-11-07
1 3 Bill 150.00 0.10 2021-11-07 2038-01-19
2 2 Ben 1000.00 0.10 2021-11-07 2021-11-07
您可以看到 Bill 的记录已被插入,但 问题 Ben 的记录也已更新为今天的插入日期 - 我只希望 Bill 发生这种情况很明显!
我的触发器中有 WHERE ((valid_to = '2038-01-19') AND (OLD.acct_name = NEW.acct_name));
并且我尝试了很多其他的 - WHERE OLD.acct_id = NEW.acct_id
我尝试更改更新以使用 acct_id 而不是名称 - 没有任何效果。我尝试交换旧的。和新的。订单 - 在更新之前或之后尝试 - 我真的疯了!
我如何重写触发器来更新 account_audit table 仅 其帐户所在的人而不是所有帐户 - 也就是说比如,只更新 Bill 的帐户而不更新 Ben 的帐户?
我知道临时 table 功能 - 我不想使用它,因为这是为了研究,我必须使用触发器!
Fiddle 是 here.
那是因为你的 where 子句对所有行都是 true
因此更改更新查询以检查 table
CREATE TRIGGER testtrigger_upd AFTER UPDATE ON account FOR EACH ROW BEGIN UPDATE account_audit SET valid_to = NOW() WHERE ((valid_to = '2038-01-19') AND (acct_name = NEW.acct_name)); INSERT INTO account_audit (acct_id, acct_name, acct_balance, tax_rate) VALUES ( OLD.acct_id, OLD.acct_name, NEW.acct_balance, OLD.tax_rate -- valid_from - NOW()! -- valid_to DEFAULTs to '2038-01-19' which is what we want for updates to balance ); END;
UPDATE account SET acct_balance = acct_balance + 50 WHERE acct_name = 'Bill';
SELECT * FROM account_audit
acct_id | txn_id | acct_name | acct_balance | tax_rate | valid_from | valid_to ------: | -----: | :-------- | -----------: | -------: | :--------- | :--------- 1 | 1 | Bill | 100.00 | 0 | 2021-11-07 | 2021-11-07 2 | 2 | Ben | 1000.00 | 0 | 2021-11-07 | 2038-01-19 1 | null | Bill | 150.00 | 0 | null | null
db<>fiddle here
在我看来,where 子句
WHERE ((valid_to = '2038-01-19') AND (OLD.acct_name = NEW.acct_name));
对 Ben 和 Bill 都有效。所以它会为他们两个更新。
一个解决方案可能是将其稍微更改为:
WHERE ((valid_to = '2038-01-19') AND (acct_name = OLD.acct_name));