【问题标题】:Access Violation in query in Delphi XE2Delphi XE2中的查询访问冲突
【发布时间】:2013-03-21 04:50:38
【问题描述】:

我在函数DoABC 中有一个查询说qryDoABC。当我第一次调用此函数时,一切正常,但第二次调用它时,与 qryDoABC 一致,它会引发访问冲突异常。

procedure TMyForm.DoABC;
begin
  with qryDoABC do
  --
  -- 
end;

我搜索了一下,发现我应该检查是否分配了查询。所以现在我也在检查是否像这样分配查询:

procedure TMyForm.DoABC;
begin
  if assigned qryDoABC then
  with qryDoABC do
  --
  -- 
end;

现在也不例外,因为没有分配第二次查询。但我也必须第二次解雇这个 qry。我应该如何第二次分配这个查询。

完整代码:

function TMyForm.DoABC:boolean;
begin
  try
    if assigned(qryDoABC)then 
    with qryDoABCdo
    begin
      Close  ;
      SQL.Clear;
      SQL.Text :=
        'Some query';

      Parameters.ParamByName('ABC').Value := ABC;
      Parameters.ParamByName('XYZ').Value := XYZ;
      Open;
      if (Recordcount = 0) then
        result := false
      else
      begin
        result := true;
      end;
      Close;
    end;
  except
    on E : Exception do
    begin
      result := false;
      exit;
    end;
  end;
end;

【问题讨论】:

  • 显示您的方法的完整代码。同时,检查你是否没有Free 里面的那个查询对象。
  • @TLama - 我已添加完整代码
  • 这里缺少重要的部分,因为如果您说第二次未分配查询对象,那么您必须在代码中的某处使用Free 和/或nil
  • @TLama - 我有一个 Form1 和 Form2。当我单击 Form1 的 OK 按钮时,此查询会触发,如果一切正常,我会跳转到 Form2。现在,如果我在那里按 ESC,我再次来到 Form1。现在,如果我按下那里的按钮,我会收到错误消息。我没有在任何地方使用 Free 或 Nil 关键字
  • 在 Form1 上显示 OnClick OK 按钮的代码。您是否在模态模式下显示 Form2?即Form2.ShowModal?此外,删除 with 语句 - 如果没有别的,它将有助于减少 DoABC 中的潜在问题。 TMyForm 实际上是 Form1 吗?我的猜测是,无论您是否直接释放了 qryDoAB 形式的任何实例,都已被释放。如果调用了 qryDoABC.Free,如果 Assigned(qryDoABC) 仍将“通过”(返回 True)。

标签: delphi delphi-xe2


【解决方案1】:

qryDoABC 是表单上的一个组件吗?如果是这样,如果表单被删除,它可能会被第二次调用。在这种情况下,表单要么发布得太早,要么查询调用太晚。

如果您手动释放表单,并且第二个查询调用是事件处理程序的结果,您可以使用 Release 释放表单,这仅在处理消息队列时才释放表单,因此没有待处理的消息表格左。

【讨论】:

    【解决方案2】:

    使用查询变量作为局部变量。在你的函数中声明它。并使用“TRY...FINALLY”来免费查询。

    function TMyForm.DoABC:boolean;
    var
      qryDoABC: TADOQuery;
    begin
      try
        qryDoABC := TADOQuery.Create(nil);
        //Set Appropriate Connection String (below for MS-Access)
        qryDoABC.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0; Data Source=MDB_file';
        try
          with qryDoABC do
          begin
            SQL.Clear;
            SQL.Text := 'Some query';
            Parameters.ParamByName('ABC').Value := 'ABC';
            Parameters.ParamByName('XYZ').Value := 'XYZ';
            Open;
            if (Recordcount = 0) then
              result := false
            else
            begin
              result := true;
            end;
            Close;
          end;
        except
          on E : Exception do
          begin
            result := false;
          end;
        end;
      finally
        FreeAndNil(qryDoABC);
      end;
    end;
    

    【讨论】:

    • 通过使用它,我什至第一次都无法触发查询。我现在第一次遇到访问冲突
    • @NareshKumar,对不起,我忘记为查询添加 ConnectionString,现在检查代码。
    【解决方案3】:

    我使用的是这样的 TADOQuery 语法

          with qryDoABC do
          begin
            SQL.Clear;
            SQL.Text := 'Some query';
            Parameters.ParamByName('ABC').Value := 'ABC';
            Parameters.ParamByName('XYZ').Value := 'XYZ';
            Open;
            if (Recordcount = 0) then
              result := false
            else
            begin
              result := true;
            end;
            Close;
          end;
    

    但我放弃了 using With 语句并像这样编写了我的代码

    qryDoABC.SQL.Clear;
        qryDoABC.SQL.Text := 'Some query';
        qryDoABC.Parameters.ParamByName('ABC').Value := 'ABC';
        qryDoABC.Parameters.ParamByName('XYZ').Value := 'XYZ';
        qryDoABC.Open;
        if (qryDoABC.Recordcount = 0) then
          result := false
        else
        begin
          result := true;
        end;
    qryDoABC.Close;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多