Delphi关联PostgreSQL应用中用户输入单引号的报错处理问询
解决Delphi PostgreSQL应用中含单引号客户名的查询语法错误
当客户名包含单引号(如Jon's Store)时,直接拼接Filter字符串会生成customer = 'Jon's Store',数据库解析时会将'Jon视为闭合的字符串,后续的s Store'会被当作无效语法,因此触发**"Syntax error at or near s"**错误。以下是几种可行的解决方法:
方案1:使用参数化查询(推荐)
放弃直接拼接Filter字符串,改用参数化查询,这是最安全且彻底的解决方法,同时避免SQL注入风险:
// 假设使用TQuery组件 DataModule1.qryOrders.Close; DataModule1.qryOrders.SQL.Clear; DataModule1.qryOrders.SQL.Add('SELECT * FROM orders WHERE customer = :CustomerName'); DataModule1.qryOrders.ParamByName('CustomerName').AsString := DataModule1.tblcustomercompany.Value; DataModule1.qryOrders.Open; // 后续处理数据 while not DataModule1.qryOrders.Eof do begin // do something with the data DataModule1.qryOrders.Next; end;
方案2:正确转义单引号后拼接Filter
如果坚持使用TTable的Filter功能,需要手动将客户名中的单引号替换为两个单引号(PostgreSQL中用两个单引号表示一个单引号):
var CustomerName: string; begin tblorders.First; tblorders.Filtered := False; tblorders.IndexFieldNames := 'customer'; // 替换单引号为两个单引号 CustomerName := StringReplace(DataModule1.tblcustomercompany.Value, '''', '''''', [rfReplaceAll]); tblorders.Filter := 'customer = ''' + CustomerName + ''''; DataModule1.tblorders.Filtered := True; // do something with the data tblcustomer.Next; end;
也可以使用AnsiQuotedStr函数自动完成转义和包裹:
tblorders.Filter := 'customer = ' + AnsiQuotedStr(DataModule1.tblcustomercompany.Value, '''');
方案3:使用OnFilterRecord事件
通过TDataSet的OnFilterRecord事件直接比较字符串,完全避免字符串拼接的问题:
- 为tblorders组件添加OnFilterRecord事件处理函数:
procedure TDataModule1.tblordersFilterRecord(DataSet: TDataSet; var Accept: Boolean); begin // 直接比较字段值和输入值 Accept := (DataSet.FieldByName('customer').AsString = DataModule1.tblcustomercompany.Value); end;
- 修改原代码:
tblorders.First; tblorders.Filtered := False; tblorders.IndexFieldNames := 'customer'; // 无需设置Filter属性,直接启用过滤 DataModule1.tblorders.Filtered := True; // do something with the data tblcustomer.Next;
内容的提问来源于stack exchange,提问作者Error In Code
相关产品推荐
相关产品推荐

