在主键上组合2个SQL表 - 更新现有表并插入新行

时间:2016-01-18 12:51:13

标签: sql-server tsql sql-insert dml

我有一个巨大的XML文件(大约60 GB),我需要从中提取数据。 我每周都会收到一个新的更新XML文件,我需要更新数据库中的数据。这是一个包含丹麦每辆车信息的文件,因此每个元素的信息可能会从一周变为另一周。我已经设法创建了一个程序,它可以读取此文件并提取每个元素并将其解析到我的数据库。它目前在XML文件中有8,400,000个元素。首先,我尝试一次将每行上传到我的数据库,我只设法插入大约300行/秒。然后插入所有840万行需要大约7-8个小时。因此,我改变了我的读者,将5000条记录存储在临时数据表中,然后一次批量插入所有5000行。这使我的读/插入速率提高到大约7000行/秒。一个巨大的进步。现在我在不到20分钟的时间内上传所有元素。我的问题是我在使用批量插入时无法更新表格。由于某种原因,某些元素在XML文件中列出了两次,因此我需要在添加主键之前删除表中的重复项。

我目前的解决方案是在我的数据库中创建2个表:dbo.eStatistik和dbo.eStatistikLoad

然后我将使用我的阅读器从新的XML文件中提取所有8,400,000个元素,并将它们批量插入到dbo.eStatistikLoad中。一旦所有元素都在dbo.eStatistikLoad中,我将删除所有重复的行,然后将列(KoeretoejIdent)设置为我的PRIMARY KEY。完成此操作后,我想使用dbo.eStatistikLoad中的数据更新dbo.eStatistik中的每个现有行,并使用dbo.eStatistikLoad中的数据在dbo.eStatistik中插入新行。

目前我可以批量插入和删除重复的行,但我不知道如何更新现有行并在2个表之间插​​入新行。如上所述,在删除重复项后,两个表都有主键(KoeretoejIdent):我已尝试过这些命令,但我一直收到错误:

INSERT
INTO    dbo.eStatistik
SELECT  *
FROM    dbo.eStatistikLoad
ON DUPLICATE KEY
UPDATE
        dbo.eStatistik.KoeretoejIdent = dbo.eStatistikLoad.KoeretoejIdent
        dbo.eStatistik.KoeretoejArtNavn = dbo.eStatistikLoad.KoeretoejArtNavn
        dbo.eStatistik.KoeretoejAnvendelseNavn = dbo.eStatistikLoad.KoeretoejAnvendelseNavn

我收到以下错误消息:

Msg 156, Level 15, State 1, Line 52
Incorrect syntax near the keyword 'ON'.
Msg 102, Level 15, State 1, Line 54
Incorrect syntax near '='.

我也试过这两个命令,但得到同样的错误:

/* COMMAND 1 */
REPLACE INTO dbo.eStatistik SELECT * FROM dbo.eStatistikLoad

/* COMMAND 2 */
INSERT IGNORE
  INTO dbo.eStatistik 
SELECT *
  FROM dbo.eStatistikLoad
     ;

使用这两个命令时出现同样的错误:

Msg 156, Level 15, State 1, Line 70
Incorrect syntax near the keyword 'INTO'.

1 个答案:

答案 0 :(得分:2)

我使用MERGE命令。自MSSQL 2008以来它一直受到支持,它专为像你这样的场景而设计。我不知道你的解决方案的细节,所以这里只是查询的草图:

MERGE dbo.eStatistik AS T
USING dbo.eStatistikLoad AS S ON (T.KoeretoejIdent = S.KoeretoejIdent) 
WHEN NOT MATCHED BY TARGET
    THEN INSERT(KoeretoejIdent, KoeretoejArtNavn, KoeretoejAnvendelseNavn) 
            VALUES(S.KoeretoejIdent, S.KoeretoejArtNavn, S.KoeretoejAnvendelseNavn)
WHEN MATCHED 
    THEN UPDATE SET 
         T.KoeretoejIdent = S.KoeretoejIdent,
         T.KoeretoejArtNavn = S.KoeretoejArtNavn,
         T.KoeretoejAnvendelseNavn = S.KoeretoejAnvendelseNavn;

MERGE命令将允许您执行比上述示例更多的操作,例如删除记录。这是另一个article值得阅读的示例,其中包含使用MERGE。