同时执行以下SQL语句的最完美和最安全的方法是,考虑到MySQLi中的事务,以便将数据添加到所有表中,或者当添加过程发生故障时需要回滚数据桌子上有一个。
$conn = new mysqli(DBHOST, DBUSER, DBPASS, DBNAME);
$stmt1 = $conn->prepare("INSERT INTO stdHouseholder (usersID, parentJob, phoneNumber,address) VALUES (?, ?, ?, ?)");
$stmt1->bind_param("ssss", $userId, $parentJob, $phoneB, $addressB);
$stmt2 = $conn->prepare("INSERT INTO stdConfirmInfo (usersID, commitment, credentials, haveOfficialLetter) VALUES (?, ?, ?, ?)");
$stmt2->bind_param("ssss", $userId, $commitment, $credentials, $NamesEnglish);
$stmt3 = $conn->prepare("INSERT INTO users_roleTB (usersID, role_id) VALUES (?, ?)");
$stmt3->bind_param("ss", $userId, $role_id);
答案 0 :(得分:1)
您可以使用mysqli命令的begin transaction,commit和rollback功能来帮助您。
您需要启动一个事务,检查每个插入查询的结果然后提交(如果它们都表现良好)或者如果它们没有执行则回滚:
<?php
$conn = new mysqli(DBHOST, DBUSER, DBPASS, DBNAME);
$stmt1 = $conn->prepare("INSERT INTO stdHouseholder (usersID, parentJob, phoneNumber,address) VALUES (?, ?, ?, ?)");
$stmt1->bind_param("ssss", $userId, $parentJob, $phoneB, $addressB);
$stmt2 = $conn->prepare("INSERT INTO stdConfirmInfo (usersID, commitment, credentials, haveOfficialLetter) VALUES (?, ?, ?, ?)");
$stmt2->bind_param("ssss", $userId, $commitment, $credentials, $NamesEnglish);
$stmt3 = $conn->prepare("INSERT INTO users_roleTB (usersID, role_id) VALUES (?, ?)");
$stmt3->bind_param("ss", $userId, $role_id);
$conn->begin_transaction();
if ($stmt1->execute() && $stmt2->execute() && $stmt3->execute()) {
$conn->commit();
} else {
$conn->rollback();
}
$conn->close();
答案 1 :(得分:0)
You can't insert to multiple tables in one statement
您必须将它们放入交易中
$conn = new mysqli(DBHOST, DBUSER, DBPASS, DBNAME);
$conn->query("BEGIN;");
$failed = false;
$stmt1 = $conn->prepare("INSERT INTO stdHouseholder (usersID, parentJob, phoneNumber,address) VALUES (?, ?, ?, ?)");
$stmt1->bind_param("ssss", $userId, $parentJob, $phoneB, $addressB);
if (!$stmt2->execute()) {
$failed = true;
$conn->query("ROLLBACK;");
}
if(!$failed){
$stmt2 = $conn->prepare("INSERT INTO stdConfirmInfo (usersID, commitment, credentials, haveOfficialLetter) VALUES (?, ?, ?, ?)");
$stmt2->bind_param("ssss", $userId, $commitment, $credentials, $NamesEnglish);
if (!$stmt2->execute()) {
$failed = true;
$conn->query("ROLLBACK;");
}
}
if(!$failed){
$stmt3 = $conn->prepare("INSERT INTO users_roleTB (usersID, role_id) VALUES (?, ?)");
$stmt3->bind_param("ss", $userId, $role_id);
if (!$stmt3->execute()) {
$failed = true;
$conn->query("ROLLBACK;");
}
}
if(!$failed){
$conn->query("COMMIT;");
}
如果你想在锁定表时进行交易,你将需要另一个approach,因为锁定一个表将提交任何正在运行的交易,这是可怕的
在这种情况下,您将通过关闭mysql的自动提交功能
来启动事务SET autocommit=0;
然后锁定你的表
LOCK TABLES stdHouseholder WRITE, stdConfirmInfo WRITE, users_roleTB WRITE;
然后正常运行准备好的陈述
$stmt->execute();
最后,如果语句成功,则提交事务,然后再次转动自动提交on
。
$conn->query("COMMIT;");
$conn->query("SET autocommit=1;");
请注意,如果您未提交(并且未回滚),则会话结束时将回滚事务(but this is not guaranteed)。