【问题标题】:Postgres Text data type truncation issuePostgres 文本数据类型截断问题
【发布时间】:2014-10-21 03:59:20
【问题描述】:

我正在使用 Postgres 9.3。当我将一个大字符串插入数据类型为“文本”的列中时,它会不断被截断为 256 个字符。

我很困惑。 Postgres 文档说“文本”数据类型是可变的并且长度不受限制。

请帮忙!

【问题讨论】:

  • 与其他一些 DBMS 不同,Postgres 默默地截断值。如果值太大而无法放入列中,您将收到错误消息。您的值会被运行 SQL 语句并将值发送到数据库的任何代码截断。
  • 感谢您提供您的版本。如果您包含正在使用的语言和客户端驱动程序等详细信息,如果您正在连接特定的应用程序框架或程序,这也很有帮助。

标签: postgresql


【解决方案1】:

您的应用程序框架正在截断这些值。 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 总是比那个更好,无论如何,在您不知情的情况下,这种情况不太可能发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 2020-04-14
    • 1970-01-01
    相关资源
    最近更新 更多