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

使用PDO更新MySQL JSON列时值被转为字符串如何解决?

问题根因

PDO默认调用execute()传入关联数组时,所有参数都会被按字符串类型(PDO::PARAM_STR)处理,传入的数值1会被转为字符串'1'绑定到SQL中,因此JSON_OBJECT生成的字段值就是字符串类型。直接写SQL字面量时1会被MySQL识别为数值类型,所以结果符合预期。

解决方案

方案1:显式绑定参数并指定类型

不直接通过execute()传参数数组,改用bindValue方法手动指定参数类型,适合value类型固定为整数的场景:

$data['id'] = 1;
$data['key'] = 'new_field';
$data['value'] = 1;
            
$query= "
    UPDATE `table`
    SET `data` =  JSON_MERGE_PATCH(`data`, JSON_OBJECT(:key, :value))
    WHERE `id` = :id
";
$stmt = $pdo->prepare($query);
$stmt->bindValue(':key', $data['key'], PDO::PARAM_STR);
$stmt->bindValue(':value', $data['value'], PDO::PARAM_INT); // 明确指定为整数类型
$stmt->bindValue(':id', $data['id'], PDO::PARAM_INT);
$stmt->execute();

方案2:SQL层面显式转换类型

如果不想修改PHP绑定逻辑,可以直接在SQL中对value参数做类型转换:

UPDATE `table`
SET `data` =  JSON_MERGE_PATCH(`data`, JSON_OBJECT(:key, CAST(:value AS UNSIGNED)))
WHERE `id` = :id

如果value为浮点类型,可将UNSIGNED替换为DOUBLE/DECIMAL等对应数值类型。

方案3:PHP侧预生成JSON补丁(推荐,适配所有类型)

直接在PHP侧构造要合并的键值对结构,通过json_encode保留原始数据类型后传入SQL,适合value类型不固定、或需要同时修改多个JSON字段的场景:

$data['id'] = 1;
$data['key'] = 'new_field';
$data['value'] = 1;

// 构造要合并的JSON片段
$patch = [
    $data['key'] => $data['value']
];
$jsonPatch = json_encode($patch);

$query= "
    UPDATE `table`
    SET `data` =  JSON_MERGE_PATCH(`data`, CAST(:json_patch AS JSON))
    WHERE `id` = :id
";
$stmt = $pdo->prepare($query);
$stmt->execute([
    'json_patch' => $jsonPatch,
    'id' => $data['id']
]);

补充说明:如果以上方案仍有异常,可关闭PDO模拟预处理避免额外类型转换:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:12:03