布尔值插入PostgreSQL中的字符变化字段

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');

SQLFiddle

编辑:因此,默认情况下有一个从布尔到文本的ASSIGNMENT转换(&还有一个字符变化).这就是你的表的text_field接受布尔输入的原因.

点赞