PostgreSQL 9.1很乐意在varchar字段中插入一个布尔值.我的期望是,这会失败,因为我正在插入错误类型的数据,我希望在我的应用程序逻辑中调出错误.除了为每个varchar字段创建触发器或约束之外,有没有办法使其成为默认行为?
CREATE TABLE
foo
(
text_field CHARACTER VARYING(32)
);
这两个插入’false’到text_field:
INSERT INTO foo (text_field) VALUES (FALSE);
INSERT INTO foo (text_field) VALUES (CAST('f' AS BOOLEAN));
最佳答案 发生这种情况,因为PostgreSQL将接受任何表达式(在INSERT语句中),其类型可以自动转换为该列的类型(更准确地说,这两种类型之间存在
ASSIGNMENT
or IMPLICIT
强制转换:这就是为什么这些强制转换存在于第一位的原因). F.ex:
-- lets see what casts exists to boolean & text
-- "castcontext" is 'a' for ASSIGNMENT, 'i' for IMPLICIT and 'e' for EXPLICIT casts
select castsource::regtype::text,
casttarget::regtype::text,
castcontext
from pg_cast
where casttarget in ('boolean'::regtype, 'text'::regtype);
create table foo (
varchar_field varchar,
text_field text,
bool_field boolean
);
-- these are equivalents, because of some casts
insert into foo values ('false', 'false', 'false');
insert into foo values (false, false, false);
-- this will throw an error
insert into foo values (0, 0, 0);
好吧,我有点作弊.有一个特例.当您编写字符串文字(如’false’)时,它具有未知类型.未知值总是传递给实际列类型的input function.真正的文本类型文字看起来有点不同:文本’false’.如果你再次查看PostgreSQL提供的默认转换,你可以看到没有从文本转换为布尔值.这就是为什么最后一个陈述会失败的原因:
insert into foo values (text 'false', text 'false', text 'false');
编辑:因此,默认情况下有一个从布尔到文本的ASSIGNMENT转换(&还有一个字符变化).这就是你的表的text_field接受布尔输入的原因.