使用 LOAD LOCAL DATA INFILE 时如何获取行 ID?

How to get row ids when using LOAD LOCAL DATA INFILE?

我有 MySQL 数据库和 table 我从多个文件中插入使用 LOAD DATA LOCAL INFILE ... 声明。我将 PRIMARY KEY ID 设置为 auto_increment。问题是,当我只想更新 table.

的一部分时

假设我过去插入了 file_1, file_2, file_3,现在我只想更新 file_2。我想象伪工作流中的过程

  1. 删除与file_2
  2. 相关的旧数据
  3. 插入来自 file_2
  4. 的新数据

但是,很难确定哪些数据最初来自 file_2。为了找出答案,我想出了这个主意:

当我插入数据时,我会记下我插入的行的 ID,因为我使用的是 auto_increment 我可以为每个文件记下类似 from_id, to_id 的内容.然后,当我只想更新 file_x 时,我将只删除带有 from_id <= id <= to_id 的数据(其中 from_id, to_idfile_x 相关)。

经过一些搜索,我发现了 @@identitylast_insert_id() (see),但是,当我在 [=26] 之后使用 select last_insert_id() =] 我只得到一个 id,而不是与数据对应的最大 id,而是最后添加的(如定义的那样)。我正在使用 mysql.connnector 使用

从 Python 连接到数据库
cur.execute("select last_insert_id();")
print(cur.fetchall())
# gives
# [(<some_number>,)]

那么,有没有办法检索分配给使用上述 LOAD DATA LOCAL INFILE... 语句导入的数据的所有(或至少最小和最大)ID?

如果您需要记住 table 中每条记录的来源,那么您最好将信息存储在一个字段中。

我将向 table 添加一个类型为 TINYINT 的新字段 (src) 并存储来源的 ID(1 for file_1, 2 对于 file_2 a.s.o.)。我假设不会超过 255 个来源;否则使用 SHORTINT 作为其类型。

然后,当您需要更新从 file_2 导入的记录时,您有两个选择:

  1. 删除所有具有 src = 2 的记录,然后将新记录从文件加载到 table;这不完全是一个更新,它是一个替代品;
  2. 将新记录从文件加载到新的 table,然后从中复制更新现有记录所需的值。

选项#1

删除很容易:

DELETE FROM table_1 WHERE src = 2

加载新数据并将 src 的值设置为 2 也很容易(在 documentation 中有解释):

LOAD DATA INFILE 'file.txt'
INTO TABLE table_1
  (column1, column2, column42)    # Put all the columns names here
                                  # in the same order the values appear in the file
SET src = 2                       # Set values for other columns too

如果文件中有您不需要的列,则将它们的值加载到变量中并忽略这些变量。例如,如果文件的第三列不包含有用的信息,您可以使用:

INTO TABLE table_1 (column1, column2, @unused, column42, ...)

单个变量(我称之为 @unused 但它可以有任何名称)可用于从您要忽略的所有列加载数据。

选项#2

第二个选项需要创建一个有效的 table 但它更灵活。它只允许根据通常的 WHERE 条件更新部分行。但是,仅当可以使用从文件加载的值(有或没有 src 列)识别记录时才可以使用它。

工作 table(我们将其命名为 table_w)具有您要从文件中加载的列,并且是预先创建的。

当需要更新从 file_2 导入的行时,您可以这样做:

  1. 截断工作 table(只是为了确保它不包含以前导入的任何剩余物);
  2. 将文件中的数据加载到工作中table;
  3. 加入工作table和table_1并根据需要更新table_1的记录;
  4. 截断工作 table(清理当前导入)。

代码:

# 1
TRUNCATE table_w;

# 2
LOAD DATA INFILE 'file.txt'
INTO TABLE table_w
    (column_1, column_2, column 42);       # etc

# 3
UPDATE table_1 t
INNER JOIN table_w w
    ON t.column_1 = w.column_1
    # AND t.src = 2                      # only if column_1 is not enough
SET t.column_2  = w.column_2,
    t.column_42 = w.column_42
# WHERE ... you can add extra conditions here, if needed

# 4
TRUNCATE TABLE table_w