【问题标题】:Different result formats when insert postgreSQL function result between JDBC & console在 JDBC 和控制台之间插入 postgreSQL 函数结果时的不同结果格式
【发布时间】:2023-04-10 21:23:01
【问题描述】:

在 postgreSQL 中,我使用 pgcrypto 模块调用 pgp_sym_encrypt 函数(返回 bytea 类型)并将结果保存到文本列中:

例如,我有 test 表,其中包含 columnA(text) 列:

CREATE EXTENSION pgcrypto;
insert into test (columnA) values (pgp_sym_encrypt('test','test'));

如果我在控制台中运行,结果类似于(转义二进制):

\303\015\004\007\003\002\022\261B\015\376\235\023\010j\3225\001\244l\253\332\026\037\\Q\305\253\365H\264\222\021\233\345\326\036Ma\346vwq\373\201\303\300\000\303\354\327:\017\020\036Q\201\025\210\364%\215$\017\304Y^_&\267

如果我在JDBC中运行,结果类似于(十六进制格式):

public class Main {
    public static void main(String[] args) throws Exception {
        Class.forName("org.postgresql.Driver");
        Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/db", "postgres", "postgres");
        Statement stmt = connection.createStatement();
        String sql = "insert into test (columnA) values (pgp_sym_encrypt('test','test'))";
        stmt.executeUpdate(sql);
        connection.close();
    }
}

结果:

\xc30d040703026859a0885a496bc66bd240018d9cbede4805fc5b733afc706d061ae613600962222f008ab2fc4e99cc1c87841e3929833066ba42697784276c49efa67655a399fa9f77264769a42eb7c85e

如果我使用 pgp_sym_decrypt 解密,两者都可以流畅地解密,但我想知道为什么结果格式不同。如果我想要相同的格式,我该怎么办?

更新: 我知道它们是转义格式和十六进制格式,可以设置为@Vao Tsun 答案。但我想知道为什么,我认为他们必须使用相同的默认格式? JDBC 是否覆盖了格式?对于这种默认格式是否有任何 JDBC 配置,或者我必须在每个事务中调用 set 语句?

【问题讨论】:

    标签: java sql postgresql jdbc bytea


    【解决方案1】:

    这是您的客户端设置的问题:

    so=# set bytea_output to escape;
    SET    
    so=# select '\xc30d040703026859a0885a496bc66bd240018d9cbede4805fc5b733afc706d061ae613600962222f008ab2fc4e99cc1c87841e3929833066ba42697784276c49efa67655a399fa9f77264769a42eb7c85e'::bytea;
                                                                                                              bytea
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     \303\015\004\007\003\002hY\240\210ZIk\306k\322@\001\215\234\276\336H\005\374[s:\374pm\006\032\346\023`\011b"/\000\212\262\374N\231\314\034\207\204\0369)\2030f\272Biw\204'lI\357\246vU\243\231\372\237w&Gi\244.\267\310^
    (1 row)
    
    Time: 0.487 ms
    so=# set bytea_output to hex;
    SET
    Time: 2.134 ms
    so=# select '\xc30d040703026859a0885a496bc66bd240018d9cbede4805fc5b733afc706d061ae613600962222f008ab2fc4e99cc1c87841e3929833066ba42697784276c49efa67655a399fa9f77264769a42eb7c85e'::bytea;
                                                                                    bytea
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
     \xc30d040703026859a0885a496bc66bd240018d9cbede4805fc5b733afc706d061ae613600962222f008ab2fc4e99cc1c87841e3929833066ba42697784276c49efa67655a399fa9f77264769a42eb7c85e
    (1 row)
    

    https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-BYTEA-OUTPUT

    设置 bytea 类型值的输出格式。有效值为十六进制 (默认)和转义(传统的 PostgreSQL 格式)。看 第 8.4 节了解更多信息。 bytea 类型总是同时接受 输入格式,无论此设置如何。

    更新

    您可以为每个用户 alter user vao set bytea_output to hex 或每个数据库甚至每个集群设置此设置,而不仅仅是会话或事务。当然,如果您不想,您绝对不必在每个语句之前运行它。

    关于 jdbc 是否有特定设置 - 我不知道,afaik 你可以在连接字符串中传递客户端设置。

    最后,如果您按用户/数据库更改它,则需要重新连接才能生效。而SET LOCAL/SESSION 会马上克服这个参数...

    【讨论】:

    • 我在我的问题中写道,我知道它们是转义格式和十六进制格式。我想知道为什么,我认为他们必须使用相同的默认格式? JDBC 是否覆盖了格式?这种默认格式是否有任何 JDBC 配置,或者我必须在每个事务中调用 set 语句?我已经更新了我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    相关资源
    最近更新 更多