postgres如何从多个数据库中获取数据

ycl3bljg  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(463)

我在不同的端口上有两个postgresql数据库:端口5432上的db1和端口5431上的db2
我有这样的代码从db1获取数据:

try {
    Class.forName("org.postgresql.Driver");
    String conString = "jdbc:postgresql://127.0.0.1:5432/DB1?user=MyUser&pass=MyPass" ; 
    c = DriverManager.getConnection(conString);
      st = c.createStatement();
      ResultSet rs = st.executeQuery(query);
      while (rs.next()){
          vaArrL.add(rs.getDouble("va"));
          vbArrL.add(rs.getDouble("vb"));
          vcArrL.add(rs.getDouble("vc"));
      }

当我只向db1发送一个查询时,效果很好。但现在,我要同时查询两个数据库,比如:

select va, vb from  DB1.public.t1 where datatime >=  1417384860 and datatime <=  1417381199 
union  
select va, vb from dblink('hostaddr=127.0.0.1 port=5431 dbname=DB2 user=MyUser password =MyPass '::text,
           'select va, vb 
            from Db2.public.t2 order by datatime ')
            datos(va integer,vb integer);

当我从pgadmin运行查询时,我得到一个结果
但当我向gunction发送查询时,我得到:connection not available
现在。如何将查询发送到函数并获取值?

eoigrqb6

eoigrqb61#

我正在寻找1个解决方案我正在使用2个连接并将查询从客户端发送到xmlrpc服务器,这里:

String conString = "jdbc:postgresql://" + host + ":" + port + "/" + DBName + 
            "?user=" + user + "&pass=" + pass;

String conString1 = "jdbc:postgresql://" + host + ":" + port2 + "/" + DBName2 + 
            "?user=" + user + "&pass=" + pass;

       c = DriverManager.getConnection(conString);
      c2 = DriverManager.getConnection(conString1);

      st = c.createStatement();
      st2 = c2.createStatement();       
          List<ResultSet> resultSets = new ArrayList<>();
          resultSets.add(st.executeQuery(query));
          resultSets.add(st2.executeQuery(query2));
           ResultSets rs = new ResultSets(resultSets);
      while (rs.next()){
          unbArrL.add(rs.getUnbalance("unbalance"));
      }

从db获取值的resultsets类是:

class ResultSets {

 private java.util.List<java.sql.ResultSet> resultSets;

    private java.sql.ResultSet current;

    public ResultSets(java.util.List<java.sql.ResultSet> resultSets) {
        this.resultSets = new java.util.ArrayList<>(resultSets);
        current = resultSets.remove(0);
    }

    public boolean next() throws SQLException {
        if (current.next()) {
            return true;
        }else if (!resultSets.isEmpty()) {
            current = resultSets.remove(0);
            return next();
        }
        return false;
    }
    public Double getUnbalance(String unbalance) throws SQLException{
        return current.getDouble("unbalance");
    }

}

zlhcx6iw

zlhcx6iw2#

你能尝试使用jdbc吗 setCatalog 方法? setCatalog's javadoc声明:
调用setcatalog对以前创建或准备的语句对象没有影响。在调用连接方法preparestatement或preparecall时,dbms prepare操作是否立即发生是由实现定义的。为了获得最大的可移植性,应该在创建或准备语句之前调用setcatalog。

try {
    Class.forName("org.postgresql.Driver");
    // Connect to DB1 (specified in connection string/URL).
    String conString = "jdbc:postgresql://127.0.0.1:5432/DB1?user=MyUser&pass=MyPass" ; 
    c = DriverManager.getConnection(conString);
    st = c.createStatement();

    // Execute query on DB1.
    ResultSet rs = st.executeQuery(query);
    while (rs.next()){
        vaArrL.add(rs.getDouble("va"));
        vbArrL.add(rs.getDouble("vb"));
        vcArrL.add(rs.getDouble("vc"));
    }

    // Switch to DB2 and execute query.
    c.setCatalog("DB2");    
    Statement st2 = c.createStatement();
    ResultSet rs2 = st2.executeQuery(...);
}

如果jdbc驱动程序不支持 setCatalog ,则可以执行sql查询 USE DB2 但这可能会影响已经打开的语句(对此我不确定)。
编辑:op希望两个数据库的所有结果都在同一个结果集中。
假设db1和db2在同一台服务器上,我建议在数据库db1中创建一个视图,该视图可以访问数据库db2中的表并返回组合结果。那你就可以 SELECT * 通过jdbc从视图中获取结果。
您可以对视图使用这样的查询(假设视图是在db1中创建的):

SELECT all.va, all.vb FROM
    (SELECT va, vb, datatime FROM t2
     UNION
    SELECT va, vb, datatime FROM DB2.public.t2) all
ORDER BY all.datatime

注意:要访问另一个数据库中的表,需要指定[db name].[schema].[tablename]。
如果查询需要动态参数,则可以创建存储过程而不是视图。

相关问题