Postgresql约束检查非ascii字符

时间:2014-09-19 01:50:00

标签: postgresql postgresql-9.3

我有一个Postgresql 9.3数据库,编码为'UTF8'。但是,数据库中有一列不应包含除ASCII之外的任何内容。如果非ascii进入那里,它会导致另一个我无法控制的系统出现问题。因此,我想为列添加约束。注意:我已经有一个BEFORE INSERT触发器 - 所以这可能是一个检查的好地方。

在PostgreSQL中实现此目的的最佳方法是什么?

2 个答案:

答案 0 :(得分:8)

为此,您可以将ASCII定义为ordinal 1 to 127,因此以下查询将标识带有"非ascii"的字符串。值:

SELECT exists(SELECT 1 from regexp_split_to_table('abcdéfg','') x where ascii(x) not between 1 and 127);

但它不太可能超级高效,并且使用子查询会强制您在触发器而不是CHECK约束中执行此操作。

相反,我使用正则表达式。如果您想要所有可打印字符,那么您可以在检查约束中使用范围,例如:

CHECK (my_column ~ '^[ -~]*$')

this will match everything from the space to the tilde,这是可打印的ASCII范围。

如果您想要所有ASCII,可打印和不可打印的,可以use byte escapes

CHECK (my_column ~ '^[\x00-\x7F]*$')

最严格的正确方法是convert_to(my_string, 'ascii'),如果失败则会引发异常......但PostgreSQL不提供ascii(即7位)编码,所以这种方法是不可能的。

答案 1 :(得分:3)

使用围绕regular expression构建的CHECK约束。

假设您的意思是某个列永远不应包含除 a z 的小写字母以外的任何内容,则 A 中的大写字母为 Z ,数字 0 9 ,这样的事情应该有效。

alter table your_table
add constraint allow_ascii_only
check (your_column ~ '^[a-zA-Z0-9]+$');

人们通常在谈论"只有ASCII"关于数据库列,但ASCII还包括标点符号,算术运算符等的字形。您想要允许的字符位于方括号之间。