在SQL文件中使用IF控制INSERT和UPDATE查询

时间:2013-02-11 01:17:48

标签: mysql sql xml bulkinsert

我想加快将一个非常大的xml文件导入到我的mysql数据库中,我决定将所有查询转储到一个SQL文件中并在控制台上执行它,所以它的速度要快一些。

但我的问题是我不能简单地插入所有数据。

有些表是链接的,这就是为什么我不能使用非常快的LOAD DATA INFILE功能的原因。所以我想把查询放在一个SQL文件中,但我需要一些控制操作。

我有一个数据集我需要它的ID(作为主键)才能使用该ID在另一个表中添加数据。

所以我通过mysql控制台尝试了这个:

INSERT IGNORE INTO tableA VALUES ( A, B, C);
SET @id = LAST_INSERT_ID();
IF( @id, SELECT 1, SELECT id INTO @id FROM tableA WHERE a=A and b=B and c=C);
INSERT INTO tableB VALUES ( @id, B, C);

显然IF语句不起作用,它只适用于“SELECT IF”。

我想要做的是使用INSERT IGNORE将数据集添加到tableA中,因此忽略重复错误。如果它添加了一个新行,我得到我的@id与LAST_INSERT_ID(),如果有一个重复@id是空的,但我的IF检查我选择重复并把它放入INTO @a,所以无论如何我有@id设置。然后我使用@id将我的数据放入tableB,所以我有正确的链接。

是否有可能使用IF进行此工作流程?由于我需要对链接表进行一些检查,因此我无法创建一个简单的CSV来使用LOAD DATA INFILE,我认为生成SQL是最好的。

我的XML文件大小为20-25GB。我的perl脚本工作3周就可以导入到数据库中进行所有检查,但由于我所做的所有mysql查询都非常慢,我想将所有查询放在一个文件中并一次性将其放入数据库中。如果我可以控制我的查询流程,我可以创建那个大的sql文件,而不是使用我的perl脚本中的所有检查来运行数百万个查询。

请告诉我这是可能的。

1 个答案:

答案 0 :(得分:1)

我不确定你是否需要这样做。如果tableA.atableA.btableA.c都确定tableA.id,那么无论行条目是否成功,您都应该能够:

INSERT IGNORE INTO tableA VALUES (A, B, C);
INSERT INTO tableB SELECT id, B, C FROM tableA WHERE a=A AND b=B AND c=C;

我意识到这与完全与您发布的查询完全相同。最大的区别是,如果一行实际上正确地插入到tableA中(即没有重复的行错误),那么上面的语句将不会为{{1}中的第一个字段插入值1 1}}。如果这是你真正想要的,那么以下内容应该有效:

tableB

我假设INSERT IGNORE INTO tableA VALUES (A, B, C); SET @id = LAST_INSERT_ID(); INSERT INTO tableB SELECT IF(@id IS NOT NULL, 1, id) FROM tableA WHERE a=A AND b=B AND c=C; 将返回LAST_INSERT_ID()而不是上一次成功插入的实际自动增量值。我还没有证实这种实际行为。