0

Trying to run a select statement using the below code. I'm parsing a SQL table name parameter whose value is determined by a case statement. This then assigns the dataset to a global datasource used in another form. However, the app is returning a "Syntax error in FROM clause" dialogue.

I've assigned the correct datatype and during my tests, I can confirm that the parameter's value is what it needs to be i.e. "ACCOUNTS" for case 1.

I'm new to using ADO but ADOQUERY.SQL.GetText is returning the SQL statement with the parameter placeholder ":ATABLE" rather than the parameter value, though I am currently assuming this is normal.

procedure TfrmDataModule.FindAllRecords(Sender: TObject; recordType: Integer);

var
  ADOQuery : TADOQuery;
  Param    : TParameter;

begin

  case recordType of
    1 : currentRecordType := 'ACCOUNTS';
    2 : currentRecordType := 'CONTACTS';
    3 : currentRecordType := 'USERS';
  end;

  { SQL Query }
  SQLStr := 'SELECT * FROM :ATABLE';

  { Create the query. }
  ADOQuery := TADOQuery.Create(Self);
  ADOQuery.Connection := ADOConn;
  ADOQuery.SQL.Add(SQLStr);

  { Update the parameter that was parsed from the SQL query. }
  Param := ADOQuery.Parameters.ParamByName('ATABLE');
  Param.DataType := ftString;
  Param.Value := currentRecordType;

  { Set the query to Prepared--it will improve performance. }

  ADOQuery.Prepared := true;

  try
    ADOQuery.Active := True;
  except
    on e: EADOError do
    begin
      MessageDlg('Error while doing query', mtError,
                  [mbOK], 0);

      Exit;
    end;
  end;

  { Create the data source. }
  DataSrc := TDataSource.Create(Self);
  DataSrc.DataSet := ADOQuery;
  DataSrc.Enabled := true;

end;

Edit: More info. The query does work if I comment out the Param lines and replace the SQLStr :ATABLE with the concatenated SQLStr and the case variable currentRecordType.

Mehdi
  • 385
  • 1
  • 12
Harrebow
  • 3
  • 2

2 Answers2

0

Credit to @DelphiCoder, it appears passing parameters as SQL table names is not allowed.

James Risner
  • 5,451
  • 11
  • 25
  • 47
Harrebow
  • 3
  • 2
0

SQL simply does not allow table names to be provided by parameters in the FROM clause. So, you will just have to use plain ordinary string concatenation instead, eg:

procedure TfrmDataModule.FindAllRecords(Sender: TObject; recordType: Integer);
var
  ADOQuery : TADOQuery;
begin
  case recordType of
    1 : currentRecordType := 'ACCOUNTS';
    2 : currentRecordType := 'CONTACTS';
    3 : currentRecordType := 'USERS';
  end;

  { Create the SQL query. }
  ADOQuery := TADOQuery.Create(Self);
  ADOQuery.Connection := ADOConn;
  ADOQuery.SQL.Text := 'SELECT * FROM ' + currentRecordType;

  try
    { Set the query to Prepared--it will improve performance. }
    ADOQuery.Prepared := true;
    ADOQuery.Active := True;
  except
    on e: EADOError do begin
      MessageDlg('Error while doing query', mtError, [mbOK], 0);
      Exit;
    end;
  end;

  { Create the data source. }
  DataSrc := TDataSource.Create(Self);
  DataSrc.DataSet := ADOQuery;
  DataSrc.Enabled := true;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770