Delphi TFDQuery访问SQL Server参数类型错误导致数值超出范围问题
问题解决方法
错误根因
你遇到的Numeric value out of range报错是FireDAC默认的参数类型推断逻辑导致的:默认配置下FireDAC不会主动拉取数据表的字段元数据匹配参数类型,只会根据你给参数赋值的字面量大小推断类型:
- 给
:P0赋值正整数1,被推断为取值范围0~255的ftByte类型 - 给
:P1赋值负整数-1,被推断为取值范围-128~127的ftShortint类型
这两个类型和表中定义的INT类型不匹配,查询执行时就会触发数值越界错误。而ADO默认会拉取数据库元数据匹配参数类型,所以不会出现该问题。
解决方法
方法1:显式指定参数类型(最稳妥,无副作用)
赋值参数时优先用AsInteger方法,或者显式设置DataType属性,强制指定为整数类型:
FDQparas.Close; FDQparas.SQL.Clear; FDQparas.SQL.Add('select * from ZREZUDET where RZLID = :P0 and RZLPOSID = :P1'); // 用AsInteger赋值自动指定参数类型为ftInteger FDQparas.Params[0].AsInteger := 1; FDQparas.Params[1].AsInteger := -1; // 也可以手动设置DataType // FDQparas.Params[0].DataType := ftInteger; // FDQparas.Params[0].Value := 1; FDQparas.Open();
方法2:开启数据库连接的扩展元数据配置
修改FDConnection的连接参数,开启ExtendedMetadata,让FireDAC主动拉取数据表的字段元数据,自动匹配参数类型:
在FDConnection的Params属性中添加一行配置:
ExtendedMetadata=True
开启后不需要手动修改参数赋值逻辑,FireDAC会自动识别到表中字段是INT类型,将参数对应设置为ftInteger。
方法3:全局修改FireDAC参数默认推断规则
如果需要全局生效,可以修改FireDAC的资源配置,将默认整数参数类型设为ftInteger,程序初始化时执行一次即可:
FireDAC.Stan.Option.FDManager.DefaultParamDataType := ftInteger;
内容的提问来源于stack exchange,提问作者Toni Grabmayr
相关产品推荐
相关产品推荐

