我正在尝试编写一个登录过程,但在尝试执行包含将来自用户输入的变量的SQL语句时,我遇到了问题。
以下是它的外观:
Var
SS,temp,fn,sn: string;
Begin
ADO := TDBClass.Create('ICAdatabase.mdb');
SS:= 'SELECT * FROM Agents Where aName = ' ' ' + fn + ' ' ' And aSurname = ' ' ' + sn + ' ' ' ';
Temp := Ado.processquery(SS);
End;
当我尝试使用这样的变量时,我得到了"缺少运算符"或"分号错误"或"未终止的字符串"。这是为什么?
答案 0 :(得分:5)
您的引号字符在它们之间有额外的空格,您需要删除它们。 ' ' '
的解析方式与'''
不同:
SS := 'SELECT * FROM Agents Where aName = ''' + fn + ''' And aSurname = ''' + sn + '''';
或者,使用#39
代替''
:
SS := 'SELECT * FROM Agents Where aName = '#39 + fn + #39' And aSurname = '#39 + sn + #39;
或者改为使用QuotedStr()
或AnsiQuotedStr()
:
SS := 'SELECT * FROM Agents Where aName = ' + QuotedStr(fn) + ' And aSurname = ' + QuotedStr(sn);
SS := 'SELECT * FROM Agents Where aName = ' + AnsiQuotedStr(fn, #39) + ' And aSurname = ' + AnsiQuotedStr(sn, #39);
此外,在旁注中,您正在泄露ADO
个对象,并且在使用它时您不是Free
。
话虽如此,你真的应该停止手动构建SQL语句。请改用参数化查询(更快更安全)。我不知道TDBClass
是什么,但以下是使用TADOQuery
的示例:
var
fn, sn, temp: string;
Begin
fn := ...;
sn := ...;
Conn := TADOConnection.Create(nil);
try
Conn.ConnectionString := ...;
ADO := TADOQuery.Create(nil);
try
ADO.Connection := Conn;
ADO.SQL.Text := 'SELECT * FROM Agents Where aName = :AgentName And aSurname = :AgentSurname';
ADO.Parameters.ParamValues['AgentName'] := fn;
ADO.Parameters.ParamValues['AgentSurname'] := sn;
ADO.Open;
try
if not (ADO.Bof and ADO.Eof) then
begin
// use ADO.Fields values as needed...
Temp := ...;
end;
finally
ADO.Close;
end;
finally
ADO.Free;
end;
finally
Conn.Free;
end;
end;
答案 1 :(得分:4)
因为您的代码完全不正确。您需要正确引用变量。我不会告诉你错误的方法(通过加倍每一个引用)导致一团糟。我会告诉你一个更好的方法来解决你提出的直接问题,然后告诉你正确的方法。
至少使用QuotedStr - 我不确定ADO.ProcessQuery
做什么或TDBClass
是什么,所以我无法解决这一问题。您应该使用TADOQuery
代替。您必须非常了解需要引用和不需要引用的内容,并自行完成所有必要的数据类型转换。例如,字符串值被引用,数字不被引用,日期值必须手动转换为数据库期望和引用的格式。
Var
SS,temp,fn,sn: string;
Begin
ADO := TDBClass.Create('ICAdatabase.mdb');
SS:= 'SELECT * FROM Agents Where aName = '+ QuotedStr(fn) +
' And aSurname = ' + QuotedStr(sn);
Temp := Ado.processquery(SS);
End;
正确的方法是使用TADOQuery
和参数。在现实世界的例子中,上面的代码看起来更像是这样:
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM Agents WHERE aName = :Name';
ADOQuery1.SQL.Add('AND aSurname = :Surname');
ADOQuery1.Params.ParamByName('Name').Value := SS;
ADOQuery1.Params.ParamByName('Surname').Value := SN;
ADOQuery1.Open;
这可以防止引用参数,转换类型(例如,直接使用TDateTime),转换数字和记住不引用它们等所有问题,还可以防止SQL注入,使您的数据容易受到恶意软件攻击或恶意用户。