SQL从XML插入表

时间:2016-03-15 08:31:43

标签: sql sql-server xml

我正在使用MS-SQL。我的xml具有结构survey, section, rows, cells。我想将valuesnodes导入到与tables相关的三个dbo.sections, dbo.rows, dbo.cells中。为此,我必须迭代这个xml。首先insert section并获取scode_indentity()并将其用作child row FKinserted部分的插入内容。然后在cell内获取inserted row,并使用insert FK scope_indentity()获取(id from the inserted parent row node)。在这种情况下best practiceto map nodes parent to child,插入并获取scope_indentity()pass it到insert语句的子值是什么?

表格说明:

dbo.sections

dbo.rows -> FK to sections

dbo.cells -> FK to rows

XML说明:

<survey S_VALUE1="45" S_VALUE2="1" S_VALUE3="1">
    <section SE_VALUE1="34" SE_VALUE2="1855436" SE_VALUE3="False">
        <row R_VALUE1="29" R_VALUE2="7444255">
            <cell C_VALUE1="43830582" C_VALUE2="28" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="29" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="30" C_VALUE3="1" />
        </row>
        <row R_VALUE1="30" R_VALUE2="7444255">
            <cell C_VALUE1="43830582" C_VALUE2="31" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="32" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="33" C_VALUE3="1" />
        </row>
        <row R_VALUE1="31" R_VALUE2="7444255">
            <cell C_VALUE1="43830582" C_VALUE2="34" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="35" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="36" C_VALUE3="1" />
        </row>
    </section>
    <section SE_VALUE1="35" SE_VALUE2="1855436" SE_VALUE3="False">
        <row R_VALUE1="32" R_VALUE2="7444255"/>
        <row R_VALUE1="33" R_VALUE2="7444255"/>
        <row R_VALUE1="34" R_VALUE2="7444255"/>
    </section>
</survey>

1 个答案:

答案 0 :(得分:3)

IF OBJECT_ID('tempdb.dbo.#temp') IS NOT NULL
    DROP TABLE #temp
GO

DECLARE @x XML = '
<survey S_VALUE1="45" S_VALUE2="1" S_VALUE3="1">
    <section SE_VALUE1="34" SE_VALUE2="1855436" SE_VALUE3="False">
        <row R_VALUE1="29" R_VALUE2="7444255">
            <cell C_VALUE1="43830582" C_VALUE2="28" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="29" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="30" C_VALUE3="1" />
        </row>
        <row R_VALUE1="30" R_VALUE2="7444255">
            <cell C_VALUE1="43830582" C_VALUE2="31" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="32" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="33" C_VALUE3="1" />
        </row>
        <row R_VALUE1="31" R_VALUE2="7444255">
            <cell C_VALUE1="43830582" C_VALUE2="34" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="35" C_VALUE3="1" />
            <cell C_VALUE1="43830582" C_VALUE2="36" C_VALUE3="1" />
        </row>
    </section>
    <section SE_VALUE1="35" SE_VALUE2="1855436" SE_VALUE3="False">
        <row R_VALUE1="32" R_VALUE2="7444255" />
        <row R_VALUE1="33" R_VALUE2="7444255" />
        <row R_VALUE1="34" R_VALUE2="7444255" />
    </section>
</survey>'

SELECT
      SE_VALUE1 = t.c.value('@SE_VALUE1', 'INT')
    , SE_VALUE2 = t.c.value('@SE_VALUE2', 'INT')
    , SE_VALUE3 = t.c.value('@SE_VALUE3', 'BIT')
    , R_VALUE1 = t2.c2.value('@R_VALUE1', 'INT')
    , R_VALUE2 = t2.c2.value('@R_VALUE2', 'INT')
    , C_VALUE1 = t3.c3.value('@C_VALUE1', 'INT')
    , C_VALUE2 = t3.c3.value('@C_VALUE2', 'INT')
    , C_VALUE3 = t3.c3.value('@C_VALUE3', 'BIT')
INTO #temp
FROM @x.nodes('survey/section') t(c)
OUTER APPLY t.c.nodes('row') t2(c2)
OUTER APPLY t2.c2.nodes('cell') t3(c3)

INSERT INTO tbl1...
SELECT DISTINCT SE_VALUE1, SE_VALUE2, SE_VALUE3
FROM #temp

INSERT INTO tbl2...
SELECT DISTINCT R_VALUE1, R_VALUE2
FROM #temp t1
JOIN tbl1 t2 ON t1.SE_VALUE1 = t2.SE_VALUE1
WHERE t1.R_VALUE1 IS NOT NULL

INSERT INTO tbl3...
SELECT DISTINCT C_VALUE1, C_VALUE2, C_VALUE3
FROM #temp t1
JOIN tbl2 t2 ON t1.R_VALUE1 = t2.R_VALUE1
WHERE t1.C_VALUE1 IS NOT NULL

更新

DECLARE @x XML = '
<section SE_VALUE1="34">
    <row R_VALUE1="29">
        <cell C_VALUE1="43830582" />
    </row>
    <row R_VALUE1="30" R_VALUE2="7444255" />
</section>
<section SE_VALUE1="35" />'

SELECT
      SE_VALUE1 = t.c.value('@SE_VALUE1', 'INT')
    , R_VALUE1 = t2.c2.value('@R_VALUE1', 'INT')
    , C_VALUE1 = t3.c3.value('@C_VALUE1', 'INT')
FROM @x.nodes('section') t(c)
OUTER APPLY t.c.nodes('row') t2(c2)
OUTER APPLY t2.c2.nodes('cell') t3(c3)

SELECT
      SE_VALUE1 = t.c.value('@SE_VALUE1', 'INT')
    , R_VALUE1 = t2.c2.value('@R_VALUE1', 'INT')
    , C_VALUE1 = t3.c3.value('@C_VALUE1', 'INT')
FROM @x.nodes('section') t(c)
CROSS APPLY t.c.nodes('row') t2(c2)
CROSS APPLY t2.c2.nodes('cell') t3(c3)

输出:

SE_VALUE1   R_VALUE1    C_VALUE1
----------- ----------- -----------
34          29          43830582
34          30          NULL
35          NULL        NULL

SE_VALUE1   R_VALUE1    C_VALUE1
----------- ----------- -----------
34          29          43830582