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

phe*_*hew 2 java postgresql jdbc plpgsql postgresql-9.4

我创建了一个带有CITEXT列的表格CITEXT(的大小写不敏感TEXT),这是我之前使用加载的扩展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;
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试使用以下方法在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;
}
Run Code Online (Sandbox Code Playgroud)

如果传递给sql函数的参数为INTEGER或类型,则调用函数的相同方法可以正常工作VARCHAR(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)
Run Code Online (Sandbox Code Playgroud)

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

phe*_*hew 5

我最终想通了。我要做的就是将参数转换为CITEXTusing ::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;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果可以的话,最好进行投射。如果您使用的ORM无法提供这种控制级别,则传递`stringtype = unspecified`要求PgJDBC将字符串视为无类型文字,并让数据库服务器推断其数据类型。 (2认同)