Postgres 文本列只有 allows/converts 小写并且没有特殊字符,例如:Ñöáè
Postgres text column that only allows/converts to lowercase and no special characters such as: Ñöáè
我有一个 table,我希望该 1 列只接受小写字符串并且没有特殊字符,例如 Ñóáöäë 等...
是否可以将此约束添加到列中?
CREATE TABLE lawyer (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
url_name VARCHAR NOT NULL,
gender VARCHAR(1) check (gender in ('m','f')) NOT NULL
);
我要添加约束的列是url_name
将所需的字符放入此 translate()
调用的第二个参数中:
CREATE TABLE lawyer (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
url_name VARCHAR check(translate(url_name, 'abcdefghijklmnopqrstuvwxyz', '') = '') NOT NULL,
gender VARCHAR(1) check (gender in ('m','f')) NOT NULL
);
insert into lawyer
values (default, 'Adam Smith', 'domain', 'f');
INSERT 0 1
insert into lawyer
values (default, 'Adam Smith', 'dömain', 'f');
ERROR: new row for relation "lawyer" violates check constraint "lawyer_url_name_check"
DETAIL: Failing row contains (3, Adam Smith, dömain, f).
或者,您可以创建一个触发器,它会即时修改值:
create or replace function lawyer_before_insert_or_update()
returns trigger language plpgsql as $$
begin
new.url_name := lower(new.url_name);
if translate(new.url_name, 'abcdefghijklmnopqrstuvwxyz', '') <> '' then
raise exception 'Incorrect url name.';
end if;
return new;
end $$;
create trigger lawyer_before_insert_or_update
before insert or update on lawyer
for each row execute procedure lawyer_before_insert_or_update();
insert into lawyer
values (default, 'Adam Smith', 'DOMAIN', 'f')
returning *;
id | name | url_name | gender
----+------------+----------+--------
4 | Adam Smith | domain | f
(1 row)
INSERT 0 1
insert into lawyer
values (default, 'Adam Smith', 'dömain', 'f');
ERROR: Incorrect url name.
对于转换(例如转换为小写),我同意触发器。但是,对于允许的字符,如果这是一个经常性的要求,我建议使用域。
类似于:
create domain lower_ascii AS text check VALUE ~ '^[a-z]*$';
域有几个优点,包括它们提供跨所有用途的单一管理点,如果需求发生变化,您可以全局修改检查约束。
我有一个 table,我希望该 1 列只接受小写字符串并且没有特殊字符,例如 Ñóáöäë 等...
是否可以将此约束添加到列中?
CREATE TABLE lawyer (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
url_name VARCHAR NOT NULL,
gender VARCHAR(1) check (gender in ('m','f')) NOT NULL
);
我要添加约束的列是url_name
将所需的字符放入此 translate()
调用的第二个参数中:
CREATE TABLE lawyer (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
url_name VARCHAR check(translate(url_name, 'abcdefghijklmnopqrstuvwxyz', '') = '') NOT NULL,
gender VARCHAR(1) check (gender in ('m','f')) NOT NULL
);
insert into lawyer
values (default, 'Adam Smith', 'domain', 'f');
INSERT 0 1
insert into lawyer
values (default, 'Adam Smith', 'dömain', 'f');
ERROR: new row for relation "lawyer" violates check constraint "lawyer_url_name_check"
DETAIL: Failing row contains (3, Adam Smith, dömain, f).
或者,您可以创建一个触发器,它会即时修改值:
create or replace function lawyer_before_insert_or_update()
returns trigger language plpgsql as $$
begin
new.url_name := lower(new.url_name);
if translate(new.url_name, 'abcdefghijklmnopqrstuvwxyz', '') <> '' then
raise exception 'Incorrect url name.';
end if;
return new;
end $$;
create trigger lawyer_before_insert_or_update
before insert or update on lawyer
for each row execute procedure lawyer_before_insert_or_update();
insert into lawyer
values (default, 'Adam Smith', 'DOMAIN', 'f')
returning *;
id | name | url_name | gender
----+------------+----------+--------
4 | Adam Smith | domain | f
(1 row)
INSERT 0 1
insert into lawyer
values (default, 'Adam Smith', 'dömain', 'f');
ERROR: Incorrect url name.
对于转换(例如转换为小写),我同意触发器。但是,对于允许的字符,如果这是一个经常性的要求,我建议使用域。
类似于:
create domain lower_ascii AS text check VALUE ~ '^[a-z]*$';
域有几个优点,包括它们提供跨所有用途的单一管理点,如果需求发生变化,您可以全局修改检查约束。