MySQL/PHP插入和更新,使用不带“的已准备语句”;“关于重复记录更新”;

MySQL/PHP插入和更新,使用不带“的已准备语句”;“关于重复记录更新”;,php,mysql,Php,Mysql,又一次,看似简单的事情却并非如此。我想使用准备好的语句插入和更新记录,因为它们提供了安全性。MySQL声明“一般来说,您应该尽量避免在具有多个唯一索引的表上使用ON-DUPLICATE-KEY-UPDATE子句。”虽然下面的查询不会显示多个表,但一旦我完成了这项工作,我将向数据模型中添加详细表(行项目)。如果我错了,请纠正我,但这表明我有多个唯一索引。(主表上的键是order_num,行项目表上的索引是order_num和line_num)。 因此,为了能够轻松地插入和更新表,我提出了以下不使用

又一次,看似简单的事情却并非如此。我想使用准备好的语句插入和更新记录,因为它们提供了安全性。MySQL声明“一般来说,您应该尽量避免在具有多个唯一索引的表上使用ON-DUPLICATE-KEY-UPDATE子句。”虽然下面的查询不会显示多个表,但一旦我完成了这项工作,我将向数据模型中添加详细表(行项目)。如果我错了,请纠正我,但这表明我有多个唯一索引。(主表上的键是order_num,行项目表上的索引是order_num和line_num)。 因此,为了能够轻松地插入和更新表,我提出了以下不使用“重复密钥更新”的场景。第一个查询是INSERT IGNORE,如果订单号不在表中,它将插入一个新的订单号;如果订单号已在表中,它将不执行任何操作。然后,我运行一个更新查询,在第一种情况下,该查询将为其余字段添加值,在第二种情况下,将更新字段。
问题是只会运行第一个查询。第二个查询总是给出以下错误。无法在C:\Sites…的第207行获取mysqli致命错误:在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();
}
函数插入($arr){
如果(!$mysqli_1=MyDatabase::getConnection()):
echo“无法连接到数据库”。.mysqli_connect_errno();
退出();
endif;
如果($arr):
$cols=数组_键($arr);
$table_key_field_name=$cols[0];
$key_field_value=$arr[$table_key_field_name];
$stmt_1=$mysqli_1->prepare(“插入忽略pi_hft_test_ajax($table_key_field_name))值(?);
$stmt_1->bind_param(“s”,$key_field_value);//这将变量绑定到上面的参数(?),而不是值;
$stmt_1->execute();
endif;
echo“受影响的行数为”。$stmt_1->受影响的行。
; $stmt_1->close(); $err=$mysqli_1->sqlstate; $mysqli_1->close(); } 功能更新($arr){ 如果(!$mysqli=MyDatabase::getConnection()): echo“无法连接到数据库”。.mysqli_connect_errno(); 退出(); endif; 如果($arr): $part=$arr['part']; $cols=数组_键($arr); foreach($arr as$key=>$value): $stmt=$mysqli->prepare(“更新pi\u hft\u test\u ajax SET$key=?其中part=?”; $stmt->bind_param(“ss”,$value,$part);//这将变量绑定到上面的参数(?),而不是值; $stmt->execute(); endforeach; endif; $stmt->close(); 回显“$mysqli->错误为“$mysqli->错误”。
; echo'SQLState is'.$mysqli->SQLState; $mysqli->close(); }
我认为您的代码似乎不受注入保护。您试图对不存在的语句执行绑定操作。例如,您的prepare调用失败,但您的代码假定成功。感谢您的评论。我不知道你为什么说这份声明不存在。每个函数(每个查询)本身运行良好,并更新表。只有当我运行一个查询,然后运行另一个查询时,第二个查询才会失败。无论第二次运行哪个查询,都会失败,无论它是哪一个查询。