原始SQL查询在转换为ActiveRecord查询Firebird数据库时会导致错误

问题描述

我正在尝试做一个相当简单的查询,涉及通过特定列获取两个日期之间的所有记录。

原始sql在Isql Firebird中工作正常:

SELECT * FROM OPS_HEADER
WHERE PB_BOL_DT
BETWEEN '2020-09-01' AND '2020-09-10';

这是我的ActiveRecord转换:

OpsHeader.where('pb_bol_dt BETWEEN 2020-09-01 AND 2020-09-10')

上面这行给我这个错误

expression evaluation not supported expression evaluation not supported Only one operand can be of type TIMESTAMP

我可能将其转换为错误,但是可以肯定,这确实是正确的方法...我不知道为什么它给我带来了很多麻烦。

解决方法

您在日期文字上缺少引号,您想从以下开始:

OpsHeader.where(%q(pb_bol_dt BETWEEN '2020-09-01' AND '2020-09-10'))

但是可以通过向ActiveRecord传递一个范围来使其构建BETWEEN:

OpsHeader.where(pb_bol_dt: '2020-09-01' .. '2020-09-10')

并让AR处理报价。您还可以使用位置或命名的占位符分别传递端点:

OpsHeader.where('pb_bol_dt between ? and ?','2020-09-01','2020-09-10')
OpsHeader.where('pb_bol_dt between :lower and :upper',lower: '2020-09-01',upper: '2020-09-10')

所有这些最终都将向数据库发送相同的SQL,唯一的区别是构建后三个查询所需的字符串处理和类型处理量很少。