BETWEEN与范围包括'1'也返回'10'

时间:2015-06-06 01:50:14

标签: php mysql zend-framework2 between

我在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

的值

然而,当我在DB上尝试类似下面的查询时,这不会发生:

SELECT * FROM my_table WHERE my_field BETWEEN 0 AND 5

(在这种情况下my_fieldvarchar

我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

在对ZF2库进行一些挖掘之后,我发现Between谓词始终将输入值设置为TYPE_VALUE,这基本上意味着值被包装在引号中。

一种解决方案是更改库中的Between类以使用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)');

//...

也许不是最漂亮的解决方案,但它适用于我需要的东西。