Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何获取Access.MDB文件中存储的表的记录数?_Delphi_Ms Access_Database Schema_Delphi Xe5 - Fatal编程技术网

Delphi 如何获取Access.MDB文件中存储的表的记录数?

Delphi 如何获取Access.MDB文件中存储的表的记录数?,delphi,ms-access,database-schema,delphi-xe5,Delphi,Ms Access,Database Schema,Delphi Xe5,我需要打开tToTable之前的RcordCount。所以我运行这个查询: ADOQuery1.SQL.Text := ‘SELECT Count(*) AS Record_Count FROM Table1’; ADOQuery1.Open; 但是,对于一个包含500多万条记录的表,在我的PC上运行9.7秒(平均10次)。这一次似乎比不上触摸如此大小的表,但我认为这种数据应该存储在.mdb文件的某个地方。有没有其他方法可以直接从文件中获取表的RecordCount? 我使用的是Delphi

我需要打开
tToTable
之前的
RcordCount
。所以我运行这个查询:

ADOQuery1.SQL.Text := ‘SELECT Count(*) AS Record_Count FROM Table1’;
ADOQuery1.Open;
但是,对于一个包含500多万条记录的表,在我的PC上运行9.7秒(平均10次)。这一次似乎比不上触摸如此大小的表,但我认为这种数据应该存储在.mdb文件的某个地方。有没有其他方法可以直接从文件中获取表的RecordCount? 我使用的是Delphi XE-5,文件是Microsoft Access 2003格式。

否,
选择计数(*)
是唯一正确的方法

但是:对于这个查询,几乎10秒的时间非常慢,尤其是在本地PC上

表是否有主键?如果是,它是什么数据类型

我用自动编号主键创建了一个简单的表,并插入了500万条记录。
SELECT COUNT(*)FROM tBig
执行时间不到1/10秒。

否,
SELECT COUNT(*)是唯一正确的方法

但是:对于这个查询,几乎10秒的时间非常慢,尤其是在本地PC上

表是否有主键?如果是,它是什么数据类型

我用自动编号主键创建了一个简单的表,并插入了500万条记录。

从tBig中选择COUNT(*)执行不到1/10秒。

我同意Andre451。我要说的另一件事是,您应该在Count语句中指定字段,而不是使用*


从tBig中选择计数(主键)就可以了。

我同意安德烈的观点。我要说的另一件事是,您应该在Count语句中指定字段,而不是使用*


从tBig中选择计数(主键)就可以了。

好吧,我再搜索了一点,找到了它。您可以直接从架构中读取表的记录数:

function ReadRecordCountFromSchema(const Connection: TADOConnection;
  const TableName: string): Integer;
var
  CardinalityField,
  NameField: TField;
  DataSet: TADODataSet;
begin
  DataSet := TADODataSet.Create(nil);
  Result := -1;
  try
    Connection.OpenSchema(siStatistics, EmptyParam, EmptyParam, DataSet);
    CardinalityField := DataSet.FieldByName('CARDINALITY'); { do not localize }
    NameField := DataSet.FieldByName('TABLE_NAME'); { do not localize }
    while not DataSet.EOF do
    begin
      if CompareText(NameField.AsString, TableName) = 0 then
      begin
        Result := CardinalityField.AsInteger;
        Break;
      end;
      DataSet.Next;
    end;
  finally
    DataSet.Free;
  end;
end;
实际上,
TADOConnection.GetTableNames
给了我这个想法

编辑

正如Andre451所提到的,最好将
TableName
传递给
OpenSchema
作为限制:

function ReadRecordCountFromSchema(const Connection: TADOConnection;
  const TableName: string): Integer;
var
  DataSet: TADODataSet;
begin
  DataSet := TADODataSet.Create(nil);
  Result := -1;
  try
    Connection.OpenSchema(siStatistics,
      VarArrayOf([Unassigned, Unassigned, TableName]),
      EmptyParam, DataSet);
    if DataSet.RecordCount > 0 then
      Result := DataSet.FieldByName('CARDINALITY').AsInteger;
  finally
    DataSet.Free;
  end;
end;

嗯,我又找了一点,找到了。您可以直接从架构中读取表的记录数:

function ReadRecordCountFromSchema(const Connection: TADOConnection;
  const TableName: string): Integer;
var
  CardinalityField,
  NameField: TField;
  DataSet: TADODataSet;
begin
  DataSet := TADODataSet.Create(nil);
  Result := -1;
  try
    Connection.OpenSchema(siStatistics, EmptyParam, EmptyParam, DataSet);
    CardinalityField := DataSet.FieldByName('CARDINALITY'); { do not localize }
    NameField := DataSet.FieldByName('TABLE_NAME'); { do not localize }
    while not DataSet.EOF do
    begin
      if CompareText(NameField.AsString, TableName) = 0 then
      begin
        Result := CardinalityField.AsInteger;
        Break;
      end;
      DataSet.Next;
    end;
  finally
    DataSet.Free;
  end;
end;
实际上,
TADOConnection.GetTableNames
给了我这个想法

编辑

正如Andre451所提到的,最好将
TableName
传递给
OpenSchema
作为限制:

function ReadRecordCountFromSchema(const Connection: TADOConnection;
  const TableName: string): Integer;
var
  DataSet: TADODataSet;
begin
  DataSet := TADODataSet.Create(nil);
  Result := -1;
  try
    Connection.OpenSchema(siStatistics,
      VarArrayOf([Unassigned, Unassigned, TableName]),
      EmptyParam, DataSet);
    if DataSet.RecordCount > 0 then
      Result := DataSet.FieldByName('CARDINALITY').AsInteger;
  finally
    DataSet.Free;
  end;
end;


可能有这个吗?但我想您必须通过OLE自动化才能访问这样的属性。如果您需要多个表的属性,则速度可能会更快….?可能有任何与此相关的信息吗?但我想您必须通过OLE自动化才能访问这样的属性。如果您需要多个表的属性,速度可能会更快…?不,它没有主键,它是8个双键和3个字符串,大小约为1.2GB。请阅读我的答案,看看是否正确。@saastn:这就是问题所在。如果没有主键,则必须读取整个表以统计记录。使用主键时,只读取此索引,速度快了几个数量级。不,它没有主键,它有8个双键和3个字符串,大小约为1.2GB。请阅读我的答案,看看是否正确。@saastn:这就是问题所在。如果没有主键,则必须读取整个表以统计记录。使用主键时,只读取这个索引,速度快了好几个数量级。它没有,但我用双字段替换了*,这使得查询速度更慢!最好使用
选择计数(*)
。如果有PK,两者都是等价的(都读取PK索引),但是如果PK是复合的,你会怎么做?计算没有PK(或唯一索引)的字段比计算(*)慢。同意。它需要在索引字段上,或者查询必须“扫描”表,这太慢了!嗯,它没有,但我用双字段替换了*,这使得查询速度更慢!最好使用
选择计数(*)
。如果有PK,两者都是等价的(都读取PK索引),但是如果PK是复合的,你会怎么做?计算没有PK(或唯一索引)的字段比计算(*)慢。同意。它需要在索引字段上,或者查询必须“扫描”表,这太慢了!有意思,我没听说过这个。但这只有在表上有索引时才有效,因此它也会读取索引,记录的数量不会神奇地存储在数据库中。使用索引,
SELECT COUNT(*)
也应该很快。它不需要是主键,我错了。顺便说一句。您应该能够在
OpenSchema
中指定表名,这样就不必对结果进行循环。请参阅@Andre451我更改了代码以防止循环。但是,您所说的关于索引的内容只有在您将
siIndexes
作为
Schema
参数传递时才是正确的,我检查了
siStatistics
中一个没有索引字段的表,它工作了。我不确定这个方法是否100%可靠。尝试在Access中打开表并添加记录。当表格在Access中打开时,试着看看你的Delphi应用程序报告有多少条记录…@kobik好吧,我在我的电脑上检查了一下,它成功了。我试着在另一个框中检查它,它说“提供商不支持它”。回到我的电脑上,我检查了一些其他场景,有时数据集是空的。。。所以,是的,既不可靠也不便携。有趣的是,我没听说过这个。但这只有在表上有索引时才有效,因此它也会读取索引,记录的数量不会神奇地存储在数据库中。使用索引,
SELECT COUNT(*)
也应该很快。它不需要是主键,我错了。顺便说一句。您应该能够在
OpenSchema
中指定表名,以便