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', '')

..因为前导字符应该只是数字(并且至少是其中一个)。

正确的触发和功能

以下测试用例适用于 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. 警告表明您没有启用此设置,这需要您将反斜杠加倍:

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