我试图通过delphi上的一个ado数据库表进行过滤。
我有一个连接到查询(qryData)的dbgrid,一旦执行此代码,该dbgrid就会变为空白,并且不再发生任何事情。即使我输入了有效的字段名称,它也应该在dbgrid中显示它,但是什么也没有显示。我究竟做错了什么?
procedure TfrmProjects.cbxColumnsSelect(Sender: TObject);
begin
if edtsearch.Text = '' then
begin
showmessage('The search field should be entered');
exit;
end
else
begin
ssearch:= edtsearch.Text;
showmessage(ssearch);
end;
if cbxColumns.ItemIndex = -1 then
begin
showmessage('Please select a field');
exit;
end
else
begin
scolumn:= cbxColumns.Items[cbxColumns.itemindex];
showmessage(scolumn);
end;
with dmUsers do
begin
with qryData do
begin
sql.Clear;
sql.Text := 'Select * FROM tbl_projects where' + quotedstr(scolumn) + ' = ' +quotedstr(ssearch);
open;
end;
end;
以下对我有用。您将需要将对qryData的引用更改为dmUsers.qryData。顺便说一句,请尝试避免使用“ with ...”
请注意,您正在构造的SQL不是理想的,因为它没有考虑要搜索的列是否为数据类型,该数据类型要求查询中指定的值用引号引起来。列名不需要用引号引起来,但如果它有嵌入的空格,则可能需要在方括号[]周围加上括号。您在列名周围加上引号的事实是网格空白的原因-您在服务器上要求Sql搜索引擎的是所有行,其中“一个字符串” =“另一个字符串”,任何行均为false因此没有返回任何内容。顺便说一句,这与您有时看到的Sql示例有关,其中有一个where子句,例如“ where 1 = 2”;当然,这永远都是不正确的,其想法是强制搜索引擎解析查询而不返回任何行。
正如@ mostkito-x所评论的那样,查询原始版本的主要问题之一是查询元素之间缺少空间。请自由使用空间,以便您可以看到自己在做什么。当您在查询时遇到麻烦时,可以将其文本放入表单中的备注(设置为Courier等固定间距字体)中,这很不错,因此您可以查看是否实际上是在构造查询,以为自己是。
顺便说一句,如果您尚未收集,在字符串数据类型的搜索值周围使用QuotedStr的优点是可以正确处理搜索值具有嵌入式引号的情况(例如o'Reilly)。
procedure TForm1.CbxColumnNameClick(Sender: TObject);
// NOTE: The following code assumes that either qryData is open when it is called
// or has persistent TFields defined
var
FieldName,
ValueToSearch,
Sql : String;
UseQuotedValue : Boolean;
begin
FieldName := cbxColumnName.Text;
if FieldName = '' then begin
ShowMessage('No field selected for search.');
Exit;
end;
UseQuotedValue := qryData.FieldByName(FieldName).DataType in [ftString, ftWideString, ftMemo];
ValueToSearch := edtSearch.Text;
if UseQuotedValue then
ValueToSearch := QuotedStr(ValueToSearch);
Sql := 'select * from tblProjects where ' + FieldName + ' = ' + ValueToSearch;
if qryData.Active then
qryData.Close;
qryData.SQL.Text := Sql;
qryData.Open;
end;
同样,使用这种类型的查询还可以了解“ SQL注入”恶意软件的风险(http://en.wikipedia.org/wiki/Sql_injection)。公认的智慧是,减少这种风险的措施是使用参数化查询。不幸的是,尽管您可以指定要匹配的列值作为参数,但是您无法在ADO中对列名进行参数化。
要使用参数化查询,Sql看起来像
从tblProjects中选择*,其中SomeColumn =:somevalue
然后,在IDE对象检查器中,您需要在qryData上定义一个参数,并在执行查询之前执行qryData.Parameters.ParamByName('somevalue')。Value:= edtSearch.Text。但是,就像我说的那样,您无法参数化要搜索的列名。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句