我想创建一个像:
的表create table project_types (
id char(20) not null unique default 'xxx'
};
从其他表中使用它:
create table other_table (
...
fk_ptype char(20),
fk_ptype_on_other_table" foreign key (fk_ptype) references project_type(id)
);
问题是,我希望插入project_types
的所有值都自动变为小写:我不想对每个可能的查询进行转换,我想要一张表,无论如何我扔了它,它返回小写标记。
我正在考虑在插入更新时触发,但我想知道是否有更好的方法来施加此类限制。此外,这个解决方案意味着我必须对删除进行转换。
对于那些可能暗示我使用枚举执行此操作的内容:类型是动态的,所以我更喜欢这种方法。
更新2017.04.17:这个问题的想法不是在堆栈中的任何地方放置控件/转换:如果数据库可以处理你扔的任何东西,那么你就没有 1。检查/转换前端, 2。检查/转换后端代码,最后 3。检查/在数据库中转换。你只需要避免做1和2,因为你知道数据库会处理你扔的任何东西,并且当你select
时它会有正确的数据。
我很想选择@herbert-pimentel回答,但似乎同样的方法不能用于delete
(我尝试使用相同的功能设置和开启删除触发器,但它没有#&# 39;工作)。
答案 0 :(得分:3)
在插入或更新之前触发器如何确保/转换数据小写;
CREATE OR REPLACE FUNCTION public.fun_trg_lowercase()
RETURNS trigger AS
$BODY$
begin
NEW.my_char_field = lowercase(NEW.my_char_field);
RETURN NEW;
end;
$BODY$
LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER biu_lowercase_field
BEFORE INSERT OR UPDATE
ON mytable
FOR EACH ROW
EXECUTE PROCEDURE fun_trg_lowercase();
答案 1 :(得分:2)
create table project_types (
id char(20) not null unique default 'xxx'
check (id = lower(id))
);
答案 2 :(得分:1)
您可以为此目的使用特殊类型的数据,称为CITEXT
(=不区分大小写的文本)。它是PostgreSQL中另外提供的模块标准。
引用PostgreSQL documentation on CITEXT:
F.8.1。理
在PostgreSQL中进行不区分大小写的匹配的标准方法是在比较值时使用lower函数,例如
SELECT * FROM tab WHERE lower(col) = LOWER(?);
这种方法运作得相当好,但有许多缺点:
它使您的SQL语句冗长,并且您始终必须记住在列和查询值上使用lower。
它不会使用索引,除非您使用lower。
创建功能索引如果将列声明为
UNIQUE
或PRIMARY KEY
,则隐式生成的索引区分大小写。因此,对于不区分大小写的搜索没有用处,并且它不会不区分大小写地强制执行唯一性。citext数据类型允许您消除SQL查询中较低的调用,并允许主键不区分大小写。 citext是语言环境感知的,就像文本一样,这意味着大写和小写字符的匹配取决于数据库LC_CTYPE设置的规则。同样,此行为与查询中较低的使用相同。但由于数据类型透明地完成了这项工作,因此您不必记住在查询中做任何特别的事情。
因此,在您的具体情况下,您只需要这样做:
一次:
CREATE EXTENSION citext ;
CREATE TABLE project_types
(
id citext PRIMARY KEY default 'xxx'
);
CREATE TABLE other_table
(
/* ... */
fk_ptype citext,
fk_ptype_on_other_table foreign key (fk_ptype) references project_type(id)
);
...然后,对您的查询执行 nothing 。没有任何额外的限制,也没有任何(显然是可怕的)触发器。