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

Column name in error text: value too long for type character

我们有一个包含 2 列的 table(它们具有相同的类型和大小)和 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 个条件:每个条件一个单独的错误或两个条件一个错误。 (恕我直言:单独的消息)