1

在 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(); 
    } 
  } 
} 

这是输出

9.3 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
{name,statement,is_holdable,is_binary,is_scrollable,creation_time} 
null 
null 

这是相同的输出设置 DEBUG 日志级别:

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 
4

1 回答 1

0

正如 jdbc 列表中的回复:问题是由于二进制类型没有实现 toString 方法引起的。

检索日期的正确方法是:

java.sql.Array sqlArray = r.getArray(1);
String[] actualArray = (String[]) sqlArray.getArray();
于 2015-02-03T14:23:39.470 回答