我正在用C#编写.NET应用程序。该应用程序使用Visual FoxPro OLEDB提供程序读取FoxPro .DBF。
允许您读取.DBF文件的功能无法检测到.CDX文件,并且查询速度很慢。如何使用.cdx文件读取.dbf文件?
public DataTable ReadDbf(string path, string str_sql)
{
string constr = "Provider=VFPOLEDB;Data Source=" + path;
OleDbConnection con = new OleDbConnection();
con.ConnectionString = constr;
con.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(str_sql, con);
DataTable dt = new DataTable();
adapter.Fill(dt);
con.Close();
return dt;
}
我的路径和str_sql示例。
path ="C:\Users\kahla.mir\Desktop\201901"
str_sql = Select * From 100307_fct where prodid = "000038" and srcid = "001190" and perid = "000001"
VFP OLEDB提供程序会自动打开,使用和维护结构¹CDX文件,就像VFP IDE和运行时引擎一样。
有几件事可能会导致CDX不能用于加速查询:
SET OPTIMIZE OFF
禁用在这三个中,后者是迄今为止最常见的。在网上的其他地方,例如在名为Understanding Rushmore的Fox维基文章中,都可以找到控制Rushmore优化资格的规则。本质是谓词中使用的表达式必须与可用的索引表达式匹配才能被优化。因此,除非您不知道索引中实际的索引表达式是什么,否则您将无法编写有效的查询。
在您的情况下,主索引很可能是包含多个字段的复合表达式,例如
prodid - '|' - srcid - '|' - perid
如果您很幸运,或
prodid + srcid + perid
如果不是。如果您反而发现类似alltrim(prodid) + alltrim(srcid) + alltrim(perid)
的东西,那么唯一有效的办法就是抓住shot弹枪,并在他造成更多伤害之前找到无能的犯罪者。
如果幸运的话,您可以像这样制定过滤条件以达到索引:
where prodid - '|' - srcid - '|' - perid == '000038|001190|000001'
密钥可以作为单个参数传递给OLEDB(因此可以在C#中进行串联并传递单个字符串),或者-如果涉及到一些不方便的框架-作为三个独立的参数,然后可以在查询本身中对其进行串联:
where prodid - '|' - srcid - '|' - perid == ? - '|' - ? - '|' - ?
在不幸的情况下,您必须确定字段宽度并相应地填充:
where prodid + srcid + perid == '000038 001190 000001'
或使用类似表达式:
where prodid + srcid + perid == padr('000038', 8) + padr('001190', 12) + '000001'
¹]'结构'CDX文件意味着CDX被视为DBF的结构部分,在这种情况下,其名称(除了扩展名之外)将与DBF的名称相同,并且CDF的位0将设置DBF标头的偏移量0x1C(十进制28)的标志字节,指示结构CDX的存在。如果CDX仅具有相同的名称,但未设置DBF头中的CDX位,则该CDX将不被视为结构性CDX(即not将被打开并自动维护)。