当PDO::ATTR_EMULATE_PREPARES
为true时,下面的插入查询工作正常,但当设置为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的MySQL原生mysqlnd驱动程序。
<?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>');}
?>
是。
由于类似"此功能可能会导致意外行为"的原因,本机准备语句的多重绑定被关闭。
只需使用另一个占位符进行绑定即可
$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的方式:
$sql='INSERT INTO t1(id,v1) VALUES(:id,:v1) ON DUPLICATE KEY UPDATE v1=values(v1)';