如何使用PostgreSQL触发器?

发布于 2024-09-28 11:19:26 字数 461 浏览 1 评论 0原文

我正在尝试在我的 Rails 应用程序中使用 PostgreSQL 触发器。因此,我尝试使用此迁移,其中触发器的执行应该很容易:

-- class AddTriggersToProducts < ActiveRecord::Migration
  def self.up
    table :products
    execute %q{
        create trigger trig1 before insert on products for each row
        begin 
        price = price + 5
        end;
        }
  end

  def self.down
    execute 'DROP TRIGGER trig1'
  end
end

但这并没有改变任何内容。如果我要在这里使用过程或函数,我不知道在哪里编写过程或函数......

I am trying to use PostgreSQL triggers in my rails app. So I tried using this migration where execution of triggers is supposedly easy:

-- class AddTriggersToProducts < ActiveRecord::Migration
  def self.up
    table :products
    execute %q{
        create trigger trig1 before insert on products for each row
        begin 
        price = price + 5
        end;
        }
  end

  def self.down
    execute 'DROP TRIGGER trig1'
  end
end

But this didn't change anything. I don't know where to write the procedure or function if I am going to use one here ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

独自唱情﹋歌 2024-10-05 11:19:26

“创建触发器”由两个步骤组成在 PostgreSQL 中:

1.) 创建一个触发函数< /a> - 具有特殊返回值trigger

CREATE FUNCTION trg_update_prod_price()
  RETURNS trigger AS
$func$
BEGIN
   NEW.price := NEW.price + 5;
   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

多个触发器可以使用相同的触发函数。

2.) 创建触发器调用现有的触发器函数:

CREATE TRIGGER update_prod_price
BEFORE INSERT ON products
FOR EACH ROW EXECUTE PROCEDURE trg_update_prod_price();

“删除触发器”(意味着触发函数),您必须首先删除引用它的所有触发器,然后删除触发器函数本身。

DROP TRIGGER update_prod_price ON products;
DROP FUNCTION trg_update_prod_price();

如果删除一个表,所有附加的触发器也会随之删除。无需单独删除它们。

"Creating a trigger" consists of two steps in PostgreSQL:

1.) Create a trigger function - with special return value trigger:

CREATE FUNCTION trg_update_prod_price()
  RETURNS trigger AS
$func$
BEGIN
   NEW.price := NEW.price + 5;
   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

Multiple triggers can use the same trigger function.

2.) Create a trigger calling an existing trigger function:

CREATE TRIGGER update_prod_price
BEFORE INSERT ON products
FOR EACH ROW EXECUTE PROCEDURE trg_update_prod_price();

To "drop the trigger" (meaning the trigger function), you have to first drop all triggers referencing it and then drop the trigger function itself.

DROP TRIGGER update_prod_price ON products;
DROP FUNCTION trg_update_prod_price();

If you drop a table, all attached triggers are dropped with it. No need to drop those separately.

绝對不後悔。 2024-10-05 11:19:26

这样的东西有用吗?创建一个函数,然后为触发器执行该函数:

   def self.up 
     execute %q{
       create or replace function update_price() returns trigger as $
         begin
           NEW.price := NEW.price + 5;
           return NEW;
         end;
       $ language plpgsql }

      execute %{ create trigger trig1 before insert on products for each row execute function update_price()}
  end

Does something like this work? Creating a function and then executing the function for the trigger:

   def self.up 
     execute %q{
       create or replace function update_price() returns trigger as $
         begin
           NEW.price := NEW.price + 5;
           return NEW;
         end;
       $ language plpgsql }

      execute %{ create trigger trig1 before insert on products for each row execute function update_price()}
  end
尝蛊 2024-10-05 11:19:26

hair_trigger gem 是管理触发器创建的好方法。

这是 Hair_trigger 文档中的示例:

class AccountUser < ActiveRecord::Base
  trigger.after(:insert) do
    "UPDATE accounts SET user_count = user_count + 1 WHERE id = NEW.account_id;"
  end

  trigger.after(:update).of(:name) do
    "INSERT INTO user_changes(id, name) VALUES(NEW.id, NEW.name);"
  end
end

The hair_trigger gem is a nice way to manage the creation of triggers.

Here is an example from hair_trigger's docs:

class AccountUser < ActiveRecord::Base
  trigger.after(:insert) do
    "UPDATE accounts SET user_count = user_count + 1 WHERE id = NEW.account_id;"
  end

  trigger.after(:update).of(:name) do
    "INSERT INTO user_changes(id, name) VALUES(NEW.id, NEW.name);"
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文