简体   繁体   English

Delphi XE2中查询中的访问冲突

[英]Access Violation in query in Delphi XE2

I have a query say qryDoABC in function DoABC . 我有一个查询说qryDoABC在功能DoABC When I call this function first time, all works fine but 2nd time when I call it, at line with qryDoABC do, it throws access violation exception. 第一次调用此函数时,一切正常,但是第二次调用时,与qryDoABC do一致,它将引发访问冲突异常。

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

I googled and found out that I should check whether query is assigned or not. 我用Google搜索,发现应该检查查询是否已分配。 So now I am also checking whether query is assigned or not like this: 所以现在我也在检查是否分配了查询,像这样:

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

Now no exception is there because 2nd time query is not assigned. 现在没有异常,因为没有分配第二次查询。 But I have to fire this qry 2nd time also. 但是我也必须第二次开除这个qry。 How should I assign this query 2nd time. 我应该如何第二次分配此查询。

Full Code: 完整代码:

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;

Use Query Variable as a Local. 使用查询变量作为本地变量。 Declare it in your function. 在您的功能中声明它。 And use 'TRY...FINALLY' to FREE query. 并使用“ 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;

Is qryDoABC a component on a form? qryDoABC是表单上的组件吗? If so, it is probably called the second time, if the form is removed. 如果是这样,如果删除了表格,则可能是第二次调用。 In that case, the form is either released too early or the query is called to late. 在这种情况下,表格要么发布得太早,要么被推迟。

If you free the form manually, and the second query call is the result of an event handler, you can free the form using Release, this frees the form only when the message queue is handled so there are no pending messages for the form left. 如果您手动释放表单,并且第二个查询调用是事件处理程序的结果,则可以使用Release释放表单,这仅在处理消息队列时才释放表单,这样就没有剩余的待处理消息。

I was using TADOQuery Syntax like this 我正在使用这样的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;

But I discarded using With statement and wrote my code like this 但是我放弃了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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM