delphi - 我怎样才能在德尔福中做到这一点?

标签 delphi ado bde

我正在将应用程序从 BDE 转换为 ADO。

在 BDE 下,如果查询是打开的并且您调用“Sql.Clear”,它将自动关闭数据集。

但是,在 TADOQuery 下情况并非如此,它会引发异常“无法在封闭数据集上执行操作”。

我们的许多遗留代码都依赖于旧的 BDE 行为,因此我从代码中收到很多运行时错误,如下例所示。

我想重写 TADOCustomQuery 类的 Sql.Clear 方法,以便它将包含“.Close”命令。我怎样才能做到这一点?

“.Clear”方法位于 SQL 属性上,该属性的类型为 TWideStrings。我真正的问题是:如何在 TADOQuery 的后代上重写 TWideStrings.Clear 方法?

我已经有一个自定义的 TADOQuery 组件,它用于 SQL 属性:

property SQL: TWideStrings read GetSQL write SetSQL;

这里有一些代码来演示我遇到的问题:

procedure TForm1.btnBDEDemoClick(Sender: TObject);
var
  qryBDE: TQuery;
begin
  //Both queries complete with no problem
  qryBDE := TQuery.Create(nil);
  try
    with qryBDE do begin
      DatabaseName := 'Test';  //BDE Alias
      Sql.Clear;
      Sql.Add('SELECT SYSDATE AS CURDAT FROM DUAL');
      Open;
      ShowMessage('the current date is: ' + FieldByName('CURDAT').AsString);

      Sql.Clear;  //<<<<<NO ERRORS, WORKS FINE
      Sql.Add('SELECT SYSDATE-1 AS YESDAT FROM DUAL');
      Open;
      ShowMessage('And yesterday was: ' + FieldByName('YESDAT').AsString);
    end;  //with qryBDE
  finally
    FreeAndNil(qryBDE);
  end;  //try-finally
end;

procedure TForm1.btnADODemoClick(Sender: TObject);
const
  c_ConnString = 'Provider=OraOLEDB.Oracle.1;Password=*;'+
    'Persist Security Info=True;User ID=*;Data Source=*';
var
  adoConn: TADOConnection;
  qryADO: TADOQuery;
begin
  //First query completes, but the second one FAILS
  adoConn := TADOConnection.Create(nil);
  qryADO := TADOQuery.Create(nil);
  try
    adoConn.ConnectionString := c_ConnString;
    adoConn.Connected := True;
    with qryADO do begin
      Connection := adoConn;
      Sql.Clear;
      Sql.Add('SELECT SYSDATE AS CURDAT FROM DUAL');
      Open;
      ShowMessage('the current date is: ' + FieldByName('CURDAT').AsString);

      Sql.Clear;//<<<<<<<<===========ERROR AT THIS LINE
      Sql.Add('SELECT SYSDATE-1 AS YESDAT FROM DUAL');
      Open;
      ShowMessage('And yesterday was: ' + FieldByName('YESDAT').AsString);
    end;  //with qryADO
  finally
    FreeAndNil(qryADO);
    FreeAndNil(adoConn);
  end;  //try-finally
end;

最佳答案

这不是 BDE 本身的功能。如果您查看 Delphi 附带的源代码,您将看到您所描述的行为是在 TQuery.SQL 的 SetQuery 方法上实现的:

procedure TQuery.SetQuery(Value: TStrings);
begin
  if SQL.Text <> Value.Text then
  begin
    Disconnect;
    SQL.BeginUpdate;
    try
      SQL.Assign(Value);
    finally
      SQL.EndUpdate;
    end;
  end;
end;

而 TADOQuery 的 SetQuery 很简单:

procedure TADOQuery.SetSQL(const Value: TWideStrings);
begin
  FSQL.Assign(Value);
end;

我无法理解为什么 Borland/Codegear 决定不同样实现它。在您的自定义 ADOQuery 中实现 TQuery 的 SetQuery 应该会给您带来您想要的行为。

关于delphi - 我怎样才能在德尔福中做到这一点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/627808/

相关文章:

delphi - 打开 dfm 文件时出错 - 未找到类 xxxx

image - 如何在delphi中向TDbgrid列添加透明图像?

SQL delphi ado,SQL批量执行

sql - 为什么 "insert (...) values (...)"不能插入新行?

delphi - 打开Paradox数据库; 'PDOXUSRS.NET' 解决方法吗?

delphi - 如何清除 Indy TIdHTTP BasicAuthentication 凭据?

json - 跨平台 JSON 解析

excel - 使用 ADO 打开包含宏 (.xlsm) 的 Excel 工作簿并运行宏

sql - 如何合并不同数据库的数据?

sql-server - 尝试发布或编辑时记录已被其他用户更改