参数编号无效,重复更新时PDO失败

时间:2014-02-22 12:52:16

标签: php mysql pdo

我在用户类中创建了以下函数:

public function update_usermeta($user_id,$user_profile)
    {
        $sql = 'INSERT INTO users_meta
                            (user_id,meta_key,meta_value)
                     VALUES (:user_id,:meta_key,:meta_value)
                         ON DUPLICATE KEY
                     UPDATE meta_value = :meta_value';

        foreach ($user_profile as $meta_key => $meta_value) {
            if ($meta_value == null OR $meta_value == "") {continue;}
            if ($meta_key == "identifier" OR $meta_key == "photoURL" OR $meta_key == "displayName" OR $meta_key == "email") {continue;}
            $params = array(
                ':meta_key'   => $meta_key,
                ':meta_value' => $meta_value,
                ':user_id'    => $user_id
            );
            $this->mysql_execute_query($sql,$params);
        }
}

插入工作正常,但我对ON DUPLICATE部分有问题,它出错:

SQLSTATE[HY093]: Invalid parameter number

显然问题是我有更多参数,而不是更新要求。我该如何解决这种情况?

2 个答案:

答案 0 :(得分:5)

取决于仿真设置。

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

如果$boolean === true (PHP 5.2或更新版本的默认值),重复的占位符有效。
如果$boolean === false,则它们无效。

这是我关于日语PDO技巧的文章。

Qiita - PHPでデータベースに接続するときのまとめ

我将翻译与此问题相关的部分......

关于仿真

性能是否足够好?

ON - >是的
关闭 - >马马虎虎

SET NAMES utf8足够安全吗?

ON - >所以(使用DSN charset参数)
关闭 - >是(使用DSN charset参数)

我可以将SQL NULL作为PHP NULL吗?

ON - >是的
关闭 - >是

我可以将SQL int作为PHP int吗?

ON - >没有
关闭 - >是

重复的占位符有效吗?

ON - >是
关闭 - >否(您应该使用?占位符。)

PDO::PARAM_*常量是否将参数转换为正确的类型?

ON - >否(手动转换,例如(int)$valueintval($value)
关闭 - >是

副作用问题$stmt->bindParam()是否安全?

ON - >否(执行后所有引用的变量都转换为字符串......)
关闭 - >是

答案 1 :(得分:3)

@CertaiN提到,真实准备,非模拟的,你不能用同一个名称多次绑定同一个变量。您可以选择使用其他名称绑定它,但此查询不需要它。 The VALUES() function returns the value that would have been inserted,会进行此查询:

    $sql = 'INSERT INTO users_meta
         (user_id,meta_key,meta_value)
       VALUES (:user_id,:meta_key,:meta_value)
       ON DUPLICATE KEY
       UPDATE meta_value = VALUES(meta_value)';

如果需要,可以用于更多列,如下所示:

    $sql = 'INSERT INTO users_meta
         (user_id,meta_key,meta_value)
       VALUES (:user_id,:meta_key,:meta_value)
       ON DUPLICATE KEY
       UPDATE 
         meta_value = VALUES(meta_value),
         meta_key = VALUES(meta_key)';