0

tsvector 列に対して次の更新トリガーがあります

CREATE TRIGGER tsvector_user_update
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW EXECUTE PROCEDURE 
tsvector_update_trigger(user_tsv, 'pg_catalog.english', firstname, surname, email, card_id);

これは正常に動作しますが、私の card_id 列 (テキスト) には、ユーザーが認識していないプリアンブル (カードがスキャンされた後に追加される) が含まれているため、tsvector 値が生成されたので、トリガー機能を手始めに試してみました

CREATE FUNCTION user_change_trigger() RETURNS trigger AS $$
BEGIN
NEW.user_tsv = setweight(to_tsvector('pg_catalog.english', coalesce(NEW.firstname,'')), 'A') ||
    setweight(to_tsvector('pg_catalog.english', coalesce(NEW.surname,'')), 'A') ||
    setweight(to_tsvector('pg_catalog.english', coalesce(REGEXP_REPLACE(NEW.card_id, '^\d+PRE', ''),'')), 'B') ||
    setweight(to_tsvector('pg_catalog.english', coalesce(NEW.email,'')), 'C');
    return new;
END

$$ LANGUAGE plpgsql;

CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
ON users FOR EACH ROW EXECUTE PROCEDURE user_change_trigger();

これは実行されますが、次のようになります。

WARNING:  nonstandard use of escape in a string literal

そして、更新された tsvector はありません

プリアンブルは整数の後に「PRE」が続きます。

(PostgreSQL 9.0)

4

1 に答える 1

3

トリガーの基本設計

問題は本質的なものです。PostgreSQL では、作業を行うトリガー関数を作成します。質問にトリガー機能がありません。

次に、この関数を利用するトリガーを作成します。トリガー関数には定数のみを渡すことができます。についてのマニュアルからのこの引用を検討してくださいCREATE TRIGGER

関数名

引数を取らず、トリガーの起動時に実行される型トリガーを返すとして宣言されているユーザー指定の関数。

引数

トリガーの実行時に関数に提供されるオプションのコンマ区切りの引数のリスト。引数はリテラル文字列定数です。単純な名前や数値定数もここに記述できますが、すべて文字列に変換されます。関数内でこれらの引数にアクセスする方法については、トリガー関数の実装言語の説明を確認してください。通常の関数の引数とは異なる場合があります。

大胆強調鉱山。

NEWトリガー関数内の列値にアクセスするために使用します。それらを引数として渡す必要はありません。まずは基本コンセプトをしっかりと。ここから始める。

regexp_replace()

使用する:

regexp_replace(card_id, '^\d+PRE', '')

.. 先頭の文字は数字のみ (および少なくとも 1 つ) であると想定されているためです。

適切なトリガーと機能

次のテスト ケースは、PostgreSQL 9.1.6 で動作します。あなたのバージョンは基本的には良さそうに見えますが、マイナーな変更を加えただけです。しかし、読み続けてください...

テスト環境を作成します (最後にロールバックされます):

BEGIN;
CREATE SCHEMA test;
SET search_path = test;

CREATE TABLE users (
    users_id serial primary key
   ,firstname text
   ,surname text
   ,card_id text
   ,email text
   ,user_tsv tsvector
   );

トリガー機能:

CREATE FUNCTION user_change_trigger()
  RETURNS trigger AS
$func$
BEGIN

NEW.user_tsv :=
   setweight(to_tsvector('pg_catalog.english', coalesce(NEW.firstname,'')), 'A')
|| setweight(to_tsvector('pg_catalog.english', coalesce(NEW.surname,'')), 'A')
|| setweight(to_tsvector('pg_catalog.english', coalesce(regexp_replace(NEW.card_id, '^\d+PRE', ''),'')), 'B')
|| setweight(to_tsvector('pg_catalog.english', coalesce(NEW.email,'')), 'C');

RETURN NEW;
END

$func$ LANGUAGE plpgsql;

plpgsqlの代入演算子は:=- が使用されている SQL とは異なります=

引き金:

CREATE TRIGGER tsvectorupdate
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW EXECUTE PROCEDURE user_change_trigger();

テスト:

INSERT INTO users (firstname, surname, card_id, email)
VALUES ('Erwin', 'Brandstetter', '123PRE456', 'foo@dummy.org')
RETURNING *;

-- looks good!

UPDATE users SET firstname = 'Walter' WHERE TRUE
RETURNING *;

-- looks good, too!

掃除:

ROLLBACK;

standard_conforming_strings

の設定を調べてくださいstandard_conforming_strings。WARNING は、この設定をオンにしていないことを示唆しており、バックスラッシュを 2 倍にする必要があります。

'^\\d+PRE'
于 2012-12-06T12:14:33.487 に答える