Postgres文本数据类型截断问题

时间:2014-08-27 14:06:36

标签: postgresql

我正在使用Postgres 9.3。当我将一个大字符串插入到数据类型为" text"的列中时它会被截断为256个字符。

我很困惑。 Postgres文档说"文本"数据类型是可变的,长度不限。

请帮忙!

1 个答案:

答案 0 :(得分:0)

您的应用程序框架正在截断值。 PostgreSQL永远不会截断textvarchar的值。它截断遗留character空白填充类型的值,但仅限于显式强制转换。

CREATE TABLE testtruncation(
    text_unlimited text,
    text_limit255 text check (length(text_limit255) <= 255),
    varchar_unlimited varchar,  
    varchar_255 varchar(255), 
    char_nosize character,
    char_255 character(255)
);

regress=> insert into testtruncation(text_unlimited) values ('abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789');
INSERT 0 1

regress=> insert into testtruncation(text_limit255) values ('abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789');
ERROR:  new row for relation "testtruncation" violates check constraint "testtruncation_text_limit255_check"
DETAIL:  Failing row contains (null, abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEF..., null, null, null, null).

regress=> insert into testtruncation(varchar_unlimited) values ('abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789');
INSERT 0 1

regress=> insert into testtruncation(varchar_255) values ('abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789');
ERROR:  value too long for type character varying(255)

regress=> insert into testtruncation(char_nosize) values ('abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789');
ERROR:  value too long for type character(1)

regress=> insert into testtruncation(char_255) values ('abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789');
ERROR:  value too long for type character(255)

值被截断的唯一时间是明确转换为character(n)

regress=> SELECT CAST('abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789abcdefghijklmnopABCDEFGHIJKLMNOP0123456789' AS character(20));
        bpchar        
----------------------
 abcdefghijklmnopABCD
(1 row)

但使用substring而不是使用{{1}}总是更好,而且在任何情况下,如果不知情的话,这种情况发生的可能性很小。