You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PDO使用占位符绑定查询字符串时触发Truncated incorrect DOUBLE value错误

错误原因

PDO预处理语句的占位符仅支持绑定数据值,不能用来绑定SQL语法片段(比如HAVING后的条件逻辑)。

当你把包含FIND_IN_SET的完整条件字符串通过:qry_str占位符绑定后,数据库会将该字符串视为普通文本值,而非可执行的SQL逻辑。此时HAVING :qry_str相当于让数据库把attributes的计算结果(布尔值)与长字符串做比较,数据库尝试将字符串转换为数值类型时,就触发了Truncated incorrect DOUBLE value错误——虽然提示里提到了datetime,但本质是类型不匹配导致的转换失败。

解决办法

方案1:安全拼接SQL片段(需做注入防护)

如果必须使用字符串拼接,要确保生成条件的过程安全,比如对group_id和value_id做整数转换,避免SQL注入:

// 假设筛选参数来自用户输入,先做安全处理
$filterPairs = [
    ['group' => 6, 'value' => 47],
    ['group' => 4, 'value' => 176],
    ['group' => 9, 'value' => 218],
];
$conditions = [];
foreach ($filterPairs as $pair) {
    // 强制转成整数,避免注入风险
    $groupId = intval($pair['group']);
    $valueId = intval($pair['value']);
    $conditions[] = "FIND_IN_SET('{$groupId}-{$valueId}', attributes)";
}
$qry_str = implode("\n    AND ", $conditions);

// 正常拼接SQL并执行
$temp_sql = <<<"TEMP"
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_attr` (
    SELECT product_id, GROUP_CONCAT(CONCAT(group_id, '-', IF (custom_value != '', custom_value, value_id)) SEPARATOR ',') AS attributes
    FROM `products_attributes`
    GROUP BY `product_id`
    HAVING $qry_str
);
TEMP;
$pdo->query($temp_sql);

方案2:拆分条件,单独绑定每个参数

把每个FIND_IN_SET的目标值单独用占位符绑定,既保留预处理的安全性,又能正确执行SQL逻辑:

$filterValues = ['6-47', '4-176', '9-218'];
$havingConditions = [];
// 生成带占位符的条件
foreach ($filterValues as $index => $val) {
    $havingConditions[] = "FIND_IN_SET(:filter{$index}, attributes)";
}
$havingClause = implode("\n    AND ", $havingConditions);

$temp_sql = <<<"TEMP"
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_attr` (
    SELECT product_id, GROUP_CONCAT(CONCAT(group_id, '-', IF (custom_value != '', custom_value, value_id)) SEPARATOR ',') AS attributes
    FROM `products_attributes`
    GROUP BY `product_id`
    HAVING $havingClause
);
TEMP;

// 预处理并绑定每个参数
$sth = $pdo->prepare($temp_sql);
foreach ($filterValues as $index => $val) {
    $sth->bindValue(":filter{$index}", $val, PDO::PARAM_STR);
}
$sth->execute();

方案3:重构查询,去掉临时表(更优)

直接将属性筛选逻辑整合到主查询中,无需临时表,代码更简洁高效:

$sql = "SELECT
            m.recommended_price   AS msrp,
            m.purchase_price      AS cost,
            pp.USD                AS regular_price,
            pc.USD                AS special_price,
            pc.start_date         AS start_date,
            pc.end_date           AS end_date,
            pl.permalink          AS permalink,
            pi.name               AS description,
            m.sku                 AS sku,
            m.default_category_id AS cat,
            m.id                  AS prod_id
        FROM `products`                    AS m
        LEFT JOIN `products_prices`        AS pp  ON m.id = pp.product_id
        LEFT JOIN `products_campaigns`     AS pc  ON m.id = pc.product_id
        LEFT JOIN `permalinks`             AS pl  ON (m.id = pl.resource_id AND pl.resource = 'product')
        LEFT JOIN `products_info`          AS pi  ON (m.id = pi.product_id)
        LEFT JOIN `products_to_categories` AS ptc ON (m.id = ptc.product_id)
        INNER JOIN (
            SELECT product_id
            FROM `products_attributes`
            GROUP BY `product_id`
            HAVING FIND_IN_SET(:filter1, GROUP_CONCAT(CONCAT(group_id, '-', IF (custom_value != '', custom_value, value_id)) SEPARATOR ','))
                AND FIND_IN_SET(:filter2, GROUP_CONCAT(CONCAT(group_id, '-', IF (custom_value != '', custom_value, value_id)) SEPARATOR ','))
                AND FIND_IN_SET(:filter3, GROUP_CONCAT(CONCAT(group_id, '-', IF (custom_value != '', custom_value, value_id)) SEPARATOR ','))
        ) AS pa ON m.id = pa.product_id
        WHERE ptc.category_id = :cat
        AND m.status = 1
        LIMIT 55;
";

$sth = $pdo->prepare($sql);
$sth->bindValue(':filter1', '6-47', PDO::PARAM_STR);
$sth->bindValue(':filter2', '4-176', PDO::PARAM_STR);
$sth->bindValue(':filter3', '9-218', PDO::PARAM_STR);
$sth->bindValue(':cat', 100, PDO::PARAM_INT);
$sth->execute();
$data = $sth->fetchAll();

内容的提问来源于stack exchange,提问作者Frank Jance

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:42:22