【问题标题】:PHP: How to combine INSERT with UPDATEPHP:如何将 INSERT 与 UPDATE 结合使用
【发布时间】:2017-11-28 02:09:01
【问题描述】:

我的项目是我的小学校的简单出勤记录。我正在通过在线表单提交进入和退出日志,并使用此查询将它们写入数据库:

$sql = "INSERT INTO table_one (first_name, last_name, location)
VALUES ('$first_name', '$last_name', '$location')";

效果很好 - 到目前为止一切都很好。

同时,我想将一些提交的信息写入同一个数据库中的另一个表。此查询在单独运行时可以正常工作:

$sql = "UPDATE another_table SET location='$location' WHERE first_name='$first_name'";

但是我的问题是如何让它们按顺序发生。只是连续列出它们是行不通的:

$sql = "INSERT INTO table_one (first_name, last_name, location) VALUES 
('$first_name', '$last_name', '$location')";

$sql = "UPDATE personnel_table SET location='$location' WHERE 
first_name='$first_name'";

结合这两个命令以使它们一起执行的最有效(和最安全)的方法是什么?

【问题讨论】:

  • $sql = "UPDATE another_table SET location='$location' WHERE first_name='$first_name'"; 在这里你应该使用那个人的用户 ID 作为标识符,否则如果你的表有 John 并且你添加另一个 john 这将更新所有 John 的记录
  • “仅仅连续列出它们是行不通的” -- 为什么它行不通?
  • 这里只是写了一个名为 $sql 的字符串
  • 所有插入查询都会为您提供插入行的 id,如 $mysqli->insert_id (返回最后插入的 id)
  • 1.简单地将这些字符串分配给变量并不是查询的目的。 Notice here 致电mysql_query()。您必须依次运行每一个。 2. 我强烈建议您将do not interpolate 放入那些SQL 查询字符串中。 3.我强烈建议你不要自己用PHP写SQL。有很多框架和 ORM 比手写查询更好地为您做到这一点。

标签: php mysql


【解决方案1】:

您需要使用事务,这样如果一个查询失败,两个查询都应该失败。只有当两个查询都成功时,它才会添加/更新数据库。

$db= new PDO('mysql:host=localhost; dbname=test', $user, $pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try {
    $db->beginTransaction();

    $sh = $db->prepare("INSERT INTO table_one (first_name, last_name, location) VALUES (?, ?, ?)");
    $sh->execute([$first_name, $last_name, $location]);

    $sh = $db->prepare("UPDATE personnel_table SET location=? WHERE first_name=?");
    $sh->execute([$location, $first_name]);

    $db->commit();
} catch ( Exception $e ) {
    $db->rollBack();
}

【讨论】:

    【解决方案2】:

    对于这个问题,你必须在数据库中使用触发器选项(forEx mysql)。

    触发器就像一个事件。在表上插入时自动更新第二个表。外汇:

    mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account
           FOR EACH ROW SET @sum = @sum + NEW.amount;
    Query OK, 0 rows affected (0.01 sec)
    

    此触发器是帐户表的对象。更新 @sum 变量,然后用于更新第二个表

    【讨论】:

      【解决方案3】:

      您可以创建如下触发器:

      delimiter # 
      create trigger after_ins_trig after insert on first_table
       for each row begin
      UPDATE second_table 
      SET new.location=old.location 
      WHERE new.first_name=old.first_name end#
      delimiter ;
      

      你可以在where子句中查看id。

      【讨论】:

        【解决方案4】:

        为什么不这样:

        Table: teraz
        Create Table: CREATE TABLE `teraz` (
          `col` int(11) DEFAULT NULL
        ) ENGINE=InnoDB DEFAULT CHARSET=latin1
        

        //

        <?php 
        $last_name = 77;
        $conn = new mysqli('localhost','root','','shopping');
        $sql = "INSERT INTO teraz VALUES ('{$last_name}')";
        $sql2 = "SELECT * FROM teraz";
        $conn->query($sql);
        $result = $conn->query($sql2);
        $x = $result->fetch_assoc() ;
        echo $x['col'];
        ?>
        

        ?

        【讨论】:

        • 如果您使用mysqli,您绝对必须使用带有占位符值的预准备语句。在这里使用latin1 也是一个糟糕的计划,utf8mb4 是一个明显更好的默认值,尽管在这里指定它是多余的,因为没有字符列。
        猜你喜欢
        • 2017-12-06
        • 2013-06-02
        • 1970-01-01
        • 1970-01-01
        • 2018-08-02
        • 1970-01-01
        • 2010-10-07
        • 2010-12-04
        • 1970-01-01
        相关资源
        最近更新 更多