一次向3个表中插入数据

分享于2022年07月17日 mysql pdo php 问答
【问题标题】:一次向3个表中插入数据(Insert data into 3 tables at once)
【发布时间】:2022-01-23 04:17:43
【问题描述】:

我想 insert 3 个表中数据数组的值。在一个 insert 中,一切正常,但在多个插入中没有。另外,如果1/3表插入失败,有什么办法可以取消这个过程?

我的代码:

    if($_POST["action"] == 'Add')
{
    $data = array(
        ':afm'      =>  $_POST["afm"],
        ':fname'            =>  $visitor->clean_input($_POST["fname"]),
        ':lname'        =>  $visitor->clean_input($_POST["lname"]),
        ':city'     =>  $visitor->clean_input($_POST["city"]),
        ':street'       =>  $visitor->clean_input($_POST["street"]),
        ':company'      =>  $_POST["company"],
        ':email'        =>  $_POST["email"],
        ':phone'        =>  $_POST["phone"],
        ':make'     =>  $_POST["make"],
        ':model'        =>  $_POST["model"],
        ':gen'      =>  $_POST["gen"],
        ':engine'       =>  $_POST["engine"],
        ':plate'        =>  $_POST["plate"],
        ':vin'      =>  $_POST["vin"]
    );

    $visitor->query = "
    INSERT INTO Client 
    (afm, fname, lname, city, street, company, email) 
    VALUES (:afm, :fname, :lname, :city, :street, :company, :email)
        ";


    $visitor->query = "
    INSERT INTO Phone 
    (phone_type, phone, clientID) 
    VALUES ("main phone", :phone, :afm)
        ";


    $visitor->query = "
    INSERT INTO Vehicle 
    (plate, make, model, gen, engine, vin, clientID) 
    VALUES (:plate, :make, :model, :gen, :engine, :vin, :afm)
        ";

    $visitor->execute($data);

    echo '
success!
'; }


【解决方案1】:

第一次插入

正如你所说,这项工作,我在这里假设你是正确的。

第二次插入

这在我看来非常可疑,您的 " main phone" 看起来在语法上不正确。我怀疑这是您的实际代码。您需要在那里有一个语法正确的命令。

第三次插入

这看起来在语法上是正确的。

覆盖查询

您的第二个和第三个查询分配给 $visitor->query 。你需要这样做

$visitor->query = ...

在第一次分配和

$visitor->query .= ...

在第二和第三。原因是首先您很乐意初始化 query 成员,但在第二个和第三个命令中,如果您丢失了之前的命令,您会很不高兴。相反,您需要 append 第二个和第三个查询。

交易

这是您可以使用事务的方式:

$db->beginTransaction();
$stmt1->execute($query1);
$stmt2->execute($query2);
$stmt3->execute($query3);
$db->commit();

此外,建议将您的命令分解为 3 个单独的 exec 调用,而不是将它们合并为一个。如果要在单个 execute 中执行所有操作,则需要调用 ->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);