I have a table containing the field ‘cost’, when I try to extract its value from the table I get an error saying the field was not found.
function TSQLs.Get(value,room,hotel: string): string; begin with Databasehub.DataModule1 do begin ADOQuery1.SQL.Clear; ADOTable1.TableName:='TblRoom'; ADOQuery1.SQL.Add('SELECT "'+value+'" FROM TblRoom WHERE RoomType="' + Room + '" AND HotelName ="'+Hotel+'"'); DataSource1.DataSet:=ADOQuery1; ADOQuery1.Open; if (ADOQuery1.RecordCount = 1) then begin Result := ADOQuery1.FieldByName(value).AsString; end; end; end;
Advertisement
Answer
In an SQL statement, don’t surround field names in double-quotes. If a field name has spaces (or other special characters, or reserved names), use square brackets instead. And since your field name is being provided by an input string
, make sure to sanitize it before using it to avoid any SQL Injection attacks.
Also, you should be using single-quotes instead of double-quotes around string literals that are used in SQL statements:
if Pos(';', value) > 0 or Pos(',', value) > 0 then raise ...; ADOQuery1.SQL.Text := 'SELECT [' + value + '] FROM TblRoom WHERE RoomType=' + QuotedStr(Room) + ' AND HotelName = ' + QuotedStr(Hotel); ADOQuery1.Open; ...
A safer option to using literals is to use parameters instead (like @whosrdaddy’s answer demonstrates), except that field names in a SELECT
clause can’t be parameterized, so that portion of the SQL will still have to use string concatenation (after sanitizing the string):
if Pos(';', value) > 0 or Pos(',', value) > 0 then raise ...; ADOQuery1.ParamCheck := True; ADOQuery1.SQL.Text := 'SELECT [' + value + '] FROM TblRoom WHERE RoomType=:Room AND HotelName=:Hotel'; ADOQuery1.Parameters.ParamByName('Room').Value := room; ADOQuery1.Parameters.ParamByName('Hotel').Value := hotel; ADOQuery1.Open; ...