由于代码冗余,我将通常的ADOQuery处理概括为它自己的方法,该方法返回查询的_RecordSet。 现在,当我在该方法中检查查询结果时,它们会检查出来。但是返回的_RecordSet似乎是空的或者为零(例外: EOleException'项目在集合中找不到相应的名称或序号。') 从我收集的内容来看,我似乎需要返回查询的_RecordSet的克隆。到目前为止,我已尝试使用
res := qr.Recordset.Clone(adLockUnspecified); Result := res;
,
TADOQuery.RecordSet._xClone()
方法
失败,以及THESE方法,没有一个工作(几个组件无法识别,我猜的版本差异)。
我用于查询的代码:
function queryDb(const s: WideString; const dc: boolean = true): _RecordSet;
var
ds: String;
conn: TADOConnection;
qr: TADOQuery;
res: _RecordSet;
begin
Result := nil;
conn := TADOConnection.Create(nil);
qr := TADOQuery.Create(nil);
try
ds := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
+ ExtractFilePath(Application.ExeName)
+ 'gdkp.mdb;Persist Security Info=False';
conn.ConnectionString := ds;
conn.LoginPrompt := false;
conn.Connected := true;
qr.Connection := conn;
if(dc = true)then begin
qr.DisableControls
end;
qr.SQL.Add(s);
qr.Open;
Result := qr.Recordset;
finally
conn.Free;
qr.Free;
end;
end;
有人之前是否已经克服了这个问题并且知道合适的答案,或者可以指导我找到有用的内容?
答案 0 :(得分:1)
我不知道哪些疯狂的滑稽动作更疯狂:
设置并连接到函数内部的数据库并在此函数中进行查询,连接到数据库每次查询,将会非常慢。
ADO Query对象的生命周期应比函数内部长。这是一种代码味道,是一种严重的气味。
将记录集保留在查询所在的位置。
普通人创建TDataModules并在其应用的生命周期内保留其对象,并使用此代码重新查询:
query.Active:= false; query.Active:= true;
每当您需要某些数据时,无需连接数据库,创建和拆除连接和查询,即可快速观看您的应用。
你在回忆的那些_recordsets上做了什么?您是否在C#中学习了ADO并且尝试在Delphi中使用C#ADO.net习语?别。停止这样做。
答案 1 :(得分:0)
您返回的RecordSet为nil / empty,因为您在finally语句中将其关闭。我猜这就是为什么你在返回之前尝试克隆RecordSet的原因?克隆它会创建另一个指向同一RecordSet的指针,因此关闭RecordSet也会导致克隆返回nil / empty。
正如Ben建议的那样,有更好的方法可以像使用TDataModules一样,但这是我的方式:
我倾向于为每个数据检索或更新/插入操作编写一个函数。每个函数都作为参数传递一个ADO连接,然后运行查询/存储过程的问题包含在函数中,任何数据都作为var参数或返回值返回。我保留一个ADO连接,根据需要传递给每个函数。
例如(伪代码,因为我暂时没有完成Delphi)
function GetAllUsers(adoConnection : TAdoConnection) : TStringList
begin
result.clear;
if (adoConnection <> nil) then
begin
..
..
// have already set up an ADOStoredProc called storedProc in this
// part of the code block
..
adoRec := storedProc.Execute();
while not (adoRec.eof) do // loop through record set and get our data
begin
result.Add(adoGetFieldStr(adoRec,'USERNAME'));
adoRec.MoveNext;
end;
adoRec.Free;
end;
end
希望有所帮助