【问题标题】:MySQL - insert rows in one table and then update another with the auto increment IDMySQL - 在一个表中插入行,然后使用自动增量 ID 更新另一个表
【发布时间】:2018-09-19 08:51:31
【问题描述】:

我有 2 个表,分别名为 applicationsfilters。表结构如下:

mysql> DESCRIBE applications;
+-----------+---------------------+------+-----+---------+----------------+
| Field     | Type                | Null | Key | Default | Extra          |
+-----------+---------------------+------+-----+---------+----------------+
| id        | tinyint(3) unsigned | NO   | PRI | NULL    | auto_increment |
| name      | varchar(255)        | NO   |     | NULL    |                |
| filter_id | int(3)              | NO   |     | NULL    |                |
+-----------+---------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> DESCRIBE filters;
+----------+----------------------+------+-----+---------+----------------+
| Field    | Type                 | Null | Key | Default | Extra          |
+----------+----------------------+------+-----+---------+----------------+
| id       | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
| name     | varchar(100)         | NO   |     | NULL    |                |
| label    | varchar(255)         | NO   |     | NULL    |                |
| link     | varchar(255)         | NO   |     | NULL    |                |
| anchor   | varchar(100)         | NO   |     | NULL    |                |
| group_id | tinyint(3) unsigned  | NO   | MUL | NULL    |                |
| comment  | varchar(255)         | NO   |     | NULL    |                |
+----------+----------------------+------+-----+---------+----------------+
7 rows in set (0.02 sec)

我要做的是选择applications中的所有记录,并在filters中创建相应的记录(以便filters.nameapplications.name相同)。当记录插入filters 时,我想获取新插入记录的主键(filters.id) - 这是一个自动增量字段 - 并用它更新applications.filter_id我应该澄清一下,applications.filter_id 是我为此目的创建的一个字段,目前不包含任何数据。

我是一名 PHP 开发人员,并且编写了一个可以执行此操作的脚本,但想知道是否可以使用纯 MySQL 解决方案。在伪代码中,我的脚本的工作方式如下:

  1. 选择applications中的所有记录
  2. 在 (1) 上执行 foreach 循环
  3. filters (filters.name == applications.name) 中插入一条记录
  4. 将插入的 ID (filters.id) 存储到变量中,然后使用变量的数据更新 applications.filter_id

我不知道如何在 MySQL 中执行循环 (2) 和存储自动增量 ID (4)。

我已经阅读了有关Get the new record primary key ID from mysql insert query? 的信息,所以我知道LAST_INSERT_ID(),但不确定如何在遍历每个applications 记录的某种“循环”中引用它。

如果可能的话,请有人建议吗?

【问题讨论】:

    标签: mysql


    【解决方案1】:

    我认为仅对 mysql 的一个请求是不可能做到这一点的。

    但是,我认为这是 mysql 触发器的一个很好的用例。

    我认为你应该这样写:

    CREATE TRIGGER after_insert_create_application_filter AFTER INSERT
    ON applications FOR EACH ROW
    BEGIN
        INSERT INTO filters (name) VALUES (NEW.name);
        UPDATE applications SET filter_id = LAST_INSERT_ID() WHERE id = NEW.id;
    END
    

    此触发器未经测试,但您应该了解它的编写方式。

    如果你不了解mysql触发器,可以阅读this part of the documentation

    【讨论】:

    • 而且您还可以在删除或更新应用时做一些事情。你觉得这个答案怎么样?
    【解决方案2】:

    这不是对您问题的回答,而是对您的数据库设计的评论。

    首先,如果name字段需要包含相同的信息,它们应该是相同的类型和大小(varchar(255)

    但总的来说,我认为您用于表的架构是错误的。您的描述说applications 中的每条记录只能保存一个filter_id。如果是这样的话,使用两个单独的表就没有意义了。

    如果有可能存在多对一关系,请通过相关主键链接记录。如果application 中的多条记录可以与单个过滤器相关,则将filters.id 存储在applications 表中。如果单个应用程序有多个过滤器,请将applications.id 存储在filters 表中。

    如果存在多对多关系,则创建另一个表来存储它:

    CREATE TABLE `application_filters_mappings` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `application_id` int(10) unsigned NOT NULL,
      `filters_id` int(10) unsigned NOT NULL,
      PRIMARY KEY (`id`)
    );
    

    【讨论】:

    • 谢谢你,但这不是问题的答案。我正在使用的数据库位于遗留应​​用程序中,因此不适合更改表结构。 applications 表中每行只有 1 个 filter_id 记录(因为它与 filters 中的记录完全对应)。我只想知道是否可以编写一条 SQL 语句来执行循环/更新,而不是对表进行结构更改。不过还是谢谢。
    猜你喜欢
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-07
    • 2018-03-10
    • 2022-01-21
    • 2014-02-10
    相关资源
    最近更新 更多