PDO :: ATTR_EMULATE_PREPARES对重复键插入/更新的影响

时间:2013-08-08 19:46:58

标签: php mysql pdo

以下插入查询在PDO::ATTR_EMULATE_PREPARES为真时工作正常,但在设置为false时会产生SQLSTATE[HY093]: Invalid parameter number。这是预期的吗?当查询使用相同的值两次时,在数组中包含具有相同值的单独索引总是好的做法吗?例如,$sql='INSERT INTO t1(id,v1) VALUES(:id,:v1) ON DUPLICATE KEY UPDATE v1=:v1_dup'; ... $stmt->execute(array('id'=>1,'v1'=>123, 'v1_dup'=>123));不知道它是否重要,但我使用PHP的本地mysqlnd驱动程序用于MySQL。

<?php
    class db
    {
        private static $instance = NULL;
        private function __construct() {}   //Make private
        private function __clone(){}   //Make private
        public static function db() //Get instance of DB
        {
            if (!self::$instance)
            {
                  try{self::$instance = new PDO("mysql:host=localhost;dbname=myDB;charset=utf8",'myUser','myPW',array(PDO::ATTR_EMULATE_PREPARES=>false,PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC));}
                //try{self::$instance = new PDO("mysql:host=localhost;dbname=myDB;charset=utf8",'myUser','myPW',array(                                  PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC));}
                catch(PDOException $e){die(library::sql_error($e));}
            }
            return self::$instance;
        }
    }

    try{
        $sql = 'CREATE TEMPORARY TABLE t1(id INT UNSIGNED NOT NULL AUTO_INCREMENT, v1 INT NOT NULL,PRIMARY KEY (id) )';
        db::db()->exec($sql);

        $sql='INSERT INTO t1(id,v1) VALUES(:id,:v1) ON DUPLICATE KEY UPDATE v1=:v1';
        $stmt = db::db()->prepare($sql);
        $stmt->execute(array('id'=>1,'v1'=>123));
        $stmt->execute(array('id'=>1,'v1'=>321));

        $stmt=db::db()->query('SELECT * FROM t1');
        $rs=$stmt->fetchAll(PDO::FETCH_ASSOC);
        echo('<pre>'.print_r($rs,1).'</pre>');


    }
    catch(PDOException $e){die('<pre>'.print_r($e,1).'</pre>');}
?>

1 个答案:

答案 0 :(得分:2)

由于“此功能可能导致意外行为”这样的原因,为本机预处理语句关闭了多个绑定。

使用其他占位符绑定它

$sql='INSERT INTO t1(id,v1) VALUES(:id,:v1) ON DUPLICATE KEY UPDATE v1=:v1d';
$stmt = db::db()->prepare($sql);
$stmt->execute(array('id'=>1,'v1'=>123,'v1d'=>123));
$stmt->execute(array('id'=>1,'v1'=>321,'v1d'=>321));

你可以使用mysql-way:

$sql='INSERT INTO t1(id,v1) VALUES(:id,:v1) ON DUPLICATE KEY UPDATE v1=values(v1)';