web-dev-qa-db-ja.com

PostgreSQL:カスタム列でupdated_atを自動更新

以前は、複数のテーブルを1つに結合して結果を返していましたが、多くのテーブルで同じ列名がありました。そのため、列名の前にテーブル名を付けることにしました。しかし、それが原因でupdated_at列を自動更新する必要がありました。

これは私が持っていた機能です:

CREATE OR REPLACE FUNCTION update_updated_at()
  RETURNS TRIGGER AS $$
  BEGIN
      NEW.updated_at = now();
      RETURN NEW;
  END;
  $$ language 'plpgsql';

そして、私は次のようなトリガーを追加します:

CREATE TRIGGER update_users_updated_at
  BEFORE UPDATE ON users
  FOR EACH ROW EXECUTE PROCEDURE update_updated_at();

しかし、私の列はusers_updated_atという名前になり、これは機能しません。私の質問は、列名をトリガーに渡して、渡された列を更新する方法があるのか​​、それとも他の方法で気付いていないのですか?

8
Ivanstame

spi module 's moddatetimeを使用します

spiモジュール、moddatetime

moddatetime —最終変更時間を追跡するための関数

moddatetime()は、現在の時刻をtimestampフィールドに格納するトリガーです。これは、テーブル内の特定の行の最終変更時刻を追跡するのに役立ちます。

使用するには、この関数を使用してBEFORE UPDATEトリガーを作成します。単一のトリガー引数(変更する列の名前)を指定します。列のタイプはタイムスタンプまたはタイムゾーン付きのタイムスタンプでなければなりません。

moddatetime.example に例があります。

例/概要

上記から 参照ファイル

DROP TABLE mdt;

CREATE TABLE mdt (
    id      int4,
    idesc       text,
    moddate timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL
);

CREATE TRIGGER mdt_moddatetime
    BEFORE UPDATE ON mdt
    FOR EACH ROW
    EXECUTE PROCEDURE moddatetime (moddate);

INSERT INTO mdt VALUES (1, 'first');
INSERT INTO mdt VALUES (2, 'second');
INSERT INTO mdt VALUES (3, 'third');

SELECT * FROM mdt;

UPDATE mdt SET id = 4
    WHERE id = 1;
UPDATE mdt SET id = 5
    WHERE id = 2;
UPDATE mdt SET id = 6
    WHERE id = 3;

SELECT * FROM mdt;

あなたの申請

だから、これはあなたがする必要があるでしょう。

CREATE EXTENSION spi;

ALTER TABLE users ALTER timestamp_at SET DEFAULT now();

DROP TRIGGER IF EXISTS
  update_users_updated_at ON users;

CREATE TRIGGER mdt_users
  BEFORE UPDATE ON users
  FOR EACH ROW
  EXECUTE PROCEDURE moddatetime (timestamp_at);
7
Evan Carroll