小编dum*_*uch的帖子

如何将800000记录插入MS Access表?

我需要在MS Access表中插入800000条记录.我正在使用Delphi 2007和TAdoXxxx组件.该表包含一些整数字段,一个浮点字段和一个只有一个字符的文本字段.其中一个整数字段(不是autoinc)上有一个主键,另一个整数和float字段上有两个索引.

使用AdoTable.AppendRecord(...)> 10分钟插入数据是不可接受的,因为每次用户开始在程序中使用新数据库时都会这样做.我无法预先填充表格,因为数据来自另一个数据库(无法访问ADO).

通过将记录写入制表符分隔的文本文件并使用tAdoCommand对象执行,我设法将时间缩短到大约1分钟

insert into table (...) select * from [filename.txt] in "c:\somedir" "Text;HDR=Yes"
Run Code Online (Sandbox Code Playgroud)

但我不喜欢这个的开销.

我想,必须有更好的方法.

编辑:

一些其他信息:

  • 选择MS Access是因为它不需要在目标机器上进行任何额外安装,并且整个数据库包含在一个可以轻松复制的文件中.
  • 这是一个单用户应用程序.
  • 数据只会插入一次,并且在数据库的生命周期内不会更改.但是,该表包含一个附加字段,该字段用作标志以指示用户已处理另一个数据库中的相应记录.
  • 一分钟可以接受的(最多3分钟也是如此)并且我的解决方案有效,但对我来说似乎太复杂了,所以我认为应该有一种更简单的方法来做到这一点.
  • 插入数据后,表的性能非常好.
  • 当我开始计划/实现使用Access数据库的程序的功能时,不需要该表.只有在客户要求另一个功能时才需要它.(情况并非如此吗?)

编辑:

从我到目前为止得到的所有答案来看,似乎我已经有了将这么多数据插入Access表的最快方法.感谢大家,感谢您的帮助.

delphi ms-access ado delphi-2007

4
推荐指数
3
解决办法
9287
查看次数

如何重定向我的程序加载的 dll 的注册表访问

我在程序中加载了一个 dll,它可以读取其设置并将其写入注册表(hkcu)。我的程序在加载 dll 之前更改了这些设置,因此它使用我的程序希望它使用的设置,效果很好。

不幸的是,我需要使用不同的 dll 设置来运行程序的多个实例。现在,我迄今为止使用的方法不再可靠地工作,因为程序的一个实例可能会在 dll 有机会读取它们之前覆盖另一个实例刚刚写入的设置。

我没有得到相关 dll 的来源,也无法要求编写它的程序员更改它。

我的一个想法是挂钩注册表访问函数并将它们重定向到特定于我的程序实例的注册表的不同分支(例如,使用进程 ID 作为路径的一部分)。我认为这应该可行,但也许你有一个不同的/更优雅的。

以防万一:我的程序使用 Delphi 2007,该 dll 可能是用 C 或 C++ 编写的。

delphi registry hook

4
推荐指数
1
解决办法
1301
查看次数

Access文本字段上的唯一索引是否始终不区分大小写?

我使用以下代码创建了MS Access表:

  tbl := Database.CreateTableDef('English', 0, '', '');
  try
    fld := tbl.CreateField('ID', dbLong, 0);
    fld.Attributes := dbAutoIncrField + dbFixedField;
    tbl.Fields.Append(fld);

    fld := tbl.CreateField('Content', dbText, 255);
    fld.Required := true;
    fld.AllowZeroLength := false;
    tbl.Fields.Append(fld);

    Database.TableDefs.Append(tbl);

    idx := tbl.CreateIndex('PrimaryKey');
    idx.Fields.Append(idx.CreateField('ID', EmptyParam, EmptyParam));
    idx.Primary := True;
    idx.Unique := true;
    tbl.Indexes.Append(idx);

    idx := tbl.CreateIndex('IX_Content');
    idx.Fields.Append(idx.CreateField('Content', EmptyParam, EmptyParam));
    idx.Primary := false;
    idx.Unique := true;
    tbl.Indexes.Append(idx);
  finally
    tbl := nil;
  end;
Run Code Online (Sandbox Code Playgroud)

这工作正常,直到我尝试将两个字符串'字段类型'和'字段类型'插入此表.我收到一个错误,告诉我唯一的索引限制我这样做.正如您所看到的,它们仅在第二个单词的情况下有所不同.由于我没有明确地使索引不敏感(我甚至不知道如何做),我不太明白为什么会发生这种情况.文本字段中的索引在MS Access中是否始终不区分大小写?如果没有,我做错了什么?

delphi indexing ms-access

4
推荐指数
1
解决办法
805
查看次数

如何撤消IntersectClipRect的效果?

给出以下代码段:

procedure TPicture.PaintLine(_Canvas: TCanvas; _Left, _Top, _Right, _Bottom: Integer);
begin
  IntersectClipRect(_Canvas.Handle, _Left, _Top, _Right, _Bottom);
  try
    _Canvas.MoveTo(_Left - 10, _Top - 10);
    _Canvas.LineTo(_Right + 10, _Bottom + 10);
    // (This is an example only, the actual drawing is much more complex.)
  finally
    SelectClipRgn(_Canvas.Handle, 0); // This does too much
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我想撤消通过调用IntersectClipRect实现的剪辑,以便先前激活的剪辑再次变为活动状态.在上面的代码中,这是由SelectClipRgn(...,0)完成的,它完全关闭了裁剪.这种方法很有效,但之后没有裁剪活动,因此在上面执行之后执行的某些绘图将绘制到不应绘制的区域.

那么,只撤消IntersectClipRect效果的正确方法是什么?

编辑:在我理解了Sertac的评论之后删除了不必要的CreateRectRgn和DeleteObject代码,以使其他人可以在以后偶然发现这个问题时更具可读性.

windows delphi gdi clipping

4
推荐指数
1
解决办法
715
查看次数

如何使用Delphi 10.2中的ToolsAPI获取当前项目的版本号

在Delphi 2007中,我可以使用以下ToolsAPI调用轻松获取当前项目的版本信息:

procedure Test;
var
  ProjectOptions: IOTAProjectOptions;
  Project: IOTAProject;
  Major: Variant;
  Minor: Variant;
  Release: Variant;
  Build: Variant;
begin
  // GxOtaGetCurrentProject is a function in GExpert's GX_OTAUtils unit that returns the current IOTAProject
  Project := GxOtaGetCurrentProject;
  if Assigned(Project) then begin
    ProjectOptions := Project.ProjectOptions;
    if Assigned(ProjectOptions) then begin
      Major := ProjectOptions.Values['MajorVersion'];
      Minor := ProjectOptions.Values['MinorVersion'];
      Release := ProjectOptions.Values['Release'];
      Build := ProjectOptions.Values['Build'];
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

在Delphi 10.2.3中,无论实际版本号如何,它都将始终返回版本1.0.0.0.这是"简单"的案例:VCL应用程序.

我还尝试了"Keys"值,它返回一个TStrings指针.在那里我也得到了FileVersion字符串,但它总是"1.0.0.0".

我想这与各种平台和配置的支持有关,但我找不到任何关于它现在应该如何工作的文档.我还搜索了ToolsAPI.pas中的"版本"和"发布",但没有出现任何可疑的内容.

有关如何在Delphi 10.2中获取版本信息的任何提示?

delphi toolsapi otapi delphi-10.2-tokyo

4
推荐指数
1
解决办法
897
查看次数

在Delphi中延迟执行

调用程序结束后是否可以延迟启动程序?

procedure StartLoop;
begin
  DoSomething;
end;

procedure FormCreate(...);
begin
  if ParamStr(1)='start' then StartLoop;
end;
Run Code Online (Sandbox Code Playgroud)

StartLoop将被称为 FORMCREATE,和FORMCREATE将等待,并阻止进一步的执行不仅FORMCREATE本身的,而且之后(FormShow等)执行进一步的程序,并形成将不会显示,直到StartLoop将结束.

我需要等到FormCreate结束,然后运行StartLoop(不使用线程).

delphi delayed-execution

4
推荐指数
2
解决办法
508
查看次数

我可以将缓冲区 + 大小转换为 TBytes 吗?

给定一个缓冲区及其大小(以字节为单位),有没有办法将其转换为 TBytes 而不复制它?

例子:

procedure HandleBuffer(_Buffer: PByte; _BufSize: integer);
var
  Arr: TBytes;
  i: Integer;
begin
  // some clever code here to get contents of the buffer into the Array
  for i := 0 to Length(Arr)-1 do begin
    HandleByte(Arr[i]);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我当然可以复制数据:

procedure HandleBuffer(_Buffer: PByte; _BufSize: integer);
var
  Arr: TBytes;
  i: Integer;
begin
  // this works but is very inefficient
  SetLength(Arr, _BufSize);
  Move(PByte(_Buffer)^, Arr[0], _BufSize);
  //
  for i := 0 to Length(Arr)-1 do begin
    HandleByte(Arr[i]);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

但是对于一个大缓冲区(大约一百兆字节),这意味着我的内存需求增加了一倍,并且还花费了大量时间来不必要地复制数据。

我知道我可以简单地使用 PByte 来处理缓冲区中的每个字节,我只对使用 …

delphi

4
推荐指数
1
解决办法
119
查看次数

有没有办法在Windows 2000上安装Delphi 2010

我刚刚从我的SA订阅中下载了Delphi 2010 iso,除了在我的笔记本电脑上安装其他Delphi之外,还想安装它.不幸的是,它拒绝安装,因为该机器运行的是Windows 2000.

有可能以某种方式安装它吗?或者是否存在技术原因导致它可能不起作用,即使它已安装?

编辑:

更多信息:

  • Delphi 2009在该计算机上安装得很好,因此已经安装了dotNET 2.0.
  • 出现Delphi 2010安装程序,询问我使用的语言,然后说"此产品至少需要Windows XP.安装程序无法继续."

我现在正在寻找的是:

  • 一种让安装程序跳过此检查并安装的方法 - 或 -
  • 这不起作用的原因(例如Delphi使用的是Windows 2000中不可用的某些Windows API)

delphi windows-server-2000 delphi-2010

3
推荐指数
1
解决办法
919
查看次数

有没有办法强制Delphi命令行编译器输出英文文本?

Delphi以各种语言本地化(我认为英语,日语,德语,法语).命令行编译器(dcc32)也已本地化,因此德语版本向控制台写入"Fehler"而不是"Error"和"Warnung"而不是"Warning".

我编写了一个解析此输出的程序,并且(作为其功能之一)计算错误和警告.这与本地化字符串失败.

我可以调整程序以检测本地化的文本,但感觉不对.我宁愿强迫编译器使用英语作为输出.是否有命令行开关或任何其他选项来做到这一点?

我想支持使用msbuild的所有Delphi版本,即> = 2007.

编辑:

至于读取错误代码而不是消息,请考虑以下错误:

C:\[...]\Borland.Delphi.Targets(113,3): error : blub.pas(56) Error: E2029 ',' expected but identifier 'bla' found
Run Code Online (Sandbox Code Playgroud)

错误代码是E2029,但程序很难检测到它.检测文本"错误:"更简单,更不容易出错.

delphi dcc32

3
推荐指数
1
解决办法
693
查看次数

如何将库路径添加到 delphi 项目?

我有几个预编译(第 3 方)库需要在我的项目中使用。

我可以得到它来建立,如果我把foo.a在我的项目文件夹的根,但是,我有一个32位版本和库的64位版本,我不希望有换出foo.afoo.32.afoo.64.a每我构建应用程序的每个版本的时间。

在这种特殊情况下,我将它们放入:

[myroot]\iOSDevice32\Debug\foo.a
[myroot]\iOSDevice32\Release\foo.a
Run Code Online (Sandbox Code Playgroud)

[myroot]\iOSDevice64\Debug\foo.a
[myroot]\iOSDevice64\Release\foo.a
Run Code Online (Sandbox Code Playgroud)

我可以把它放在库路径中(工具 -> 选项 -> Delphi 选项 -> 库 -> 库路径);但是,我希望它特定于项目并相对于项目文件夹的根目录(而不是硬编码到所有项目的一个位置)。

我如何告诉 Delphi/Embarcadero RAD Studio 在哪里可以找到这些库?

delphi delphi-xe8

3
推荐指数
1
解决办法
1万
查看次数