繰り返しますが、単純であるべきだと思われることが、そうではないことが判明しました。提供されるセキュリティのために、準備済みステートメントを使用してレコードを挿入および更新したいと考えています。MySQL は、「一般に、複数の一意のインデックスを持つテーブルで ON DUPLICATE KEY UPDATE 句を使用しないようにする必要があります」と述べています。以下のクエリでは複数のテーブルが表示されませんが、これが機能するようになったら、詳細テーブル (項目) をデータ モデルに追加します。間違っている場合は修正してください。ただし、それは複数の一意のインデックスを示しています。(マスター テーブルのキーは order_num になり、明細テーブルのインデックスは order_num と line_num になります)。そのため、テーブルを簡単に挿入および更新できるようにするために、「重複キー更新時」を使用しない次のシナリオを考え出しました。最初のクエリは INSERT IGNORE で、新しい注文番号がテーブルにない場合は挿入し、注文番号がテーブルにある場合は何もしません。次に、最初のケースでは残りのフィールドの値を追加し、2 番目のケースではフィールドを更新する更新クエリを実行します。
問題は、最初のクエリのみが実行されることです。2 番目のクエリでは、常に次のエラーが発生します。C:\Sites… の mysqli を行 207 でフェッチできませんでした 致命的なエラー: C:\Sites… の非オブジェクトでメンバー関数 bind_param() を呼び出します。挿入または更新のどちらのクエリを最初に実行しても問題ありません (最初に更新を実行すると、明らかに既存のフィールドが更新されます)。2 番目のクエリは常に失敗します。ある種のテーブル ロックの問題のように見えますが、クエリの実行の間に 3 秒のスリープ ステートメントがあっても同じエラーが発生します。私は困惑しています。二次的な問題は、テーブルに挿入されたフィールドごとにステートメントを準備する必要があることです。これはあまりエレガントではありませんが、機能します。より良い方法があれば (それは簡単です!)、それについて知りたいです。何らかの方向性を提供できる人に事前に感謝します。
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();
}