问题描述
我们有一个包含 2 列(都具有相同的类型和大小)和 2 个约束的表:
create table colors
(
color varchar(6)
constraint color_check check
((color)::text ~ '^[0-9a-fA-F]{6}$'::text),color_secodandry varchar(6)
constraint color_secondary_check check
((color_secodandry)::text ~ '^[0-9a-fA-F]{6}$'::text),);
对于长值插入的情况:
insert into colors (color,color_secondary) values ('ccaabb','TOO_LONG_TEXT');
insert into colors (color,color_secondary) values ('TOO_LONG_TEXT','ccaabb');
ERROR: value too long for type character varying(6) (sqlSTATE 22001)
Postgresql 在插入之前验证该列的长度,因此我们的检查永远不会运行。有没有办法理解,哪一列有无效数据?
解决方法
您遇到的问题是预期值的评估顺序。您告诉 Postgres 不允许长度超过 6 (character varying(6)
),您还指定了这些值必须满足的其他特定条件。发生的事情是 Postgres 验证长度标准并在值失败时抛出异常,在这种情况下,由于 Postgres 在 exit on first failure
上工作,因此不会执行检查约束。只有在长度通过后才处理检查约束。 Example:
create table test1( id integer generated always as identity,color6 character varying (6)
constraint color6_check check (color6 ~ '^[0-9a-fA-F]{6}$'),color60 character varying (60)
constraint color60_check check (color60 ~ '^[0-9a-fA-F]{6}$')
) ;
insert into test1( color6 ) values ('aabbccdd') ;
/* Result
SQL Error [22001]: ERROR: value too long for type character varying(6)
ERROR: value too long for type character varying(6)
*/
insert into test1( color60 ) values ('aabbccdd') ;
/* Result
SQL Error [23514]: ERROR: new row for relation "test1" violates check constraint "color60_check"
Detail: Failing row contains (3,null,aabbccdd).
ERROR: new row for relation "test1" violates check constraint "color60_check"
*/
注意它们之间的唯一区别是插入的列的长度规范。然而他们失败了,但原因不同。由于长度规范和检查约束都强制执行长度,因此您现在需要决定如何处理 2 个条件:每个条件的单独错误或两者的单个错误。 (恕我直言:单独的消息)