TADOQuery.SQL 属性是一个TStrings 对象。它的Add() 方法返回您刚刚添加到列表中的字符串的index。这就是为什么在您的示例中返回值是整数0。
但这不是您在这种情况下想要的。根据需要填写SQL语句后,您需要通过调用TADOQuery.Open()方法在数据库上实际执行该SQL,然后您可以从@读取检索到的字段值987654325@收藏,如:
ADOQuery1.SQL.Text := 'SELECT grouppp FROM f3_sheet WHERE holder = ' + AnsiQuotedStr(cb1.Text, '"');
ADOQuery1.Open;
try
if not ADOQuery1.Eof then
gpp.Text := ADOQuery1.Fields[0].AsString
else
gpp.Text := '';
finally
ADOQuery1.Close;
end;
话虽如此,请注意我如何将您的 SQL 更改为使用 AnsiQuotedStr(),而不是手动将 cb1.Text 用引号括起来。如果允许用户在TComboBox 中输入任意文本,您的原始代码将遭受潜在的SQL 注入攻击。
例如,如果用户要在TComboBox 中输入类似"; DELETE FROM f3_sheet; -- 的内容,您的原始代码最终会执行以下SQL:
SELECT grouppp FROM f3_sheet WHERE holder = ""; DELETE FROM f3_sheet; --"
您的数据库表的内容将会再见!
将TComboBox 设为只读是缓解这种攻击的一种方法,这样只有您的代码才能指定不会破坏 SQL 的有效字符串。
使用AnsiQuotedStr()是另一种方式,通过转义用户文本中嵌入的引号,例如:
SELECT grouppp FROM f3_sheet WHERE holder = """; DELETE FROM f3_sheet; --"
现在 SQL 将在 holder 字段中搜索文字字符串 "; DELETE FROM f3_sheet; --,但找不到任何结果。
但是,避免此类攻击的最佳方法是首先不要手动创建 SQL 语句,而是使用 参数化查询 或 存储过程。例如,上面的例子可以重写为使用这样的参数:
// make sure to set ADOQuery1.ParamCheeck=true beforehand...
ADOQuery1.SQL.Text := 'SELECT grouppp FROM f3_sheet WHERE holder = :PHolder';
ADOQuery1.Parameters.ParamByName('PHolder').Value := cb1.Text;
ADOQuery1.Open;
try
if not ADOQuery1.Eof then
gpp.Text := ADOQuery1.Fields[0].AsString
else
gpp.Text := '';
finally
ADOQuery1.Close;
end;
让数据库为您处理任何引用和转义要求。