【问题标题】:How to query a Foxpro .DBF file with .NDX index file using the OLEDB driver in C#如何使用 C# 中的 OLEDB 驱动程序使用 .NDX 索引文件查询 Foxpro .DBF 文件
【发布时间】:2015-11-16 23:17:19
【问题描述】:

我有一个 Foxpro .DBF 文件。我正在使用 OLEDB 驱动程序来读取 .DBF 文件。我可以查询 DBF 并利用它的 .CDX 索引文件(因为它是自动打开的)。我的问题是我想用 .NDX 索引文件(打开 .DBF 时不会自动打开)查询它。如何使用 OLEDB 驱动程序在 C# 中打开 .NDX 文件,因为 DBF 非常大,无法在没有索引的情况下搜索记录?谢谢大家!这是我用来读取 DBF 的代码。

OleDbConnection oleDbConnection = null;
        try
        {
            DataTable resultTable = new DataTable();
            using (oleDbConnection = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=P:\\Test\\DSPC-1.DBF;Exclusive=No"))
            {
                oleDbConnection.Open();
                if (oleDbConnection.State == ConnectionState.Open)
                {
                    OleDbDataAdapter dataApdapter = new OleDbDataAdapter();
                    OleDbCommand command = oleDbConnection.CreateCommand();

                    string selectCmd = @"select * from P:\Test\DSPC-1  where dp_file = '860003'";
                    command.CommandType = CommandType.Text;
                    command.CommandText = selectCmd;

                    dataApdapter.SelectCommand = command;
                    dataApdapter.Fill(resultTable);
                    foreach(DataRow row in resultTable.Rows)
                    {
                        //Write the data of each record 
                    }
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            try
            {
                oleDbConnection.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to close Oledb connection: " + e.Message);
            }
        }

【问题讨论】:

标签: c# oledb visual-foxpro foxpro oledbconnection


【解决方案1】:

ndx 文件在默认情况下不会被打开,这些已经成为过去,为什么不简单地将索引添加到 CDX 中。如果这不是一个选项,那么您可以执行 DRapp 的 ExecScript 建议。他非常接近。您可以这样做:

string myCommand = @"Use ('P:\Test\DSPC-1') alias myData
Set Index To ('P:\Test\DSPC-1_Custom.NDX')
select * from myData ;
  where dp_file = '860003' ;
  into cursor crsResult ;
  nofilter
SetResultset('crsResult')";

DataTable resultTable = new DataTable();
using (oleDbConnection = new OleDbConnection(@"Provider=VFPOLEDB;Data Source=P:\Test"))
{
  oleDbConnection.Open();
  OleDbCommand command = new OleDbCommand("ExecScript", oleDbConnection);
  command.CommandType = CommandType.StoredProcedure;
  command.Parameters.AddWithValue("code", myCommand);

  resultTable.Load(cmd.ExecuteReader());
  oleDbConnection.Close();
}

【讨论】:

  • 感谢@Cetin Basoz,您的代码运行完美,没有错误,但性能仍然相同。在 Foxpro 上运行相同的查询时,查找记录“860003”大约需要 60 秒,而
  • 我还尝试在我的计算机上使用测试数据,并通过索引获得“更快”的结果。也许您的 P: 驱动器是远程的,并且正在浪费时间引入索引文件?您是否尝试将索引添加到结构 CDX?你有几行???即使没有任何索引,60s 听起来也很慢。顺便说一句,VFP 中存在一个已知的优化问题,即表的代码页与 OS 代码页不同。
  • 我的 DBF 有超过 500 万条记录。它创建于 15 多年前,因此 .NDX 索引文件在系统中的不同位置使用。可以将其转换为结构 CDX,但我的老板不喜欢这样:(。你说得对,我的 P 盘是远程的。如果我把它带到本地,查询需要 30 秒,但我仍然无法使用那个性能用于生产。无论如何,我标记了您的答案以供将来参考。谢谢@Cetin Basoz!
【解决方案2】:

您的连接字符串应该只引用 .dbf 文件所在的 PATH。

那么,您的查询只是通过表名。

new OleDbConnection("Provider=VFPOLEDB.1;Data Source=P:\\Test\\;Exclusive=No"))

selectCmd = @"select * from DSPC-1  where dp_file = '860003'";

至于使用 .NDX,它是如何/在哪里创建的……这是您使用 Visual Foxpro 驱动程序的旧 dBASE 文件吗?

如果它是一个单独的描述,您可能需要通过 ExecScript() 首先使用索引显式打开文件,然后运行您的查询。这只是您的固定值的样本。您可能必须对其进行参数化,否则您将对 sql-injection 持开放态度。

cmd.CommandText = string.Format(
@"EXECSCRIPT('
USE DSPC-1 INDEX YourDSPC-1.NDX
SELECT * from DSPC-1 where dp_file = '860003'" );

此外,您可能会遇到表名被连字符连接的问题,您可能需要将其括在 [方括号] 中,但如果这是一个问题,则不是肯定的。

【讨论】:

  • 您好,.NDX 是在 Foxpro 中创建的索引文件,它与主 DBF 文件存储在同一目录中。我怎样才能让 SQL 使用这个索引文件? @DRapp
  • @h2nghia,请参阅提供脚本选项的修订答案。
  • @DRapp,你非常接近。 VFP 字符串文字的长度限制为 255,并且在文字中有换行符,execsript 不会成功执行。其次,您需要将结果放在游标中并使用 SetResultSet() 将结果发送回 VFPOLEDB 客户端。
  • @CetinBasoz 自非 .cdx 文件可用以来从未真正使用过,对此并不积极。另外,感谢 SetResultSet()。我赞成您的解决方案。
  • 我猜,很少有开发人员使用非 CDX 版本 :) 我上次使用非 CDX 索引时可能是 foxbase 2.1(那是因为当时不存在 CDX)。跨度>
猜你喜欢
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
相关资源
最近更新 更多