我有一个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
的正确索引。
如何限制此关联?
答案 0 :(得分:0)
想出来......万一其他人需要帮助......
我更改了最后一个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 the
FROM`子句,如下所示:
`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)`
答案 1 :(得分:0)
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)