如何基于XML文档更新多个SQL记录并与多个选项合并?

时间:2014-10-01 17:27:35

标签: sql sql-server xml database

我是SQL的新手(大约一周),我有一个问题,我无法弄清楚。

我有一堆xml文件,其结构有点像这样:

<foods>
     <type>
       <food_id>123456789</food_id>
       <food_type>bacon</food_type>
       <food_information>
           <stuff>blah</stuff>
       </food_information>
       <more_food_info>
           <more_stuff>blah</more_stuff>
       </more_food_info>
     </type>
     <type>
       <food_id>123456780</food_id>
       <food_type>eggs</food>
       <food_information>
           <stuff>blahblah</stuff>
       </food_information>
       <more_food_info>
           <more_stuff>blahblahblah</more_stuff>
       </more_food_info>
     </type>
</foods>

我正在使用T-SQL进行批量插入。现在,这个数据库包含数千万条食物记录。几乎没有什么是唯一的,除了一个唯一的值,&#34; food_id。&#34;它总是独一无二的。但是,较新的XML文件包含旧记录的更新,我需要能够仅使用这些新记录(基于food_id)。所以,我需要合并/更新/删除整个记录。

food_information 是一个包含大量内容的表。

more_food_info 也是另一个包含大量内容的表格。

这是我的插入代码的一部分:

DECLARE @xml_data xml
DECLARE @xdoc INT

SET @xml_data = (SELECT CONVERT(xml, BulkColumn, 2) FROM OPENROWSET(Bulk 'foods.xml', SINGLE_CLOB) [rowresults])

EXEC sp_xml_preparedocument @xdoc, OUTPUT, @xml_data

INSERT INTO [type]
    SELECT * FROM OPENXML(@xdoc, '/foods/type', 2)
    WITH
    (
        [food_id] VARCHAR(8) 'food_id',
        [food_type] VARCHAR(255) 'food_type',
    )

INSERT INTO [food_information]
    SELECT 
        [type].[Type_ID], 
        xml.[stuff] FROM [type]
    INNER JOIN OPENXML(@xdoc, '/foods/type/food_information', 2)
    WITH 
    ( 
        [food_id] VARCHAR(8) '../food_id', 
        [stuff] VARCHAR(255) 'stuff'
    )
    AS XML ON xml.[food_id] = [type].[food_id]
    -- Repeat the same style for every other table... (not the same as the [type] table)

EXEC sp_xml_removedocument

这有效,但是我需要能够匹配其他表中这些外键的所有内容,主表中的主键([type]),当然还有序列号,以便更新基于它的所有记录。我不知道如何为多个记录执行此操作。

我需要在MERGE更新中加入所有表,但我只知道如何合并FIRST表,因为我似乎无法插入其他表中的其他条件。 我需要一种方法来查找与 food_id 相关的所有记录,并删除每条记录的最低 Type_ID 号码(主键)并匹配该记录到相应的外键中删除其他表中的其他记录。

问题是,在读取批量xml时,food_id会返回一个巨大的id列表。我只想要我们目前使用的那个,所以我无法比较它。和&#34; IN(选择陈述)&#34;不是我想要的:它必须是一次一个。

TLDR :我该怎么做?伪代码:

Read XML document.
If exists (SELECT [food_id] from [type] WHERE [food_id] = current_xml_food_id)
    THEN
    -- Update/MERGE stuff
    -- Include all the other tables that need updating: 
    -- ... food_information, more_food_info, etc.
    -- ...and make sure the foreign key relationship stays
    -- ...intact. We need to match Type_ID (main table 
    -- ...PrimaryKey) to TableName_ID (ForeignKey)
    ELSE
    -- Insert stuff
End read

编辑:我需要其中一种解决方案,但我不知道如何做到这些:

  • 如果记录存在,请使用合并更新记录。
  • 如果记录存在,删除它(以及所有带有相同foreignkey_id的附带记录)并插入新记录
  • 如果存在多个[food_id]值的副本,请根据其主键删除最低号码。最高的主键号始终是最新的。

1 个答案:

答案 0 :(得分:0)

我认为这个问题真的很糟糕,所以我又做了一个更好的解释。 Blam解决了这个问题。谢谢,Blam!

How do I delete duplicate records, or merge them with foreign-key restraints intact?