【问题标题】:Reading Visual Foxpro Data From Java using ODBC使用 ODBC 从 Java 读取 Visual Foxpro 数据
【发布时间】:2013-05-05 01:30:21
【问题描述】:

我正在尝试从我的 Java 应用程序中查询一个 dbf 表。我参考了这个thread

我使用 ODBC 数据源管理器创建了一个系统数据源,我将数据源名称设置为 VFPDS,并将数据库类型设置为 .DBC,最后我将路径设置为 .dbc 文件。

以下是我的java代码:

import javax.swing.* ;
import java.awt.* ;
import java.awt.event.* ;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
// Import custom library containing myRadioListener
import java.sql.DriverManager;

public class testodbc {

public static void main( String args[] )
{
    try
    {
        // Load the database driver
        Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ) ;

        // Get a connection to the database
        Connection conn = DriverManager.getConnection( "jdbc:odbc:VFPDS" ) ;

        // Print all warnings
        for( SQLWarning warn = conn.getWarnings(); warn != null; warn = warn.getNextWarning() )
        {
            System.out.println( "SQL Warning:" ) ;
            System.out.println( "State  : " + warn.getSQLState()  ) ;
            System.out.println( "Message: " + warn.getMessage()   ) ;
            System.out.println( "Error  : " + warn.getErrorCode() ) ;
        }

        // Get a statement from the connection
        Statement stmt = conn.createStatement() ;

        // Execute the query
        ResultSet rs = stmt.executeQuery( "SELECT * FROM pmsquoteh" ) ;//code crashes here

        // Loop through the result set
        while( rs.next() )
            System.out.println( rs.getString(1) ) ;

        // Close the result set, statement and the connection
        rs.close() ;
        stmt.close() ;
        conn.close() ;
    }
    catch( SQLException se )
    {   se.printStackTrace();
        System.out.println( "SQL Exception:" ) ;

        // Loop through the SQL Exceptions
        while( se != null )
        {   se.printStackTrace();
            System.out.println( "State  : " + se.getSQLState()  ) ;
            System.out.println( "Message: " + se.getMessage()   ) ;
            System.out.println( "Error  : " + se.getErrorCode() ) ;

            se = se.getNextException() ;
        }
    }
    catch( Exception e )
    {
        System.out.println( e ) ;
    }
}
}

我遇到了这个异常:

java.sql.SQLException: [Microsoft][ODBC Visual FoxPro Driver]Not a table.
at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcStatement.execute(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(Unknown Source)
at UsingButtons.main(testodbc.java:38)

SQL Exception:
State  : S0002
Message: [Microsoft][ODBC Visual FoxPro Driver]Not a table.
Error  : 123

我确定数据库中存在表 pmsquoteh,并且我的机器是 64 位机器。 我究竟做错了什么 ?我将不胜感激具体的答案。

【问题讨论】:

  • VFP 错误“不是表格”可能意味着很多不同的事情。这可能意味着表已损坏。这也可能意味着该表已被加密。您有可用的 VFP 副本吗?如果是这样,你能打开那里的桌子吗?如果是这样,您就知道问题出在您的连接代码上。如果不是,那就是桌子。
  • @TamarE.Granor,我可以打开表格并查看其中的记录。所以它不是桌子

标签: java jdbc odbc visual-foxpro jdbc-odbc


【解决方案1】:

我能够在 Windows 7 上使用 jdbc-odbc 桥访问 FoxPro 表,但需要执行一些步骤。我已经安装了 VFP 驱动程序,但我不记得我是从哪里下载的,所以我没有那个链接。

我在这里复制了 jbdc:odbc 示例中的代码:http://www.java2s.com/Code/Java/Database-SQL-JDBC/SimpleexampleofJDBCODBCfunctionality.htm

DriverManager.getConnection 方法采用数据库 URL。要创建 URL,您需要使用 ODBC 管理器。对我来说不幸的是,我可以通过控制面板访问的 ODBC 管理器仅适用于 64 位数据源。我不知道 64 位 foxpro 驱动程序。

要生成 32 位 DSN,您需要运行 32 位 ODBC 管理器:odbcad32.exe。我的机器有几个副本。我从 C:\Windows\SysWOW64 运行了一个。转到系统 DSN 选项卡并选择 Microsoft Visual Foxpro 驱动程序。当您单击完成时,您将看到一个对话框,询问数据源名称、描述和 FoxPro 数据库或表的路径。您还必须指定是要连接到 .dbc 还是空闲表目录。您的错误消息让我怀疑您是否在 DSN 上选择了错误的选项。

我传递给 getConnection 方法的数据库 URL 是“jdbc:odbc:mydsnname”。

运行后,我收到一个错误:

[Microsoft][ODBC Driver Manager] 指定的 DSN 包含一个 驱动程序和应用程序之间的架构不匹配

这是因为我使用的是 64 位 JVM 和 32 位 DSN。我下载了一个 32 位 JVM,并且能够使用它来运行我的示例类。

我不知道你是否可以在 64 位 JVM 上设置一个开关来告诉它以 32 位运行。

【讨论】:

    【解决方案2】:

    我从这里使用了 JDBC 驱动程序:

    http://www.csv-jdbc.com/relational-junction/jdbc-database-drivers-products/new-relational-junction-dbf-jdbc-driver/

    对我来说很好用。到目前为止(大约一个小时)的测试中,它读取 MEMO 文件,并且似乎对包含 DBC 的表或空闲 DBF 没有任何问题。

    不确定这个驱动程序的成本是多少。由于 VFP 已经过时,客户可能最多只支付 100 美元。

    【讨论】:

      【解决方案3】:

      过去六个月我使用 javadbf-0.4.0.jar 没有问题。我将发布我的 Java 类和主程序。

      package foxtablereader.src;
      
      import java.sql.Connection;
      import java.sql.SQLException;
      import sun.jdbc.rowset.CachedRowSet;
      
      /**
       *
       * @author kalimk
       */
      public class DbfMain {
      
          static CachedRowSet crs;
      
          /**
           * @param args the command line arguments
           */
          public static void main(String[] args) throws SQLException {
      
             
              DbfConnection foxconn = new DbfConnection();
              Connection connection = null;
                      
              String inputTablePath = "c:\\vfp_table\\";
              connection = foxconn.connection(inputTablePath);
      
              String query = "SELECT * FROM TrigExport2.dbf ";
      
              crs = foxconn.select(query, connection);
              //crs = ft.query(query, inputTablePath);
              System.out.println(" Size " + crs.size());
              while (crs.next()) {
                  System.out.println("DESC " + crs.getString("Serialnum") + " " + crs.getString("cmailcode"));
              }
      
              inputTablePath = "C:\\sourcecode\\FoxTableReader\\";
              connection = foxconn.connection(inputTablePath);
              query = "SELECT * FROM TrigExports.dbf ";
              crs = foxconn.select(query, connection);
      
              System.out.println(" Size " + crs.size());
      
              int z = 1;
              while (crs.next()) {
                  System.out.println(z++ + "  " + crs.getString("Serialnum") + " " + crs.getString("cmailcode"));
              }
      
              inputTablePath = "C:\\sourcecode\\FoxTableReader\\";
              connection = foxconn.connection(inputTablePath);
              String queryinsert = "insert into Mcdesc (Desc,Mailcode,Del_type,Column1) values ('Kalim','KHAN', 'ERUM','KHAN')";
              foxconn.insertUpdate(queryinsert, connection);
      
              inputTablePath = "C:\\sourcecode\\FoxTableReader\\";
              connection = foxconn.connection(inputTablePath);
              String queryupdate = "update  Mcdesc set  Column1= 'Sadiqquie'  where Desc = 'Kalim'";
              foxconn.insertUpdate(queryupdate, connection);
          }
      
      }
      
      
      package foxtablereader.src;
      
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.sql.Statement;
      import java.util.Properties;
      import java.util.logging.Level;
      import java.util.logging.Logger;
      import sun.jdbc.rowset.CachedRowSet;
      
      /**
       *
       * @author kalimk
       */
      public class DbfConnection {
      
          public Connection connection(String inputTablePath) throws SQLException {
      
              Connection con = null;
              //String jdbURL = "jdbc:DBF:/C:\\vfp_table\\";
              String jdbURL = "jdbc:DBF:/" + inputTablePath;
              Properties props = new Properties();
              props.setProperty("delayedClose", "0");
      
              try {
      
                  Class.forName("com.caigen.sql.dbf.DBFDriver");
      
                  try {
      
                      con = DriverManager.getConnection(jdbURL, props);
      
                  } catch (SQLException ex) {
                      Logger.getLogger(DbfConnection.class.getName()).log(Level.SEVERE, null, ex);
                  }
      
              } catch (ClassNotFoundException ex) {
                  Logger.getLogger(DbfConnection.class.getName()).log(Level.SEVERE, null, ex);
              }
      
              return con;
          }
      
          public CachedRowSet select(String cQuery, Connection con) {
              CachedRowSet crs = null;
              try {
      
                  Statement stmt = con.createStatement();
                  ResultSet rs = stmt.executeQuery(cQuery);
                  crs = new CachedRowSet();
                  crs.populate(rs);
                  stmt.close();
              } catch (Exception e) {
                  System.out.println(e.getMessage());
                  e.printStackTrace();
              }
              return crs;
          }
      
          public boolean insertUpdate(String cQuery, Connection con) {
              boolean crs = false;
              try {
      
                  PreparedStatement pStmnt = con.prepareStatement(cQuery);
                  crs = pStmnt.execute();
                  pStmnt.close();
              } catch (Exception e) {
                  System.out.println(e.getMessage());
                  e.printStackTrace();
              }
              return crs;
          }
      
          public int insertUpdateCount(String cQuery, Connection con) {
      
              int count = 0;
              try {
      
                  Statement stmt = con.createStatement();
                  count = stmt.executeUpdate(cQuery);
                  System.out.println("Number of rows updated in database =  " + count);
                  stmt.close();
              } catch (Exception e) {
                  System.out.println(e.getMessage());
                  e.printStackTrace();
              }
              return count;
          }
      
          public int insertUpdateCount2(String cQuery, Connection con) {
      
              int count = 0;
              boolean crs = false;
              try {
      
                  PreparedStatement pStmnt = con.prepareStatement(cQuery);
                  count = pStmnt.executeUpdate(cQuery);
                  pStmnt.close();
              } catch (Exception e) {
                  System.out.println(e.getMessage());
                  e.printStackTrace();
              }
              return count;
          }
      
          public static void DBDisconnect(Connection DBCon) {
              try {
      
                  if (DBCon != null) {
                      DBCon.close();
                  }
              } catch (SQLException e) {
                  System.out.println(e.toString());
              } finally {
                  try {
      
                      DBCon.close();
                      //System.err.println("Fimally is always executed");
                  } catch (SQLException ex) {
                      Logger.getLogger(DbfConnection.class.getName()).log(Level.SEVERE, null, ex);
                  }
              }
          }
      
      }
      

      【讨论】:

      • 没有关于您从何处获得此驱动程序的信息?
      猜你喜欢
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      • 1970-01-01
      相关资源
      最近更新 更多