【问题标题】:Trouble shredding an xml document into a table using .nodes() and cross apply使用 .nodes() 将 xml 文档切碎成表格并交叉应用时遇到问题
【发布时间】:2016-09-12 15:07:41
【问题描述】:

我有一个定义表索引的 xml 文档。
这是一个例子:

<TargetDatabaseChanges>
     <Tables>
        <Table TName="Replacement" Schema="dbo" TextImageOnFileGroup="PRIMARY">
            <Indexes>
                <Index IndexName="IX_InventoryId" PrimaryKeyIndex="0" IndexDescription="NONCLUSTERED" PadIndex="0" Statistics_NoRecompute="0" IgnoreDupKey="0" AllowRowLocks="1" AllowPageLocks="1">
                  <IndexColumn ICName="ProductId" IsDescendingSort="0" OrdinalPosition="1" />
                </Index>
                <Index IndexName="IX_VendorId" PrimaryKeyIndex="0" IndexDescription="NONCLUSTERED" PadIndex="0" Statistics_NoRecompute="0" IgnoreDupKey="0" AllowRowLocks="1" AllowPageLocks="1">
                  <IndexColumn ICName="VendorId" IsDescendingSort="0" OrdinalPosition="1" />
                </Index>
            </Indexes>
        </Table>
        <Table TName="Activity" Schema="dbo" TextImageOnFileGroup="PRIMARY">
            <Indexes>
                 <Index IndexName="IX_ApplicationId" PrimaryKeyIndex="0" IsUnique="0" IndexDescription="NONCLUSTERED" PadIndex="0" Statistics_NoRecompute="0" IgnoreDupKey="0" AllowRowLocks="1" AllowPageLocks="1">
                    <IndexColumn ICName="ApplicationId" IsDescendingSort="0" OrdinalPosition="1" />
                </Index>
            </Indexes>
        </Table>
     </Tables>
</TargetDatabaseChanges>

当表有 2 个索引,每个索引关联不同的列时,我应该只得到 2 行数据,而我得到 4 行数据。

这是我的选择语句:

SELECT DBTables.Name.value('@TName', 'varchar(100)') AS TableName, DBTables.Name.value('@Schema', 'varchar(20)') AS SchemaName, 
        [Indexes].I.value('@IndexName', 'varchar(100)') AS IndexName,  [Indexes].I.value('@PrimaryKeyIndex', 'varchar(1)') AS PrimaryKeyIndex,  [Indexes].I.value('@IsUnique', 'varchar(1)') AS IsUnique, 
            [Indexes].I.value('@IndexDescription', 'varchar(120)') AS IndexDescription,
            [Indexes].I.value('@PadIndex', 'varchar(1)') AS PadIndex, [Indexes].I.value('@Statistics_NoRecompute', 'varchar(1)') AS StatisticsNoRecompute, [Indexes].I.value('@IgnoreDupKey', 'varchar(1)') AS IgnoreDupKey,
            [Indexes].I.value('@AllowRowLocks', 'varchar(1)') AS AllowRowLocks, [Indexes].I.value('@AllowPageLocks', 'varchar(1)') AS AllowPageLocks,
        [IndexColumn].IC.value('@ICName', 'varchar(100)') AS IndexColumnName, [IndexColumn].IC.value('@IsDescendingSort', 'varchar(1)') AS IsDescendingSort, 
        [IndexColumn].IC.value('@OrdinalPosition', 'varchar(2)') AS OrdinalPosition
FROM @XmlDBChanges.nodes('/TargetDatabaseChanges/Tables/Table') AS DBTables(Name)               
        CROSS APPLY DBTables.Name.nodes('Indexes/Index[@PrimaryKeyIndex=0]') AS [Indexes](I)
        CROSS APPLY DBTables.Name.nodes('Indexes/Index[@PrimaryKeyIndex=0]/IndexColumn') AS [IndexColumn](IC)

这是有 2 个索引的表的表:

Replacement dbo IX_InventoryId  0   NULL    NONCLUSTERED    0   0   0   1   1   ProductId   0   1
Replacement dbo IX_InventoryId  0   NULL    NONCLUSTERED    0   0   0   1   1   VendorId    0   1
Replacement dbo IX_VendorId 0   NULL    NONCLUSTERED    0   0   0   1   1   ProductId   0   1
Replacement dbo IX_VendorId 0   NULL    NONCLUSTERED    0   0   0   1   1   VendorId    0   1

将索引 IX_InventoryId 与列 VendorID 相关联的行不应该存在。 IX_VendorId 行与 ProductId 列相同。

似乎CROSS APPLY DBTables.Name.nodes('Indexes/Index[@PrimaryKeyIndex=0]/IndexColumn') AS [IndexColumn](IC) 正在执行此错误关联,但我不知道如何将其限制为仅IndexColumn 以获得正确的索引。

如何限制这种关联?

【问题讨论】:

    标签: sql-server xml nodes cross-apply


    【解决方案1】:

    想通了...以防其他人需要帮助... 我改了最后一个CROSS APPLY

    CROSS APPLY DBTables.Name.nodes('Indexes/Index[@PrimaryKeyIndex=0]/IndexColumn') AS [IndexColumn](IC)
    

    到这里:

    CROSS APPLY I.nodes('IndexColumn') AS [IndexColumn](IC)
    

    I 来自前面的 CROSS APPLY' So theFROM` 子句,如下所示:

    `FROM @XmlDBChanges.nodes('/TargetDatabaseChanges/Tables/Table') AS DBTables(Name)              
            CROSS APPLY DBTables.Name.nodes('Indexes/Index[@PrimaryKeyIndex=0]') AS [Indexes](I)
            CROSS APPLY I.nodes('IndexColumn') AS [IndexColumn](IC)`
    

    【讨论】:

      【解决方案2】:

      cross apply 中不需要。您可以像这样访问查询中的所有内容。

      select t.v.value('../../../@TName','varchar(100)') TName,
      t.v.value('../@IndexName','varchar(100)') IndexName,
      t.v.value('@ICName','varchar(100)') ICName
      from @x.nodes('TargetDatabaseChanges/Tables/Table/Indexes/Index/IndexColumn') t(v)
      --if you want to filter
      --from @x.nodes('TargetDatabaseChanges/Tables/Table/Indexes/Index[@PrimaryKeyIndex="0"]/IndexColumn') t(v)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多