再一次,看起来应该很简单的事情结果并非如此。由于它们提供的安全性,我想使用准备好的语句插入和更新记录。MySQL 声明“一般来说,您应该尽量避免在具有多个唯一索引的表上使用 ON DUPLICATE KEY UPDATE 子句。” 虽然下面的查询没有显示多个表,但一旦我得到这个工作,我会将详细表(行项目)添加到数据模型中。如果我错了,请纠正我,但这表明我有多个唯一索引。(主表上的键是 order_num,行项目表上的索引是 order_num 和 line_num)。因此,为了能够轻松地插入和更新表,我想出了以下不使用“重复键更新”的场景。第一个查询是 INSERT IGNORE ,如果新订单号不在表中,它将插入一个新的订单号,如果订单号已经在表中,则不执行任何操作。然后我运行一个更新查询,在第一种情况下将添加其余字段的值,在第二种情况下更新字段。
问题是只有第一个查询会运行。第二个查询总是给出以下错误。无法在 C:\Sites... 中获取 mysqli 第 207 行致命错误:在 C:\Sites... 中的非对象上调用成员函数 bind_param()。我先运行哪个查询,插入或更新都没有关系(如果我先运行更新,我显然会更新现有字段)。第二个查询总是失败。这似乎是某种表锁定问题,但即使在运行查询之间有 3 秒的 sleep 语句也会发生相同的错误。我难住了。第二个问题是,必须为插入到表中的每个字段准备语句不是很优雅,但它可以工作。如果有更好的方法(很简单!)我很想知道。提前感谢任何可以提供一些指导的人。
function insert($arr){
if(!$mysqli_1=MyDatabase::getConnection()):
echo 'Cannot connect to database.'. mysqli_connect_errno();
exit();
endif;
if($arr):
$cols=array_keys($arr);
$table_key_field_name=$cols[0];
$key_field_value=$arr[$table_key_field_name];
$stmt_1 = $mysqli_1 -> prepare("INSERT IGNORE pi_hft_test_ajax ($table_key_field_name) VALUES(?) ");
$stmt_1->bind_param("s", $key_field_value);//this binds the variables to the paramters (?) above, NOT the values;
$stmt_1->execute();
endif;
echo ' number of affected rows is '.$stmt_1->affected_rows.'<br />';
$stmt_1 -> close();
$err = $mysqli_1->sqlstate;
$mysqli_1 -> close();
}
function update($arr){
if(!$mysqli=MyDatabase::getConnection()):
echo 'Cannot connect to database.'. mysqli_connect_errno();
exit();
endif;
if($arr):
$part=$arr['part'];
$cols=array_keys($arr);
foreach($arr as $key=> $value):
$stmt = $mysqli -> prepare("UPDATE pi_hft_test_ajax SET $key=? WHERE part=? ");
$stmt->bind_param("ss", $value, $part);//this binds the variables to the paramters (?) above, NOT the values;
$stmt->execute();
endforeach;
endif;
$stmt -> close();
echo '$mysqli->error is '.$mysqli->error.'<br />';
echo 'SQLState is '. $mysqli->sqlstate;
$mysqli -> close();
}