【问题标题】:DELPHI exception calls EAccess ViolationDELPHI 异常调用 EAccess Violation
【发布时间】:2018-02-23 13:04:01
【问题描述】:

有一个类似的问题,但是用户使用的是更高级的东西,所以我很困惑。

这是异常爆发的过程。特别是在 ADOCon.connected 行。我正在为我的数据库使用 dbgo 的东西和 Microsoft 访问权限。

我得到的例外是:EAcessViolation。我想知道我犯了什么错误导致它以及如何解决它。我已经使用预先存在的数据库和新数据库运行了该过程。当有一个预先存在的数据库时,例外是第 19 行之一,没有它是第 14 行。正如用户所提到的,我已经阅读了文档,但是我仍然对如何解决错误感到困惑。错误肯定在这里,因为这是我调用的第一个访问权限。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,DB, ADODB,ComObj;

type
 TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
var
ADOCom:TADOcommand;
ADOCon:TADOConnection;
ADOQ:TADOQuery;
nameDB:string;
db:OLEVariant;

begin
namedb:='Brill.accdb';
if not fileexists(namedb) then
  begin
    db:=createOLEObject('ADOX.Catalog');
    db.create('Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+nameDB+';');
    db:=null;
  ADOCon.connectionstring:='Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+
    nameDB+';';
    ADOCon.connected:=True;
    ADOCon.loginprompt:=False;
  end
else
  ADOCon.connectionstring:='Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+
  nameDB+';';
end.

【问题讨论】:

  • eaccessviolation 是什么意思,是什么原因造成的并修复它,抱歉忘记添加了
  • 我可以安全地假设您阅读了documentation 吗?显然,这始终是第一个开始的地方。假设您确实阅读了文档,您不了解其中的哪一部分?一旦您了解了访问冲突是什么,您就可以进行一些调试。显然我们无法调试您的代码。如果您不提供minimal reproducible example,我们当然无法确定您代码中的问题。
  • 我已经尝试过使用和不使用现有数据库。当数据库存在时,它在 AdoCon.connected=true 行上引发,当它不存在时,它在连接字符串上引发。
  • 所以你当时没有阅读文档。为什么不呢?
  • 感谢您提供足够的代码来回答。我可能已经猜到了这个问题,ADOCon 似乎没有初始化。但这就是我们需要minimal reproducible example 的原因。那我们就不用猜了。

标签: delphi ms-access exception


【解决方案1】:

您的代码充满了错误。

当您在代码中声明特定类类型的变量时,您有责任创建该类的实例并在使用之前将其分配给该变量,并在使用完毕后进行清理。

var
  ADOCon: TAdoConnection;
  ADOCom:TADOcommand;
  ADOQ:TADOQuery;

begin
  ADOCon := TADOConnection.Create(nil);
  try
    // Set up connection properties here 
    ADOQ := TADOQuery.Create(nil);
    try
      // Set up ADOQ properties and use query here
    finally
      ADOQ.Free;
    end;
  finally
    ADOCon.Free;
  end;
end;

此外,您对db: OleVariant(以及与之相关的所有代码)的使用完全没有任何作用。您获得一个实例,为该实例分配属性,然后将其丢弃,这意味着您可以删除该变量以及与它完全相关的三行代码;它们的用途为零。

当然,比上述任何一个更好的解决方案是在表单中添加一个 TDataModule,在其上放置一个 TADOConnection 和 TADOQuery,在 Object Inspector 或数据模块的 OnCreate 中设置属性。然后,您可以将该数据模块移动到可用表单列表中,将其上移以在主表单之前创建,并且可以从应用程序中使用该数据模块的任何位置进行访问,当您退出应用程序时,该数据模块将正确释放所有内容。它还将所有数据库代码从您的用户界面中分离出来,大大地清理了您的代码。

【讨论】:

  • 没有。正如我在上面的评论中解释的那样,你没有按照肯所说的去做。
  • 请通过编辑现有问题停止提出新问题。 How to Ask, help center
  • 不。这是一个完全不同的问题,具有相同的错误消息。是链式调试。现在你可以用一个非常简单的minimal reproducible example 提出一个新问题,只包含ADOCon := TADOConnection.Create(nil) 行并询问为什么会引发 AV。
  • 不是minimal reproducible example。缺少所有变量声明。再次。请照我说的做。请提出新问题。集中精力使其适当地最小化。一行代码就足够了。在控制台应用程序中。使用此处的代码stackoverflow.com/questions/2918016/… 作为如何呈现minimal reproducible example 的指南。请记住,您是新手,我知道如何在这里提问和回答问题。你在浪费自己的时间,错过了学习的好机会。继续这样下去,你注定永远是个新手。
  • 通过研究 Ken 的答案和上面的 cmets,您最好将当前浪费的时间花在与 @DavidHeffernan 和 Ken White 争论上。
猜你喜欢
  • 2017-07-26
  • 2012-09-21
  • 1970-01-01
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 2017-09-18
相关资源
最近更新 更多