mariadb PDO预准备语句似乎忽略HAVING子句

zpf6vheq  于 2022-11-08  发布在  其他
关注(0)|答案(1)|浏览(143)

I've included a DB-fiddle, and you can adjust the input parameter accordingly。这将返回我所期望的结果,并且与我在PDO中看到的结果不同。
我有以下缩小的表视图和查询:

CREATE TABLE `tagged` {
    `tag` SMALLINT(5) UNSIGNED NOT NULL
}

表中有各种各样的值,但您可以使用1-10表示DB中的标签:

INSERT INTO tagged (tag) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)

查询:

SELECT tagged.tag,
    (@t := :tag),
    @t AS temp_var,
    (@t IS NULL OR FIND_IN_SET(tagged.tag, @t) > 0) AS is_match
FROM tagged
HAVING is_match = 1
LIMIT 150

如果我输入''NULL,我会得到所有的结果。同样地,输入'1'只会得到1的标签,而输入'1,4'则会得到所有带1或4的标签。
查询限制这些结果的方式是通过HAVING子句中的is_match = 1。当与PDO一起运行时,该参数似乎绑定正确,但它完全忽略了子句中的条件:

Array
(
    [0] => stdClass Object
        (
            [tag] => 3
            [(@t := ?)] => 1,4
            [temp_var] => 1,4
            [is_match] => 0     ## should not have been returned
        )

    [1] => stdClass Object
        (
            [tag] => 4
            [(@t := ?)] => 1,4
            [temp_var] => 1,4
            [is_match] => 1
        )

用于运行此程序的PHP代码(简化):

$conn = /* pdo connection object */;
$stmt = $conn->prepare(DB::queryOf('test')); //uses our above query from a file
$stmt->bindValue(':tag', $args['tag'], PDO::PARAM_STR); //hardcode binding '1,4'
$stmt->execute(); //also tried plain #execute($args)
return $stmt->fetchAll(PDO::FETCH_OBJ);

我是不是遗漏了什么?我绑定了一个直接的字符串参数,临时变量似乎在那里,并且设置正确。为什么PDO返回is_match = 0的元素的结果?

wnavrhmk

wnavrhmk1#

我认为这种行为取决于所使用的RDBMS。
在缺少GROUP BY子句的情况下,似乎在某些情况下,整个结果可以被视为“一组”。因为结果中的一行满足HAVING条件,所以所有结果都应通过。
其他阅读资料:
Use of HAVING without GROUP BY in SQL queries
HAVING without GROUP BY
另外,我认为> 0是没有必要的。
我想我应该这样写您的查询:

SELECT tag,
    @t := '1,4' AS temp_var,
    1 AS is_match
FROM tagged
WHERE @t IS NULL OR FIND_IN_SET(tag, @t)
LIMIT 150;

相关问题