搜索sql表的所有字段时出现语法错误

搜索sql表的所有字段时出现语法错误,sql,delphi,search,syntax,syntax-error,Sql,Delphi,Search,Syntax,Syntax Error,我正在为我的sql表创建一个搜索过滤器,我希望能够搜索表中的所有字段,并返回包含我输入的文本的记录。我有多个表,所以不能将所有字段硬编码到我的语句中。我尝试了此方法(请参见代码snippit),但我遇到了以下错误: 类EOIeException,消息为“查询表达式中的语法错误(缺少运算符)”(类似“%SearchStr%”的fieldContent) 或(字段内容,如“%SearchStr%”) 或“”。进程已停止 通常语法错误很容易解决,但我对这一点一无所知。希望你能帮忙。谢谢顺便说一句,fi

我正在为我的sql表创建一个搜索过滤器,我希望能够搜索表中的所有字段,并返回包含我输入的文本的记录。我有多个表,所以不能将所有字段硬编码到我的语句中。我尝试了此方法(请参见代码snippit),但我遇到了以下错误:

类EOIeException,消息为“查询表达式中的语法错误(缺少运算符)”(类似“%SearchStr%”的fieldContent) 或(字段内容,如“%SearchStr%”) 或“”。进程已停止

通常语法错误很容易解决,但我对这一点一无所知。希望你能帮忙。谢谢顺便说一句,fieldContent和SearchStr只是实际内容的表示

qryInfo.SQL.Clear;
qryInfo.SQL.Add('SELECT * FROM ' + tableName);
qryInfo.Open;

tblInfo.SQL.Clear;
tblInfo.SQL.Add('SELECT * FROM ' + tableName);
tblInfo.SQL.Add('WHERE (' + qryInfo.Fields[0].AsString + ' LIKE ' + QuotedStr('%' + edtSearch.Text + '%') + ')');

for i:= 1 to qryInfo.FieldCount - 1 do
  begin
    tblInfo.SQL.Add(' OR (' + qryInfo.Fields[i].AsString + ' LIKE ' + QuotedStr('%' + edtSearch.Text + '%') + ')');
  end;
tblInfo.Open;
当将ShowMessage(tblInfo.Text)放在tblInfo.Open之前时,我得到

 SELECT * FROM tblGymnast
 WHERE (EG000002 LIKE '%S%')
 OR (Erasmus LIKE '%S%')
 OR (Petrus LIKE '%S%')
 OR (Peter LIKE '%S%')
 OR (EF000001 LIKE '%S%')
 OR (2 LIKE '%S%')
 OR (0832133123 LIKE '%S%')
 OR (SFEW33FWX LIKE '%S%')
 OR (- LIKE '%S%')
 OR (2016/03/08 LIKE '%S%')
 OR (1996-08-19 LIKE '%S%')
 OR (M LIKE '%S%')
 OR (Afrikaans LIKE '%S%')
 OR (White LIKE '%S%')
 OR (Trampoline LIKE '%S%')
 OR (1908966000234 LIKE '%S%')
 OR (EL000004 LIKE '%S%')
 OR (ES000002 LIKE '%S%')
 OR (EL000003 LIKE '%S%')
 OR (TR000002 LIKE '%S%')
 OR (ED000001 LIKE '%S%')
 OR (234567890 LIKE '%S%')
 OR (EM000001 LIKE '%S%')

在编辑添加生成的SQL之后,代码中的错误变得非常清楚。(生成的SQL包含无效的列名,在我指出后,您随后的评论确认它实际上是数据。)

您正试图使用
字段[i].AsString
检索列名作为语句的左边值,但这是错误的
t字段.AsString
以字符串形式返回字段的内容,而不是字段的名称。要检索名称,您需要改用
TField.FieldName

qryInfo.SQL.Clear;
qryInfo.SQL.Add('SELECT * FROM ' + tableName);
qryInfo.Open;

tblInfo.SQL.Clear;
tblInfo.SQL.Add('SELECT * FROM ' + tableName);
tblInfo.SQL.Add('WHERE (' + qryInfo.Fields[0].FieldName + ' LIKE ' + QuotedStr('%' + edtSearch.Text + '%') + ')');

for i:= 1 to qryInfo.FieldCount - 1 do
begin
  tblInfo.SQL.Add(' OR (' + qryInfo.Fields[i].FieldName + ' LIKE ' + QuotedStr('%' + edtSearch.Text + '%') + ')');
end;
tblInfo.Open;

我要指出的是,这段代码对SQL注入非常脆弱,因为它盲目地使用未初始化的用户数据来连接SQL语句。这是一个非常糟糕的主意,因为它会使整个数据库处于危险之中。使用
QuotedStr
绝对不能降低这种风险。请参阅,以获取有关为什么会出现这种安全风险的信息。

编辑添加生成的SQL后,代码中的错误变得非常清楚。(生成的SQL包含无效的列名,在我指出后,您随后的评论确认它实际上是数据。)

您正试图使用
字段[i].AsString
检索列名作为语句的左边值,但这是错误的
t字段.AsString
以字符串形式返回字段的内容,而不是字段的名称。要检索名称,您需要改用
TField.FieldName

qryInfo.SQL.Clear;
qryInfo.SQL.Add('SELECT * FROM ' + tableName);
qryInfo.Open;

tblInfo.SQL.Clear;
tblInfo.SQL.Add('SELECT * FROM ' + tableName);
tblInfo.SQL.Add('WHERE (' + qryInfo.Fields[0].FieldName + ' LIKE ' + QuotedStr('%' + edtSearch.Text + '%') + ')');

for i:= 1 to qryInfo.FieldCount - 1 do
begin
  tblInfo.SQL.Add(' OR (' + qryInfo.Fields[i].FieldName + ' LIKE ' + QuotedStr('%' + edtSearch.Text + '%') + ')');
end;
tblInfo.Open;

我要指出的是,这段代码对SQL注入非常脆弱,因为它盲目地使用未初始化的用户数据来连接SQL语句。这是一个非常糟糕的主意,因为它会使整个数据库处于危险之中。使用
QuotedStr
绝对不能降低这种风险。请参阅,以了解为什么这是一种安全风险。

就在
tblInfo.Open之前
,添加
ShowMessage(tblInfo.SQL.Text)并查看您是否得到了预期的结果。另外,对SQL注入进行一些研究——通过使用未初始化的用户输入连接SQL,您已经完全打开了自己的大门。我会喜欢你的。嗨,肯。我用ShowMessage(tblInfo.SQL.Text)的结果编辑了我的问题。它给出了正确的结果。此外,QoutedStr()中包含的字符串是否仍然会对SQL注入造成负担@KenWhiteYes,QuotedStr()中包含的字符串非常容易受到SQL注入的攻击。你看过我给你的链接了吗?您的SQL没有给出正确的结果。我发现您添加的SQL至少有6个问题-
2
0832133123
-
2016-03/08
1996-08-19
1908966000234
234567890
在我遇到的任何SQL方言中都不是有效的列名。如果您的SQL不会在允许您运行它进行测试的管理实用程序中执行,那么它也不会在您的Delphi应用程序中运行。谢谢你的回复和回复。指出为无效列名的字符串实际上是每列第一行中包含的字符串。为什么qryInfo.Fields[i].AsString返回表中包含的信息而不是列名?请参阅下面的答案。就在
tblInfo.Open之前
,添加
ShowMessage(tblInfo.SQL.Text)并查看您是否得到了预期的结果。另外,对SQL注入进行一些研究——通过使用未初始化的用户输入连接SQL,您已经完全打开了自己的大门。我会喜欢你的。嗨,肯。我用ShowMessage(tblInfo.SQL.Text)的结果编辑了我的问题。它给出了正确的结果。此外,QoutedStr()中包含的字符串是否仍然会对SQL注入造成负担@KenWhiteYes,QuotedStr()中包含的字符串非常容易受到SQL注入的攻击。你看过我给你的链接了吗?您的SQL没有给出正确的结果。我发现您添加的SQL至少有6个问题-
2
0832133123
-
2016-03/08
1996-08-19
1908966000234
234567890
在我遇到的任何SQL方言中都不是有效的列名。如果您的SQL不会在允许您运行它进行测试的管理实用程序中执行,那么它也不会在您的Delphi应用程序中运行。谢谢你的回复和回复。指出为无效列名的字符串实际上是每列第一行中包含的字符串。为什么qryInfo.Fields[i].AsString返回表中包含的信息而不是列名?请参阅下面的答案。谢谢,这样就解决了错误。我知道这是无懈可击的,但目前这与我无关。这是一个学校项目,我将首先关注设计的其他方面,然后再讨论如何确保注射安全。感谢您的帮助。快速问题@Ken White,如何将参数与%:Parameter%等类似语句一起使用您使用的
:Parameter
,并使用
“%”+ParamValue设置参数