BETWEEN 范围包括 '1' 也 returns '10'

BETWEEN with range including '1' also returns '10'

我在 ZF2 中使用 BETWEEN 谓词时遇到一些意外行为。 考虑以下代码:

$ranges = array(
            array(
                'min' => 2,
                'max' => 4
            ),
            array(
                'min' => 7,
                'max' => 9
            )
);

$predicates = array();

foreach($ranges as $range){
    // create a new 'Between' predicate and add it to array
    $between = new Predicate\Between('my_field', $range['min'], $range['max']);
    array_push($predicates, $between);
}

// add predicateset
$select->where->addPredicate(
    new Predicate\PredicateSet(
                            $predicates,
                            Predicate\PredicateSet::COMBINED_BY_OR
                       )
);

现在所有这些工作正常,除非使用包含 1 的范围(例如 0-21-5 等)。 在这种情况下,结果集还包括 10

的值

但是,当我在数据库上直接尝试以下查询时,不会发生这种情况:

SELECT * FROM my_table WHERE my_field BETWEEN 0 AND 5

my_field 在这种情况下是 varchar

我在这里错过了什么?

在深入了解 ZF2 库之后,我发现 Between 谓词总是将输入值设置为 TYPE_VALUE,这基本上意味着值被引号括起来。

一个解决方案是将库中的 Between class 更改为使用 TYPE_LITERAL,但我认为乱用 ZF2 库是不好的做法。

最后,我通过为谓词设置自定义规范使其工作,ZF2 为此提供了一种方法 setSpecification。这会将值转换回整数。

//...

    $between = new Predicate\Between('my_field', $range['min'], $range['max']);

    $between->setSpecification('%1$s BETWEEN CAST(%2$s AS UNSIGNED) AND CAST(%3$s AS UNSIGNED)');

//...

也许不是最漂亮的解决方案,但它可以满足我的需要。