错误文本中的列名:类型字符的值太长

问题描述

我们有一个包含 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 个条件:每个条件的单独错误或两者的单个错误。 (恕我直言:单独的消息)