Postgresql 插入触发器中的字符串匹配-如何在条件中使用以返回NULL?
在采用UTF8编码的PostgreSQL 8.4.13数据库中,我在下表中保留了一本(非英语)词典:Postgresql 插入触发器中的字符串匹配-如何在条件中使用以返回NULL?,postgresql,triggers,plpgsql,string-matching,postgresql-8.4,Postgresql,Triggers,Plpgsql,String Matching,Postgresql 8.4,在采用UTF8编码的PostgreSQL 8.4.13数据库中,我在下表中保留了一本(非英语)词典: create table good_words ( word varchar(64) primary key ); 以及下列错误(但经常提示或键入错误)单词的列表: create table bad_words ( word varchar(64) primary key ); 对于前一个表,我有一个我正在尝试扩展的表: create or replace f
create table good_words (
word varchar(64) primary key
);
以及下列错误(但经常提示或键入错误)单词的列表:
create table bad_words (
word varchar(64) primary key
);
对于前一个表,我有一个我正在尝试扩展的表:
create or replace function keep_clean() returns trigger as $body$
begin
new.word := upper(new.word);
perform true
from bad_words
where word = new.word;
if found then
return null;
end if;
-- forbid words with [XYZ] at beginning and Z at the end
-- forbid words with LLL unless it is KLLL or MLLL
return new;
end;
$body$ language plpgsql;
create trigger count_letters
BEFORE INSERT on good_words
for each row execute procedure keep_clean();
我的问题是:我正在尝试向触发器添加3条规则(返回NULL
):
类似“%KLLL%”或类似“%MLLL%”的情况下才允许使用这些单词。
SELECT-INTO
或perform
?或者我可以在这里使用:=
运算符,或者甚至可以在IF
语句中执行字符串匹配
更新:
在Craig的解释(谢谢!)之后,我已经准备好了,但它仍然有两个问题:
create table good_words (
word varchar(64) primary key
);
create or replace function keep_clean() returns trigger as $body$
begin
new.word := upper(new.word);
/* next line does not compile? */
IF new.word !~ '^[\x0410-\x042F]{2,}$' THEN
RAISE EXCEPTION 'Not an uppercased Russian word in UTF8';
END IF;
IF new.word ~ '^[ЪЫЬ]' OR new.word ~ 'Ъ$' THEN
return NULL;
END IF;
/* does not return NULL for 'ошибббка'? */
IF new.word ~ '(.)\1\1' AND new.word NOT LIKE '%ШЕЕЕ%' AND new.word NOT LIKE '%ЗМЕЕЕ%' THEN
return NULL;
END IF;
return new;
end;
$body$ language plpgsql;
此处不应采用UTF8编码中的前两个单词,但它确实:
insert into good_words (word)
values
('abcde'), /* bad word: non-russian */
('ошибббка'), /* bad word: 3 letters in a row */
('длинношеее'),
('проверка')
;
select * from good_words;
更新2:触发器现在可以工作了,谢谢:使用PostgreSQL的
~
运算符或regexp\u matches
函数。请参阅文档中的
简单的PL/PgSQL示例:
DO
$$
BEGIN
IF 'XABCK' ~ '^[XY]' THEN
RAISE EXCEPTION 'Disallowed character';
END IF;
END;
$$;
如您所见,
IF
可以接受表达式。这些表达式可能具有任意复杂性,可能包括子查询、CASE
,几乎所有SQL中合法的内容。谢谢!你能看看我的SQL小提琴中的两个问题吗?我已经更新了我的问题too@AlexanderFarber升级PostgreSQL;我敢肯定,在8.4中,regex中对utf-8的支持相当缺乏。您的“俄语单词”regexp在9.2上编译并运行良好。您为什么不为此创建一个检查约束?我反复向我的good_words
表中输入新词以扩展词典,并希望不好的单词只是无声地失败-这与检查约束不同。我在插入触发器中还做了更多的工作:我计算字母频率,并将其存储在数组列中(在我的问题中省略),用于文字游戏。