我正在将应用程序从 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/