Java 使用二进制传输时,准备语句中的文本数组返回null

Java 使用二进制传输时,准备语句中的文本数组返回null,java,postgresql,jdbc-postgres,Java,Postgresql,Jdbc Postgres,在postgresql jdbc中使用二进制传输时,我在使用返回文本数组类型的预处理语句时遇到问题:它在应该有值的位置返回null。事实上,在我的测试中,它只发生在循环的第6次迭代中 如果我将binaryTransfer属性设置为false,它可以正常工作 我已经在PG 9.2和9.3数据库中使用postgresql-9.3-1102.jdbc4.jar对其进行了测试 对于较旧的jdbc版本(即postgresql-9.0-801.jdbc4.jar),它不实现二进制传输,因此工作正常 以下是我

在postgresql jdbc中使用二进制传输时,我在使用返回文本数组类型的预处理语句时遇到问题:它在应该有值的位置返回
null
。事实上,在我的测试中,它只发生在循环的第6次迭代中

如果我将
binaryTransfer
属性设置为
false
,它可以正常工作

我已经在PG 9.2和9.3数据库中使用postgresql-9.3-1102.jdbc4.jar对其进行了测试

对于较旧的jdbc版本(即postgresql-9.0-801.jdbc4.jar),它不实现二进制传输,因此工作正常

以下是我测试的代码:

import java.sql.Connection; 
import java.sql.Driver; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.util.Properties; 

public class TestMe { 
  public static void main(String[] args) throws SQLException { 
    String url = "jdbc:postgresql://localhost:5433/pi1"; 
    Connection conn = null; 
    // org.postgresql.Driver.setLogLevel(org.postgresql.Driver.DEBUG); 

    Properties connectionProps = new Properties(); 
    connectionProps.put("user", "tad"); 
    connectionProps.put("password", "password"); 
    connectionProps.put("binaryTransfer", "true"); 
    conn = DriverManager.getConnection(url, connectionProps); 

    Driver driver = DriverManager.getDriver(url); 
    conn = driver.connect(url, connectionProps); 
    System.out.println(org.postgresql.Driver.MAJORVERSION + "." 
        + org.postgresql.Driver.MINORVERSION); 

    PreparedStatement fs = conn 
        .prepareStatement("SELECT proargnames FROM pg_proc where proname ='pg_cursor'"); 

    for (int i = 0; i < 7; i++) { 
      ResultSet rs = fs.executeQuery(); 
      rs.next(); 

      System.out.println(rs.getArray(1)); 
      rs.close(); 
    } 
  } 
} 
以下是相同的输出设置调试日志级别:

13:18:59.474 (1) PostgreSQL 9.3 JDBC4 (build 1102) 
13:18:59.485 (1) Trying to establish a protocol version 3 connection to localhost:5433 
13:18:59.519 (1) Receive Buffer Size is 131003 
13:18:59.519 (1) Send Buffer Size is 331875 
13:18:59.519 (1)  FE=> StartupPacket(user=tad, database=pi1, client_encoding=UTF8, DateStyle=ISO, extra_float_digits=2, TimeZone=Europe/Madrid) 
13:18:59.522 (1)  <=BE AuthenticationOk 
13:18:59.533 (1)  <=BE ParameterStatus(application_name = ) 
13:18:59.533 (1)  <=BE ParameterStatus(client_encoding = UTF8) 
13:18:59.534 (1)  <=BE ParameterStatus(DateStyle = ISO, DMY) 
13:18:59.534 (1)  <=BE ParameterStatus(integer_datetimes = on) 
13:18:59.534 (1)  <=BE ParameterStatus(IntervalStyle = postgres) 
13:18:59.534 (1)  <=BE ParameterStatus(is_superuser = on) 
13:18:59.534 (1)  <=BE ParameterStatus(server_encoding = UTF8) 
13:18:59.534 (1)  <=BE ParameterStatus(server_version = 9.3.5) 
13:18:59.534 (1)  <=BE ParameterStatus(session_authorization = tad) 
13:18:59.534 (1)  <=BE ParameterStatus(standard_conforming_strings = on) 
13:18:59.534 (1)  <=BE ParameterStatus(TimeZone = Europe/Madrid) 
13:18:59.534 (1)  <=BE BackendKeyData(pid=25866,ckey=1929735537) 
13:18:59.534 (1)  <=BE ReadyForQuery(I) 
13:18:59.536 (1) simple execute, handler=org.postgresql.core.SetupQueryRunner$SimpleResultHandler@81f59f1, maxRows=0, fetchSize=0, flags=23 
13:18:59.537 (1)  FE=> Parse(stmt=null,query="SET extra_float_digits = 3",oids={}) 
13:18:59.538 (1)  FE=> Bind(stmt=null,portal=null) 
13:18:59.538 (1)  FE=> Execute(portal=null,limit=1) 
13:18:59.538 (1)  FE=> Sync 
13:18:59.539 (1)  <=BE ParseComplete [null] 
13:18:59.539 (1)  <=BE BindComplete [null] 
13:18:59.539 (1)  <=BE CommandStatus(SET) 
13:18:59.539 (1)  <=BE ReadyForQuery(I) 
13:18:59.540 (1)     compatible = 9.3 
13:18:59.540 (1)     loglevel = 2 
13:18:59.540 (1)     prepare threshold = 5 
13:18:59.544 (1)     types using binary send = INT8_ARRAY,TIMESTAMPTZ,FLOAT4_ARRAY,FLOAT8_ARRAY,UUID,TEXT_ARRAY,VARCHAR_ARRAY,BYTEA,TIME,FLOAT4,FLOAT8,INT2_ARRAY,TIMETZ,INT2,INT8,INT4,INT4_ARRAY,TIMESTAMP,POINT,BOX 
13:18:59.546 (1)     types using binary receive = INT8_ARRAY,TIMESTAMPTZ,FLOAT4_ARRAY,FLOAT8_ARRAY,UUID,TEXT_ARRAY,VARCHAR_ARRAY,BYTEA,TIME,DATE,FLOAT4,FLOAT8,INT2_ARRAY,TIMETZ,INT2,INT8,INT4,INT4_ARRAY,TIMESTAMP,POINT,BOX 
13:18:59.546 (1)     integer date/time = true 
getConnection returning org.postgresql.Driver 
DriverManager.getDriver("jdbc:postgresql://localhost:5433/pi1") 
getDriver returning org.postgresql.Driver 
13:18:59.556 (driver) Connecting with URL: jdbc:postgresql://localhost:5433/pi1 
13:18:59.556 (2) PostgreSQL 9.3 JDBC4 (build 1102) 
13:18:59.556 (2) Trying to establish a protocol version 3 connection to localhost:5433 
13:18:59.557 (2) Receive Buffer Size is 131003 
13:18:59.557 (2) Send Buffer Size is 331875 
13:18:59.557 (2)  FE=> StartupPacket(user=tad, database=pi1, client_encoding=UTF8, DateStyle=ISO, extra_float_digits=2, TimeZone=Europe/Madrid) 
13:18:59.560 (2)  <=BE AuthenticationOk 
13:18:59.560 (2)  <=BE ParameterStatus(application_name = ) 
13:18:59.560 (2)  <=BE ParameterStatus(client_encoding = UTF8) 
13:18:59.560 (2)  <=BE ParameterStatus(DateStyle = ISO, DMY) 
13:18:59.561 (2)  <=BE ParameterStatus(integer_datetimes = on) 
13:18:59.561 (2)  <=BE ParameterStatus(IntervalStyle = postgres) 
13:18:59.561 (2)  <=BE ParameterStatus(is_superuser = on) 
13:18:59.561 (2)  <=BE ParameterStatus(server_encoding = UTF8) 
13:18:59.561 (2)  <=BE ParameterStatus(server_version = 9.3.5) 
13:18:59.561 (2)  <=BE ParameterStatus(session_authorization = tad) 
13:18:59.561 (2)  <=BE ParameterStatus(standard_conforming_strings = on) 
13:18:59.561 (2)  <=BE ParameterStatus(TimeZone = Europe/Madrid) 
13:18:59.561 (2)  <=BE BackendKeyData(pid=25867,ckey=1041579294) 
13:18:59.561 (2)  <=BE ReadyForQuery(I) 
13:18:59.561 (2) simple execute, handler=org.postgresql.core.SetupQueryRunner$SimpleResultHandler@68a48d59, maxRows=0, fetchSize=0, flags=23 
13:18:59.561 (2)  FE=> Parse(stmt=null,query="SET extra_float_digits = 3",oids={}) 
13:18:59.562 (2)  FE=> Bind(stmt=null,portal=null) 
13:18:59.562 (2)  FE=> Execute(portal=null,limit=1) 
13:18:59.562 (2)  FE=> Sync 
13:18:59.562 (2)  <=BE ParseComplete [null] 
13:18:59.562 (2)  <=BE BindComplete [null] 
13:18:59.563 (2)  <=BE CommandStatus(SET) 
13:18:59.563 (2)  <=BE ReadyForQuery(I) 
13:18:59.563 (2)     compatible = 9.3 
13:18:59.563 (2)     loglevel = 2 
13:18:59.563 (2)     prepare threshold = 5 
13:18:59.564 (2)     types using binary send = INT8_ARRAY,TIMESTAMPTZ,FLOAT4_ARRAY,FLOAT8_ARRAY,UUID,TEXT_ARRAY,VARCHAR_ARRAY,BYTEA,TIME,FLOAT4,FLOAT8,INT2_ARRAY,TIMETZ,INT2,INT8,INT4,INT4_ARRAY,TIMESTAMP,POINT,BOX 
13:18:59.566 (2)     types using binary receive = INT8_ARRAY,TIMESTAMPTZ,FLOAT4_ARRAY,FLOAT8_ARRAY,UUID,TEXT_ARRAY,VARCHAR_ARRAY,BYTEA,TIME,DATE,FLOAT4,FLOAT8,INT2_ARRAY,TIMETZ,INT2,INT8,INT4,INT4_ARRAY,TIMESTAMP,POINT,BOX 
13:18:59.566 (2)     integer date/time = true 
9.3 
13:18:59.580 (2) simple execute, handler=org.postgresql.jdbc2.AbstractJdbc2Statement$StatementResultHandler@2d6a5acd, maxRows=0, fetchSize=0, flags=17 
13:18:59.580 (2)  FE=> Parse(stmt=null,query="SELECT proargnames FROM pg_proc where proname ='pg_cursor'",oids={}) 
13:18:59.580 (2)  FE=> Bind(stmt=null,portal=null) 
13:18:59.581 (2)  FE=> Describe(portal=null) 
13:18:59.581 (2)  FE=> Execute(portal=null,limit=0) 
13:18:59.581 (2)  FE=> Sync 
13:18:59.582 (2)  <=BE ParseComplete [null] 
13:18:59.583 (2)  <=BE BindComplete [null] 
13:18:59.584 (2)  <=BE RowDescription(1) 
13:18:59.584 (2)         Field(,TEXT_ARRAY,65535,T) 
13:18:59.584 (2)  <=BE DataRow(len=66) 
13:18:59.585 (2)  <=BE CommandStatus(SELECT 1) 
13:18:59.602 (2)  <=BE ReadyForQuery(I) 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
13:18:59.608 (2) simple execute, handler=org.postgresql.jdbc2.AbstractJdbc2Statement$StatementResultHandler@fc5d5e4, maxRows=0, fetchSize=0, flags=17 
13:18:59.608 (2)  FE=> Parse(stmt=null,query="SELECT proargnames FROM pg_proc where proname ='pg_cursor'",oids={}) 
13:18:59.608 (2)  FE=> Bind(stmt=null,portal=null) 
13:18:59.608 (2)  FE=> Describe(portal=null) 
13:18:59.608 (2)  FE=> Execute(portal=null,limit=0) 
13:18:59.608 (2)  FE=> Sync 
13:18:59.609 (2)  <=BE ParseComplete [null] 
13:18:59.609 (2)  <=BE BindComplete [null] 
13:18:59.609 (2)  <=BE RowDescription(1) 
13:18:59.610 (2)         Field(,TEXT_ARRAY,65535,T) 
13:18:59.610 (2)  <=BE DataRow(len=66) 
13:18:59.610 (2)  <=BE CommandStatus(SELECT 1) 
13:18:59.610 (2)  <=BE ReadyForQuery(I) 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
13:18:59.610 (2) simple execute, handler=org.postgresql.jdbc2.AbstractJdbc2Statement$StatementResultHandler@55d73d3, maxRows=0, fetchSize=0, flags=17 
13:18:59.611 (2)  FE=> Parse(stmt=null,query="SELECT proargnames FROM pg_proc where proname ='pg_cursor'",oids={}) 
13:18:59.611 (2)  FE=> Bind(stmt=null,portal=null) 
13:18:59.611 (2)  FE=> Describe(portal=null) 
13:18:59.611 (2)  FE=> Execute(portal=null,limit=0) 
13:18:59.611 (2)  FE=> Sync 
13:18:59.612 (2)  <=BE ParseComplete [null] 
13:18:59.612 (2)  <=BE BindComplete [null] 
13:18:59.612 (2)  <=BE RowDescription(1) 
13:18:59.613 (2)         Field(,TEXT_ARRAY,65535,T) 
13:18:59.613 (2)  <=BE DataRow(len=66) 
13:18:59.613 (2)  <=BE CommandStatus(SELECT 1) 
13:18:59.613 (2)  <=BE ReadyForQuery(I) 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
13:18:59.613 (2) simple execute, handler=org.postgresql.jdbc2.AbstractJdbc2Statement$StatementResultHandler@3a5f2465, maxRows=0, fetchSize=0, flags=17 
13:18:59.614 (2)  FE=> Parse(stmt=null,query="SELECT proargnames FROM pg_proc where proname ='pg_cursor'",oids={}) 
13:18:59.614 (2)  FE=> Bind(stmt=null,portal=null) 
13:18:59.614 (2)  FE=> Describe(portal=null) 
13:18:59.614 (2)  FE=> Execute(portal=null,limit=0) 
13:18:59.614 (2)  FE=> Sync 
13:18:59.615 (2)  <=BE ParseComplete [null] 
13:18:59.615 (2)  <=BE BindComplete [null] 
13:18:59.615 (2)  <=BE RowDescription(1) 
13:18:59.615 (2)         Field(,TEXT_ARRAY,65535,T) 
13:18:59.616 (2)  <=BE DataRow(len=66) 
13:18:59.616 (2)  <=BE CommandStatus(SELECT 1) 
13:18:59.616 (2)  <=BE ReadyForQuery(I) 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
13:18:59.616 (2) simple execute, handler=org.postgresql.jdbc2.AbstractJdbc2Statement$StatementResultHandler@3c4e80d3, maxRows=0, fetchSize=0, flags=16 
13:18:59.616 (2)  FE=> Parse(stmt=S_1,query="SELECT proargnames FROM pg_proc where proname ='pg_cursor'",oids={}) 
13:18:59.616 (2)  FE=> Bind(stmt=S_1,portal=null) 
13:18:59.616 (2)  FE=> Describe(portal=null) 
13:18:59.617 (2)  FE=> Execute(portal=null,limit=0) 
13:18:59.617 (2)  FE=> Sync 
13:18:59.617 (2)  <=BE ParseComplete [S_1] 
13:18:59.618 (2)  <=BE BindComplete [null] 
13:18:59.618 (2)  <=BE RowDescription(1) 
13:18:59.618 (2)         Field(,TEXT_ARRAY,65535,T) 
13:18:59.618 (2)  <=BE DataRow(len=66) 
13:18:59.618 (2)  <=BE CommandStatus(SELECT 1) 
13:18:59.618 (2)  <=BE ReadyForQuery(I) 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
13:18:59.618 (2) simple execute, handler=org.postgresql.jdbc2.AbstractJdbc2Statement$StatementResultHandler@7767d3c1, maxRows=0, fetchSize=0, flags=16 
13:18:59.618 (2)  FE=> Bind(stmt=S_1,portal=null) 
13:18:59.618 (2)  FE=> Execute(portal=null,limit=0) 
13:18:59.619 (2)  FE=> Sync 
13:18:59.619 (2)  <=BE BindComplete [null] 
13:18:59.619 (2)  <=BE DataRow(len=103) 
13:18:59.619 (2)  <=BE CommandStatus(SELECT 1) 
13:18:59.619 (2)  <=BE ReadyForQuery(I) 
null 
13:18:59.619 (2) simple execute, handler=org.postgresql.jdbc2.AbstractJdbc2Statement$StatementResultHandler@417f6125, maxRows=0, fetchSize=0, flags=16 
13:18:59.620 (2)  FE=> Bind(stmt=S_1,portal=null) 
13:18:59.620 (2)  FE=> Execute(portal=null,limit=0) 
13:18:59.620 (2)  FE=> Sync 
13:18:59.620 (2)  <=BE BindComplete [null] 
13:18:59.620 (2)  <=BE DataRow(len=103) 
13:18:59.620 (2)  <=BE CommandStatus(SELECT 1) 
13:18:59.620 (2)  <=BE ReadyForQuery(I) 
null 
13:18:59.474(1)PostgreSQL 9.3 JDBC4(构建1102)
13:18:59.485(1)正在尝试建立与本地主机的协议版本3连接:5433
13:18:59.519(1)接收缓冲区大小为131003
13:18:59.519(1)发送缓冲区大小为331875
13:18:59.519(1)FE=>StartupPacket(用户=tad,数据库=pi1,客户端编码=UTF8,日期样式=ISO,额外浮点数=2,时区=Europe/Madrid)

13:18:59.522(1)正如jdbc列表中回答的:问题是由于二进制类型未实现toString方法而导致的

检索日期的正确方法是:

java.sql.Array sqlArray = r.getArray(1);
String[] actualArray = (String[]) sqlArray.getArray();

查询是:
从pg\u proc中选择proargnames,其中proname='pg\u cursor'
。它返回一行始终相同,第一次正确返回参数5次。它在第6次迭代时开始失败。很抱歉,我没有意识到您总是选择同一行。这似乎与
prepareThreshold
有关,它在执行
PreparedStatement
一定次数后开始使用。当我增加阈值时,您的示例运行良好。您应该将此作为错误报告发布到JDBC邮件列表:Thank@a_horse_with_no_name我已经向
java.sql.Array sqlArray = r.getArray(1);
String[] actualArray = (String[]) sqlArray.getArray();