Delphi ADO查询主/详细信息
如何设置ADOQuery以过滤数据,从而在DBGrid中显示所有有鳟鱼的湖泊 数据: Nate Pond-LakeMaps.Lake_名称Delphi ADO查询主/详细信息,delphi,Delphi,如何设置ADOQuery以过滤数据,从而在DBGrid中显示所有有鳟鱼的湖泊 数据: Nate Pond-LakeMaps.Lake_名称 Brook trout - Species.Species_Name Creek chub Golden shiner 黑池 Brook trout Brown bullhead Common shiner Brook trout Brown bullhead Common shiner 普莱西德湖 Lake trout Smallmou
Brook trout - Species.Species_Name
Creek chub
Golden shiner
黑池
Brook trout
Brown bullhead
Common shiner
Brook trout
Brown bullhead
Common shiner
普莱西德湖
Lake trout
Smallmouth bass
Yellow perch
MDB数据库
ADoTable1=LakeMapsMASTER
ADOTable2=物种详细信息
关系
LakeMaps Table
LakeMaps.Field[0] = Lake_ID: Autonumber --- ]
LakeMaps.Field[1] = Lake_Name: Text--- |
|Relationship set in the access database
Species Table |
Species.Field[0] = Species_ID: numeric --- ]
Species.Field[1] = Species_Name: text
物种表是一个细节,湖泊地图是主要的
如何设置ADOQuery以过滤数据,从而在DBGrid中显示所有有鳟鱼的湖泊
过滤数据:
内特池塘
Brook trout
Creek chub
Golden shiner
黑池
Brook trout
Brown bullhead
Common shiner
Brook trout
Brown bullhead
Common shiner
您可以设置
Filtered=true
,然后使用OnFilterRecord
事件检查详细数据集是否包含请求的值(这可以在循环中完成,也可以使用数据集的Locate
过程完成)
对于较大数量的数据,这可能会非常缓慢。在这些情况下,我通常直接在SQL中过滤主记录。大概是这样的:
SELECT * FROM LakeMaps
WHERE Lake_ID in (SELECT Lake_ID
FROM Species INNER JOIN SpeciesLakesRelation
ON (Species.Species_ID = SpeciesLakesRelation.Species_Id)
WHERE SPECIES_NAME = 'Brook Trout')
ADOQuery1.SQL.Add( 'SELECT * FROM LakeMaps WHERE Lake_ID in ' +
'(SELECT Lake_ID FROM Species INNER JOIN LakeMaps ON ' +
'(Species.Species_ID = LakeMaps.Lake_Id) ' +
'WHERE SPECIES_NAME = ' + QuotedStr(ComboBoxSpecies.Text) + ')');
此SQL返回来自具有“布鲁克鳟鱼”的湖泊的记录
SpeciesLakesRelation
是包含湖泊地图和物种之间关系的表格 中查询的问题是,查询中的文本必须使用撇号。如果ComboBoxSpecies.Text
具有值Brook Trout
,则SQL的计算结果为:
SELECT * FROM LakeMaps WHERE Lake_ID in
(SELECT Lake_ID FROM Species INNER JOIN LakeMaps ON
(Species.Species_ID = LakeMaps.Lake_Id)
WHERE SPECIES_NAME = Brook Trout)
请注意,Brook Trout并没有撇号,所以您可以从MsAccess获得语法错误
编辑:正如Gerry在评论中指出的:
- 应使用
函数添加撇号,而不是双撇号李>QuotedStr
- 最好的解决方案是使用查询参数
QuotedStr
的Delphi代码应如下所示:
SELECT * FROM LakeMaps
WHERE Lake_ID in (SELECT Lake_ID
FROM Species INNER JOIN SpeciesLakesRelation
ON (Species.Species_ID = SpeciesLakesRelation.Species_Id)
WHERE SPECIES_NAME = 'Brook Trout')
ADOQuery1.SQL.Add( 'SELECT * FROM LakeMaps WHERE Lake_ID in ' +
'(SELECT Lake_ID FROM Species INNER JOIN LakeMaps ON ' +
'(Species.Species_ID = LakeMaps.Lake_Id) ' +
'WHERE SPECIES_NAME = ' + QuotedStr(ComboBoxSpecies.Text) + ')');
现在,如果ComboBoxSpecies.Text
具有值Brook Trout
,则此字符串:
'WHERE SPECIES_NAME = ' + QuotedStr(ComboBoxSpecies.Text) + ')'
评估为:
WHERE SPECIES_NAME = 'Brook Trout')
这是一个不同于:?谢谢Zendar。。。现在它几乎可以工作了。如何避免登录。我试图从connectionstring中删除“Admin”,但在运行时始终需要登录,即使在Delphi IDE中将所有设置为active?您需要做两件事:在连接字符串中设置用户名和密码,并将TAdoConnection属性LoginPrompt设置为false。如果在ComboBoxSpecies.Text中获得一个带撇号的值,则上述示例将失败。按照上面Fabricio的建议使用QuotedStr,或者更好地使用参数化查询(SQL注入也更安全-如果组合框样式是csDropDownList,可能不会有问题)。