PostgreSQL/JDBC - 如何准备调用带有参数 CITEXT (TEXT) 的函数?

Posted

技术标签:

【中文标题】PostgreSQL/JDBC - 如何准备调用带有参数 CITEXT (TEXT) 的函数?【英文标题】:PostgreSQL/JDBC - How do I prepare-call a function with parameter CITEXT (TEXT)? 【发布时间】:2015-09-29 00:08:58 【问题描述】:

我创建了一个带有CITEXT 列的表,CITEXTTEXT 的不区分大小写版本)是我之前使用CREATE EXTENSION citext; 加载的扩展

CREATE TABLE artists (
    artist_id   SERIAL   PRIMARY KEY,
    artist      CITEXT   UNIQUE NOT NULL
);

CREATE OR REPLACE FUNCTION add_artist(_artist CITEXT) RETURNS INTEGER AS $$
    DECLARE
        _artist_id INT;
    BEGIN
        SELECT artist_id INTO _artist_id FROM artists WHERE artist = _artist;

        IF (_artist_id IS NULL) THEN
            INSERT INTO artists (artist) VALUES (
                _artist
            ) RETURNING artist_id INTO _artist_id;
        END IF;

        RETURN _artist_id;
    END;
$$ LANGUAGE plpgsql;

现在我正在尝试使用 java 调用该函数

public int addArtist(String name) throws SQLException 
    int artist_id;

    try (CallableStatement callableStatement = 
            connection.prepareCall(" ? = CALL add_artist(?) ")) 
        callableStatement.registerOutParameter(1, Types.INTEGER);
        callableStatement.setString(2, name);
        callableStatement.execute();
        artist_id = callableStatement.getInt(1);
    

    return (artist_id != 0) ? artist_id : -1;

如果传递给 sql 函数的参数类型为 INTEGERVARCHAR(n),则调用函数的相同方法可以正常工作。

我假设 callableStatement.setString(2, name); 正在抛出 SQLException 因为 setString() 将用于 VARCHAR(n) 字段?

org.postgresql.util.PSQLException: ERROR: function add_artist(character varying) does not exist
  Hint: No function matches the given name and argument types. You might need to add explicit type casts.
  Position: 15
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2182)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1911)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:615)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:465)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:458)
at postgresql.PostgreSQL.addArtist(PostgreSQL.java:61)
at postgresql.PostgreSQLConnector.main(PostgreSQLConnector.java:26)

CallableStatement 没有像 setText(int i, String text) 这样的方法 - 我必须改用什么方法?

【问题讨论】:

【参考方案1】:

我终于明白了。我所要做的就是使用::citext 将参数转换为CITEXT

public int addArtist(String name) throws SQLException 
    int artist_id;

    try (CallableStatement callableStatement = 
            connection.prepareCall(" ? = CALL add_artist(?::citext) ")) 
        callableStatement.registerOutParameter(1, Types.INTEGER);
        callableStatement.setString(2, name);
        callableStatement.execute();
        artist_id = callableStatement.getInt(1);
    

    return (artist_id != 0) ? artist_id : -1;

【讨论】:

另一个选项是将stringtype=unspecified设置为连接参数。 有趣,这比强制转换更常见吗?设置stringtype=unspecified 和在prepareCall() 字符串中转换参数有区别吗? 如果可以的话,最好选择铸造。如果您使用的 ORM 无法提供那种级别的控制,则传递 stringtype=unspecified 会要求 PgJDBC 将字符串视为无类型文字,并让数据库服务器推断它们的数据类型。 谢谢你的信息,那我就去选角了。尽管如此,出于懒惰,还是很想使用stringtype 参数。

以上是关于PostgreSQL/JDBC - 如何准备调用带有参数 CITEXT (TEXT) 的函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 org.postgresql.jdbc.PgConnection.createClob() 尚未实现

Postgres 错误方法 org.postgresql.jdbc.PgConnection.createClob() 未实现

如何在flyway创建的postgresql jdbc连接上设置时区?

如何解析 Postgresql JDBC url 以获取主机名、端口和 db_name

在 Linux 命令行上检查 postgresql jdbc 驱动程序版本的命令是啥?

Android上的Postgresql JDBC连接错误