【问题标题】:Inserting XML into SQL Server table将 XML 插入 SQL Server 表
【发布时间】:2017-07-14 13:03:31
【问题描述】:

鉴于此 XML:

<Documents>
    <Batch BatchID = "1" BatchName = "Fred Flintstone">
        <DocCollection>
            <Document DocumentID = "269" KeyData = "" />
            <Document DocumentID = "6"   KeyData = "" />
            <Document DocumentID = "299" KeyData = ""     ImageFile="Test.TIF" />
        </DocCollection>    
    </Batch>    
    <Batch BatchID = "2" BatchName = "Barney Rubble">
        <DocCollection>
            <Document DocumentID = "269" KeyData = "" />
            <Document DocumentID = "6"   KeyData = "" />
        </DocCollection>
    </Batch>
</Documents>

我需要以这种格式将它插入到 SQL Server 中的表中:

BatchID   BatchName           DocumentID
1         Fred Flintstone     269
1         Fred Flintstone     6
1         Fred Flintstone     299
2         Barney Rubble       269
2         Barney Rubble       6

这个 SQL:

   SELECT
        XTbl.XCol.value('./@BatchID','int') AS BatchID,
        XTbl.XCol.value('./@BatchName','varchar(100)') AS BatchName,
        XTbl.XCol.value('DocCollection[1]/DocumentID[1]','int') AS DocumentID
   FROM @Data.nodes('/Documents/Batch') AS XTbl(XCol)

得到这个结果:

BatchID BatchName       DocumentID
1       Fred Flintstone NULL
2       Barney Rubble   NULL

我做错了什么?

另外,有人可以推荐一个关于 SQL Server 中 XML 的好教程吗?

谢谢

卡尔

【问题讨论】:

    标签: sql sql-server xml tsql


    【解决方案1】:

    你很亲密。

    使用通配符和 CROSS APPLY,您可以生成多条记录。

    将别名更改为 lvl1lvl2 以更好地说明。

    Declare @XML xml = '
    <Documents>
        <Batch BatchID = "1" BatchName = "Fred Flintstone">
            <DocCollection>
                <Document DocumentID = "269" KeyData = "" />
                <Document DocumentID = "6"   KeyData = "" />
                <Document DocumentID = "299" KeyData = ""     ImageFile="Test.TIF" />
            </DocCollection>    
        </Batch>    
        <Batch BatchID = "2" BatchName = "Barney Rubble">
            <DocCollection>
                <Document DocumentID = "269" KeyData = "" />
                <Document DocumentID = "6"   KeyData = "" />
            </DocCollection>
        </Batch>
    </Documents>
    '
    
    Select BatchID    = lvl1.n.value('@BatchID','int') 
          ,BatchName  = lvl1.n.value('@BatchName','varchar(50)') 
          ,DocumentID = lvl2.n.value('@DocumentID','int') 
     From  @XML.nodes('Documents/Batch') lvl1(n)
     Cross Apply lvl1.n.nodes('DocCollection/Document') lvl2(n)
    

    退货

    BatchID BatchName       DocumentID
    1       Fred Flintstone 269
    1       Fred Flintstone 6
    1       Fred Flintstone 299
    2       Barney Rubble   269
    2       Barney Rubble   6
    

    【讨论】:

    • 很好的解决方案,我这边+1,但为什么* 在第一个.nodes() 中?
    • @Shnugo 既然您提到它, /Batch 会更安全/更具体。还是你在想别的?
    • 不,只是为了避免错误,如果可能有更多具有其他名称的节点...
    • @Shnugo 已更新,但交叉应用仍将针对 DocCollection/Document。只是为了好玩,我在批处理中添加了 ...
    • 嗯,这很复杂 :-D 试图用&lt;DocCollcetion&gt; 封装你的测试&lt;Document&gt;
    猜你喜欢
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    相关资源
    最近更新 更多