2013-02-11 265 views
1

我想加快将非常大的xml文件导入到我的mysql数据库中,我决定将所有查询转储到SQL文件中,并在控制台上执行它,位更快。在SQL文件中使用IF控制INSERT和UPDATE查询

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

某些表格被链接,这就是为什么我不能使用非常快的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

我不确定你需要这样做。如果tableA.atableA.b,并tableA.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(即没有重复的行错误),则上述语句不会在tableB的第一个字段中插入值1。如果这是你真正想要的,那么下面应该工作:

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()将返回NULL,而不是上次成功插入的实际自动递增值。我没有证实这种实际行为。