Search code examples
delphitadoquery

Delphi TADOQuery Select top N


I am trying to select only the top N items in a TADOQuery, but it gives me and error when I activate the query. It seems to find the top parameter just fine, but fails to replace it when executing. If I don't limit the SQL statement with "Top N" the code works fine.

Here is the basic idea of the code.

const SQL_STR = 'SELECT TOP :cnt name from dSomeTable where done = FALSE';

var
  dbCon         : TADOConnection;
  toSolveQry    : TADOQuery;
  getCnt        : TParameter;
  names         : TField;
  threadCnt     : Integer;

begin
  threadCnt  := 3;
  dbCon := TADOConnection.Create(nil);
  ...
  dbCon.Open();

  toSolveQry := TADOQuery.Create(nil);
  toSolveQry.Connection := dbCon;
  toSolveQry.SQL.Add(SQL_STR);
  toSolveQry.ParamCheck := True;
  getCnt := toSolveQry.Parameters.ParamByName('cnt');
  getCnt.Value := threadCnt;

  toSolveQry.Active := true; //Error here

  names       := toSolveQry.FieldByName('name');
  ...
end

Solution

  • Parameters can't be used for column names in a SELECT or WHERE clause. This precludes use in TOP x as well.

    Use the Format function instead:

    const SQL_STR = 'SELECT TOP %d name from dSomeTable where done = FALSE';
    
    toSolveQry.SQL.Text := Format(SQL_STR, [threadCnt]);
    toSolveQry.Open;
    

    Using the integer format specifier (%d) prevents SQL injection, as Delphi will raise an exception if you provide anything but an integer value as the argument to Format.