我有一个名为“refFile”的字段,其中可能包含或不包含路径描述。
我需要遍历整个数据库并检查“refFile”中定义的路径是否仍然存在。
使用Delphi(Pascal)这需要很多很多分钟
[{
"rank": 1,
"id": "something2",
"diff": "0.7"
},
{
"rank": 2,
"id": "something3",
"diff": "0.1"
},
{
"rank": 3,
"id": "something1",
"diff": "0.09"
}]
我如何在SQL中执行此操作?
谢谢。
答案 0 :(得分:2)
您无法在SQLLite中检查路径的有效性,但可以使用路径中的某些内容过滤记录,并减少要检查的行列表。
您可以在此字段上订购记录(如果您有索引)并仅检查之前未检查过的路径。
您还可以使用线程在后台执行此长操作。只需使用TThread.Createanonymousthread(程序开始结束).Start;
答案 1 :(得分:2)
您无法在纯 SQLLite 查询中检查文件是否存在。你可以使用UDF (User defined function)来做到这一点,但它会稍微复杂一些,需要一些其他编程语言的技能(请注意,在这种情况下,你的文件应该可以从服务器访问,否则它将无法工作)。
如果您正在寻找一个更简单的解决方案,我认为您可以通过减少查询产生的记录数量以及改进 Delphi 代码来加快您的程序速度效率更高。
选择SQL:
使用length和trim函数,因为减少了 Delphi 代码验证的记录数。
select refFile
from myTable
where (refFile is not null) and (length(trim(refFile)) > 0)
<强>的Delphi:强>
尝试使用TDataSet.DisableControls和TDataSet.EnableControls(这样,即使数据集组件未链接到任何控件,某些数据集的组件也会更快。)
var
Fld : TField;
begin
BigDB.DisableControls();
try
Fld := BigDB.FieldByName('refFile');
BigDB.First;
while not(BigDB.Eof) do
begin
if not(FileExists(Fld.AsString)) then
begin
BigDB.Edit;
Fld.AsString := '';
BigDB.Post;
end;
BigDB.Next;
end;
finally
BigDB.EnableControls();
end;
此外,您可以考虑其他优化:
refFile
字段多次包含相同的值,您可以按refFile
字段对查询进行排序,并更改 Delphi 代码,以便仅验证每个文件名一旦。 (您可以通过存储FileExists
函数的最后一个值和结果来实现。 答案 2 :(得分:2)
例如,使用FireDAC,创建用户定义的函数非常容易。如果您正在使用它,请尝试这样的事情。它可以节省一些时间,因为引擎不需要将结果集提取到客户端应用程序:
uses
FireDAC.Phys.SQLiteWrapper;
type
TForm1 = class(TForm)
Button1: TButton;
FDQuery1: TFDQuery;
FDConnection1: TFDConnection;
FDGUIxWaitCursor1: TFDGUIxWaitCursor;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
FValidator: TSQLiteFunction;
procedure ValidateFile(AFunc: TSQLiteFunctionData; AInputs: TSQLiteInputs;
AOutput: TSQLiteOutput; var AUserData: TObject);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FDConnection1.Open;
FValidator := TSQLiteFunction.Create((TObject(FDConnection1.CliObj) as TSQLiteDatabase).Lib);
FValidator.Args := 1;
FValidator.Name := 'FileExists';
FValidator.OnCalculate := ValidateFile;
FValidator.InstallAll;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FDQuery1.SQL.Text :=
'UPDATE MyTable SET FileName = NULL WHERE ' +
'FileName IS NOT NULL AND NOT FileExists(FileName)';
FDQuery1.ExecSQL;
end;
procedure TForm1.ValidateFile(AFunc: TSQLiteFunctionData; AInputs: TSQLiteInputs;
AOutput: TSQLiteOutput; var AUserData: TObject);
begin
AOutput.AsBoolean := FileExists(AInputs[0].AsString);
end;
或者简单地删除TFDSQLiteFunction组件,使用函数名填写FunctionName属性,编写类似于上面的OnCalculate事件处理程序,并通过设置{{来启用组件3}}属性。