0

我正在尝试通过存储过程将 xml 文件导入 MSSQL 2012 服务器。正如您在 xml 文件中看到的那样,它由我要导入表中的几个节点组成:

production_orders- 而一个 xml 文件由该表中的一条记录表示

operations- 一个生产订单由 n 个操作组成

bom_items- 一个操作由 n 个消耗的项目组成

我在插入bom_items表格时遇到了困难。我使用以下(部分)程序进行了尝试。我的问题是我无法访问 operation_id - 或者更好地说 - 它在数据库中仍然是空的。通常可以以这种方式访问​​ ConsumedItem 上方的节点还是我的方法错误?

/** INSERT FOR bom_items **/
     DECLARE db_cursor CURSOR FOR  
     SELECT
            bom_id = line.value('(ItemID/ID)[1]','nvarchar(255)'),
            operation_id = line.value('(../ID)[1]','nchar(10)'),
            stock_id = line.value('(Location/ID)[1]','nvarchar(255)'),
            article_description = line.value('(Description)[1]','nvarchar(255)'),
            line_number = line.value('(LineNumber)[1]','int'),
            quantity = line.value('(Quantity)[1]','float')
            FROM @xmlData.nodes('/DataArea/ProductionOrder/ProductionOrderDetail/BillOfResources/Operations/ConsumedItem')as A(line)
    OPEN db_cursor   
    FETCH NEXT FROM db_cursor INTO @bom_id, @operation_id, @stock_id, @article_description, @line_number, @quantity

    WHILE @@FETCH_STATUS = 0
    BEGIN   
           IF EXISTS (SELECT * FROM bom_items WHERE production_order_id = @production_order_id AND line_number = @line_number AND operation_id = @operation_id)
                      UPDATE bom_items
                      SET   bom_id = @bom_id,
                            stock_id = @stock_id,
                            article_description = @article_description,
                            quantity = @quantity
                      WHERE production_order_id = @production_order_id AND line_number = @line_number

                ELSE
                      INSERT INTO bom_items (bom_id, production_order_id, stock_id, operation_id, article_description, line_number, quantity)
                      SELECT @bom_id, @production_order_id, @stock_id, @operation_id, @article_description, @line_number, @quantity
           FETCH NEXT FROM db_cursor INTO @bom_id, @stock_id, @operation_id, @article_description, @line_number, @quantity    
    END   

    CLOSE db_cursor   
    DEALLOCATE db_cursor    

XML 文件:

<DataArea>
        <ProductionOrder>
          <ProductionOrderHeader type="ShopFloor">
            [...]
          </ProductionOrderHeader>
          <ProductionOrderDetail>
            <Sequence>1</Sequence>
            <Status>
              <Code listID="Production Order Status">Released</Code>
              <EffectiveDateTime>2013-11-13T10:45:51Z</EffectiveDateTime>
            </Status>
            <BillOfResources>
              <Operations>
                <ID>10</ID>
                <NextID>20</NextID>
                <Note/>
                <Status>
                  <Code listID="Production Order Status">Planned</Code>
                  <EffectiveDateTime>2013-11-13T10:45:51Z</EffectiveDateTime>
                </Status>
                <ConsumedItem>
                  <ItemID>
                    <ID>BL_BLU</ID>
                  </ItemID>
                  <Description>Gehäuse blau</Description>
                  <LineNumber>10</LineNumber>
                  <Quantity unitCode="ST">1</Quantity>
                  <BaseUOMQuantity unitCode="ST">1</BaseUOMQuantity>
                  <Location type="Warehouse">
                    <ID>W_RM</ID>
                  </Location>
                </ConsumedItem>
                <ConsumedItem>
                  <ItemID>
                    <ID>BL_INC</ID>
                  </ItemID>
                  <Description>Glühlampe</Description>
                  <LineNumber>20</LineNumber>
                  <Quantity unitCode="ST">3</Quantity>
                  <BaseUOMQuantity unitCode="ST">3</BaseUOMQuantity>
                  <Location type="Warehouse">
                    <ID>W_RM</ID>
                  </Location>
                </ConsumedItem>
              </Operations>
              <Operations>
                <ID>20</ID>
                <Note/>
                <Status>
                  <Code listID="Production Order Status">Planned</Code>
                  <EffectiveDateTime>2013-11-13T10:45:51Z</EffectiveDateTime>
                </Status>
                <OutputItem>
                  <ItemID>
                    <ID>BIKELIGHT_RAC_BLU_INC_3_MET_I</ID>
                  </ItemID>
                  <Description>Bikelight Modell Racer</Description>
                  <Location type="Warehouse">
                    <ID>W_FWB</ID>
                  </Location>
                </OutputItem>
              </Operations>
            </BillOfResources>
          </ProductionOrderDetail>
        </ProductionOrder>
      </DataArea>
4

2 回答 2

2

首先,为了避免重复你的代码和可能的错误,我建议使用这样的游标结构

declare db_cursor cursor for
    select ...

open db_cursor
while 1 = 1
begin
    fetch db_cursor into @variable
    if @@fetch_status <> 0
       break
    ...
end
close db_cursor
deallocate db_cursor

第二,你为什么需要光标在这里?你可以只使用一个或两个语句,例如,对这个操作使用合并,或者更新 + 插入,像这样:

merge table1 as t
using (
    select
        a.b.value('key1[1]', 'int') as key1,
        a.b.value('val1[1]', 'int') as val1,
        a.b.value('val2[1]', 'int') as val2
    from @xmlData.nodes('root/data') as a(b)
) as x on x.key1 = t.key1
when matched then
    update set
        val1 = x.val1,
        val2 = x.val2
when not matched then
    insert (key1, val1, val2)
    values (x.key1, x.val1, x.val2);

sql fiddle demo

于 2013-11-13T18:16:13.957 回答
0

问题出在第二个

 FETCH NEXT FROM db_cursor INTO @bom_id, @stock_id, @operation_id, @article_description, @line_number, @quantity    

而光标的顺序是 bom_id, operation_id, stock_id (...) 因此 stock_id 映射到 operation_id ,反之亦然。

感谢这个问题的所有读者。

于 2013-11-13T15:58:20.623 回答