You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用FireDAC DBMS标识符实现SQL文本的条件切换

问题解决说明

你遇到的语法报错核心原因是FireDAC的SQL条件预处理器默认未启用,你写的{IF MSSQL}、{IF PG}这类条件指令没有被解析过滤,所有内容都作为普通SQL文本直接发送给了PostgreSQL服务端,PG无法识别MSSQL相关的语法片段,因此抛出如下错误:

[FireDAC][Phys][PG][libpq] ERROR: syntax error at or near "select"


修复配置

你只需要补充1项配置即可启用预处理器:

  • 给TFDConnection或者TFDQuery的ResourceOptions.PreprocessCmdText属性设为True,该属性默认值为False,是预处理器不生效的核心原因。

修正后完整代码

procedure TForm1.Button2Click(Sender: TObject);
var
  Conn: TFDConnection;
  Qry: TFDQuery;
  IdParam: TFDParam;
begin
  Conn := TFDConnection.Create(nil);
  try
    Conn.ConnectionString := 'DriverID=PG;Server=localhost;Database=postgres;User_Name=user;Password=pass;';
    // 启用连接级别的SQL预处理,所有关联的查询都会自动生效
    Conn.ResourceOptions.PreprocessCmdText := True;
    Conn.Connected := True;

    Qry := TFDQuery.Create(nil);
    try
      Qry.Connection := Conn;

      Qry.SQL.Text := 'INSERT INTO people (name) VALUES (:name) ' +
        '{IF MSSQL} select :id = @@identity {FI}' +
        '{IF PG} returning id {INTO :id} {FI}';

      Qry.ParamByName('name').AsString := 'George Smith';

      IdParam := Qry.ParamByName('id');
      IdParam.ParamType := ptOutput;
      IdParam.DataType := ftInteger;

      Qry.Prepare;
      Qry.ExecSQL;

      ShowMessage(IntToStr(IdParam.AsInteger));
    finally
      Qry.Free;
    end;

  finally
    Conn.Free;
  end;
end;

生效逻辑说明

配置开启后,FireDAC会自动根据当前连接的DriverID过滤SQL语句:

  • 连接PG数据库时,最终发送给服务端的SQL为INSERT INTO people (name) VALUES (:name) returning id,MSSQL相关的语句片段会被完全移除
  • 连接MSSQL数据库时,最终发送给服务端的SQL为INSERT INTO people (name) VALUES (:name) select :id = @@identity,PG相关的语句片段会被完全移除

语法错误会直接消失,输出参数也可以正常获取自增ID值。


内容的提问来源于stack exchange,提问作者Tony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 02:45:04