7

Unit db.pas contains implementation of TParam class, which represents a parameter in database query.

While testing queries with lots of params I noticed that function TParam.ParamRef: TParam takes a lot of time, since it calls ParamByName which does an unindexed search of params.

The implementation is simple:

function TParam.ParamRef: TParam;
begin
  if not Assigned(FParamRef) then
    if Assigned(Collection) and (Name <> '') then
      FParamRef := TParams(Collection).ParamByName(Name) else
      FParamRef := Self;
  Result := FParamRef;
end;

It can return self or ParamRef, so the idea is to allow some sort of redirection. But it does a slow ParamByName, is called a lot and I don't understand the purpose. In fact, if I modify it to just returns self everything seems to work correctly.

The only use I see for it would be to have several params of same name all redirect to same instance. If that's the case, surely the performance penalty of ParamByName overweights the benefit of this feature.

ParamRef is undocumented and private so only relevant within the db.pas unit. Also, there is no significant discussion about it online.

Has anyone encountered the same problem ?

  • 3
    Looks to me like wrong implementation of named collection and `ParamRef` like a last resort to reflect `Name` property modification. All those references are discarded when you modify an unlocked parameter collection. If you add one parameter, set its name, add another, rename the first one and use that name for the second, you'll be referring to the second, not the first. – Victoria Apr 09 '18 at 09:22
  • 1
    I second @Victoria. Looks like a piece of code that fixes a problem that shouldn't exist :-) – Markus Müller Apr 09 '18 at 09:26

1 Answers1

1

The only use I see for it would be to have several params of same name all redirect to same instance.

Far as I know that is correct. In Delphi the same parameter can be used multiple times but the underlying database calls usually consider them separate parameters so you end up with multiple instances of the same parameter.

SELECT * FROM SomeTable WHERE FirstName = :NAME or LastName = :NAME

enter image description here

With both parameters redirected to the same instance modifying either sets the other as well.

Brian
  • 6,717
  • 2
  • 23
  • 31