提问人:peteisace 提问时间:4/25/2023 更新时间:4/25/2023 访问量:59
无法通过 Java 客户端将复合类型插入 postgresql 数据库:“value too long for type character(1)”
Unable to insert composite type via Java client to postgresql database: "value too long for type character(1)"
问:
现有的答案似乎都无助于解决特定问题,即 - 我有一个带有复合类型列的表:
CREATE TYPE my_type AS (
my_id INT4
, my_other_id INT4
, some_varchar VARCHAR(32)
, is_true BOOL
, some_char CHAR(1)
)
表中使用:
CREATE TABLE the_table
(
id UUID
, url VARCHAR(32)
, name VARCHAR(32)
, my_types _my_type NULL
)
通过 java:
final String SQL = """
INSERT INTO the_table(
id
, url
, name
, my_types
)
VALUES (
?
, ?
, ?
, ?
)
"""
// some stuff - like get connection
var statement = c.prepareStatement(SQL);
statement.setObject(1, model.getId());
statement.setObject(2, model.getUrl());
statement.setObject(3, model.getName());
statement.setObject(4, c.createArrayOf("my_type", model.getMyTypes());
// where the implementation of MyType::toString() is:
@Override
public String toString() {
return String.format("(%d, %d, '%s', %b, '%c'),
this.getId(),
this.getOtherId(),
this.getName(),
this.getIsTrue(),
this.getSomeChar());
问题:我无法避免收到错误:“类型character(1)的值太长” - 即使getSomeChar()绝对是单个字符。我可以让它运行而不会出错的唯一方法是将 toString() 更改为:
return String.format("(%d, %d, '%s', %b, \"\")
这当然不能做我想做的事(char 为 null),但它确实证明了至少可以以这种方式持久化这种复合类型。我不知道我做错了什么,也不知道为什么它鄙视我试图推动一个角色。
答:
0赞
Priyank
4/25/2023
#1
答案取决于您对字符使用的编码(以及哪些字符可以返回)。从这个文档中,一些编码,如 utf-8,期望分配 char(4) 来存储单个字符。更改为应涵盖所有可能的编码:getSomeChar
CHAR(4)
CREATE TYPE my_type AS (
my_id INT4
, my_other_id INT4
, some_varchar VARCHAR(32)
, is_true BOOL
, some_char CHAR(4)
)
评论
1赞
peteisace
4/25/2023
确实认为 - 我尝试了懒惰的方式,即将CLIENT_ENCODING设置为SQL_ASCII,但这引发了一堆错误。我不明白的是为什么 DBeaver 客户端没有同样的问题 - INSERT 没有问题......VALUES(ROW(1, 1, 'hi', 0, 'A')::my_type) 替换为 DBeaver,尽管编码设置为 UTF-8(客户端和数据库)。我会试试的。
0赞
peteisace
4/25/2023
getSomeChar() 将始终在 ASCII 范围内 - 小写或大写:[A-Z|a-z]
1赞
peteisace
4/26/2023
char(3) 它是 :/
评论