【问题标题】:How to write a trigger in PostgreSQL to compare a field to a field in another table如何在 PostgreSQL 中编写触发器以将字段与另一个表中的字段进行比较
【发布时间】:2011-04-23 11:10:40
【问题描述】:

这是我第一次尝试触发器。我已经了解触发器背后的概念和用途,但是我不太确定如何编写程序。

基本上我有一个表,我们称之为“Money”,其中有一个名为“Max_transaction_amount”的字段,还有一个名为“Currency_ID”的字段。然后,我有一个名为“Transactions”的表。基本上,我想要实现的是一种机制,每当将新交易添加到“交易”表中时,都会进行检查以查看与某种货币有关的所有交易的“计数”不超过“ Max_transaction_amount' 在名为'Money' 的表中,相对于'Currency_ID'。

对于有数据库经验的用户来说,这似乎是一个非常简单的问题,但是我仍在学习并想编写这样一个程序以从正确的角度开始。

很遗憾,我无法提供任何代码,因为我对如何执行此操作一无所知。然而,这是我“认为”可能的工作:

  • 触发器需要在更新“事务”表时执行
  • 该过程通过检查其“Currency_ID”来检查正在添加的记录中的“Max_transaction_amount”。
  • 执行一个 select 语句来查找符合该特定 'Currency_ID' 的行数
  • 将检查“货币”表中的“Max_transaction_amount”字段以查看该特定货币的最大金额
  • 在“交易”表中,与该特定货币有关的所有记录的计数与“最大交易金额”进行比较
  • 如果小于或等于最大数量,则保存更改。

任何帮助将不胜感激!


我已尝试编写以下过程...虽然语法被接受,但如果我尝试超过该数量,则不会发生任何事情。有人可以指导我正确的方向吗?

BEGIN

IF ((SELECT COUNT(Currency_ID) FROM "Transactions" WHERE "Currency_ID" = NEW.Currency_ID) > (SELECT "max_transaction_amount" FROM "Money" WHERE "Currency_ID" = NEW.Currency_ID)) THEN
RAISE EXCEPTION 'Error';

END IF;
END;

【问题讨论】:

  • 请向我们展示表的 DDL、样本数据和两种可能的 Transactions 操作:一种是您希望允许的,另一种是您希望拒绝的。 (我想当你的意思是“INSERT”时你说“UPDATE”,当你的意思是“SUM”时说“COUNT”等等——例子会更清楚。)
  • 感谢您的回复。不幸的是,我没有任何样本数据,因为这一切仍处于计划阶段。基本上,我想要完成的是查看输入的具有特定 ID 的记录数量,因此这些记录的“计数”是否小于或等于在另一个表中找到的字段中指定的值.

标签: sql database postgresql triggers plpgsql


【解决方案1】:

不确定我是否理解 max_transaction_amount 的存储方式,但在我看来,您可以通过 moneys 表中的 balance 列和检查约束来实现这一点。每次在事务表中插入一行时,余额都会更新

CREATE TABLE money 
(
   currency_id              integer not null,
   max_transaction_amount   numeric(18,2) not null,
   current_balance          numeric(18,2) not null default 0,
   primary key (currency_id),
   check (current_balance <= max_transaction_amount)
);

CREATE TABLE transactions 
(
  transaction_id       integer not null,
  transaction_amount   numeric(18,2) not null,
  currency_id          integer not null,
  primary key (transaction_id),
  foreign key (currency_id) references money (currency_id)
);

现在您只需要确保每次插入交易时都会更新 current_balance。这似乎是规则有意义的罕见情况之一(但也可以在触发器中完成 - 特别是如果您需要进行更多检查):

CREATE RULE transactions_insert AS 
  ON INSERT TO transactions
    DO UPDATE money 
          SET current_balance = current_balance + new.transaction_amount
       WHERE currency_id = new.currency_id;

现在更新current_balance 列时,检查约束将确保不超过max_transaction_amount

如果需要将UPDATEs 覆盖到表中,则需要创建另一个规则:

CREATE RULE transactions_update AS 
  ON UPDATE TO transactions
    DO UPDATE money 
          SET current_balance = current_balance - old.transaction_amount + new.transaction_amount
       WHERE currency_id = new.currency_id;

当然,这两个规则也可以用一个触发器函数来完成。

【讨论】:

  • 感谢您的回复!我不太确定这种规则格式,它与触发程序有什么不同吗?
  • 规则和触发器是两个完全不同的东西。有关详细信息,请参阅手册。
猜你喜欢
  • 1970-01-01
  • 2015-12-21
  • 2019-10-08
  • 1970-01-01
  • 2019-07-16
  • 2016-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多