Ich glaube, ich bin mit meiner jetzigen Variante recht zufrieden. Für mehrere tausend Zeilen könnte das sicherlich etwas lahm werden, aber es erfüllt zumindest die Aufgabe "finde den längenmäßig besten Match zu einem String, der den Feldwert enthält oder wo der Feldwert im String enthalten ist, in der Tabelle X aus allen Textspalten":
Delphi-Quellcode:
var
fields: TStringList;
tableName, fieldName, suchString: String;
i: Integer;
begin
fields := TStringList.Create;
try
Qry.SQL.Text := 'DESCRIBE `'+tableName+'`';
Qry.Open;
while not Qry.Eof do
begin
typeName := Qry.FieldByName('Type').AsString;
if (Pos('char', typeName)>0) or (Pos('text', typeName)>0) then
fields.Add(Qry.FieldByName('Field').AsString);
Qry.Next;
end;
Qry.Close;
Qry.SQL.Clear;
for i := 0 to fields.Count-1 do
begin
Qry.SQL.Add('(SELECT id, ABS(CHAR_LENGTH(`'+fields[i]+'`)-'+IntToStr(Length(suchString))+') lendiff, '''+fields[i]+''' colname FROM `'+tableName+'` WHERE '+
'INSTR(`'+fields[i]+'`, '''+suchString+''')>0 OR INSTR('''+suchString+''', `'+fields[i]+'`)>0) ')
if i<fields.Count-1 then
Qry.SQL.Add('UNION ');
end;
Qry.SQL.Add(' ORDER BY lendiff ASC LIMIT 1');
Qry.Open;
if Qry.RecordCount > 0 then
begin
gesuchteSpalte := Qry.FieldByName('colname').AsString;
gesuchteID := Qry.FieldByName('id').AsInteger;
end;
finally
fields.Free;
end;
end;
Falls des mal wer brauchen kann. Vorsicht ist allerdings bei Strings geboten, die Sonderzeichen beinhalten. Da wäre Umstricken auf Parameter sicherlich sinnig, in meinem Fall entsprechen sie ursprungsbedingt immer schon nur gültigen Bezeichnern ohne Sonderkrams.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)