XQuery交叉应用返回额外的记录

时间:2016-09-28 18:01:27

标签: sql-server xquery cross-apply

我在XML列中有以下结构。它应该show stored procedures并列出下面的used tables and columns

显示额外记录。请参阅以下结构和查询:

CREATE TABLE #T (
    ID  int primary key, 
    MetaData xml
)

insert into #T values(1,
'<root>
    <object name="myProc">
        <tables>
            <table database="LynxReporting" schema="Secure" name="factPortCore">
                <columns>
                    <column name="SnapshotKey"/>
                    <column name="SnapshotDt"/>
                </columns>
            </table>
            <table database="LynxSnapshot" schema="dbo" name="Loan">
                <columns>
                    <column name="LoanProgId"/>
                    <column name="FinType"/>
                </columns>
            </table>
            <table database="LynxReporting" schema="dbo" name="dimGLSrcSysId">
                <columns>
                    <column name="GLSrcSysId"/>
                </columns>
            </table>
        </tables>
    </object>
    <object name="usp_Recon">
        <tables>
            <table database="LynxReporting" schema="Secure" name="dimAppSysId">
                <columns>
                    <column name="AppSysId"/>
                    <column name="AppSysIdLongDesc"/>
                </columns>
            </table>
        </tables>
    </object>
</root>')

SELECT
    t.x.value('@name', 'varchar(max)') as TableName
    , c.x.value('@name', 'varchar(max)') as ColumnName
FROM #T
    CROSS APPLY MetaData.nodes('root/object/tables/table') as t(x)
    CROSS APPLY MetaData.nodes('root/object/tables/table/columns/column') as c(x)
order by 1,2

我得到了什么(你看到不相关的行):

╔═══════════════╦══════════════════╗
║ TableName     ║ ColumnName       ║
╠═══════════════╬══════════════════╣
║ Loan          ║ AppSysId         ║
╠═══════════════╬══════════════════╣
║ Loan          ║ AppSysIdLongDesc ║
╠═══════════════╬══════════════════╣
║ Loan          ║ FinType          ║
╠═══════════════╬══════════════════╣
║ Loan          ║ GLSrcSysId       ║
╠═══════════════╬══════════════════╣
║ Loan          ║ LoanProgId       ║
╠═══════════════╬══════════════════╣
║ Loan          ║ SnapshotDt       ║
╠═══════════════╬══════════════════╣
║ Loan          ║ SnapshotKey      ║
╠═══════════════╬══════════════════╣
║ dimAppSysId   ║ AppSysId         ║
╠═══════════════╬══════════════════╣
║ dimAppSysId   ║ AppSysIdLongDesc ║
╠═══════════════╬══════════════════╣
║ dimAppSysId   ║ FinType          ║
╠═══════════════╬══════════════════╣
║ dimAppSysId   ║ GLSrcSysId       ║
╠═══════════════╬══════════════════╣
║ dimAppSysId   ║ LoanProgId       ║
╠═══════════════╬══════════════════╣
║ dimAppSysId   ║ SnapshotDt       ║
╠═══════════════╬══════════════════╣
║ dimAppSysId   ║ SnapshotKey      ║
╠═══════════════╬══════════════════╣
║ dimGLSrcSysId ║ AppSysId         ║
╠═══════════════╬══════════════════╣
║ dimGLSrcSysId ║ AppSysIdLongDesc ║
╠═══════════════╬══════════════════╣
║ dimGLSrcSysId ║ FinType          ║
╠═══════════════╬══════════════════╣
║ dimGLSrcSysId ║ GLSrcSysId       ║
╠═══════════════╬══════════════════╣
║ dimGLSrcSysId ║ LoanProgId       ║
╠═══════════════╬══════════════════╣
║ dimGLSrcSysId ║ SnapshotDt       ║
╠═══════════════╬══════════════════╣
║ dimGLSrcSysId ║ SnapshotKey      ║
╠═══════════════╬══════════════════╣
║ factPortCore  ║ AppSysId         ║
╠═══════════════╬══════════════════╣
║ factPortCore  ║ AppSysIdLongDesc ║
╠═══════════════╬══════════════════╣
║ factPortCore  ║ FinType          ║
╠═══════════════╬══════════════════╣
║ factPortCore  ║ GLSrcSysId       ║
╠═══════════════╬══════════════════╣
║ factPortCore  ║ LoanProgId       ║
╠═══════════════╬══════════════════╣
║ factPortCore  ║ SnapshotDt       ║
╠═══════════════╬══════════════════╣
║ factPortCore  ║ SnapshotKey      ║
╚═══════════════╩══════════════════╝

我想要的是什么:

╔════════════╦═══════════════╦══════════════════╗
║ ObjectName ║ TableName     ║ ColumnName       ║
╠════════════╬═══════════════╬══════════════════╣
║ myProc     ║ Loan          ║ FinType          ║
╠════════════╬═══════════════╬══════════════════╣
║ myProc     ║ Loan          ║ LoanProgId       ║
╠════════════╬═══════════════╬══════════════════╣
║ usp_Recon  ║ dimAppSysId   ║ AppSysId         ║
╠════════════╬═══════════════╬══════════════════╣
║ usp_Recon  ║ dimAppSysId   ║ AppSysIdLongDesc ║
╠════════════╬═══════════════╬══════════════════╣
║ myProc     ║ dimGLSrcSysId ║ GLSrcSysId       ║
╠════════════╬═══════════════╬══════════════════╣
║ myProc     ║ factPortCore  ║ SnapshotDt       ║
╠════════════╬═══════════════╬══════════════════╣
║ myProc     ║ factPortCore  ║ SnapshotKey      ║
╚════════════╩═══════════════╩══════════════════╝

如您所见,我还希望获得ObjectName列。 我不知道应该如何更改查询。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

交叉应用上一组

中的值
SELECT
    r.o.value('@name', 'varchar(max)') as ObjectName
    , t.x.value('@name', 'varchar(max)') as TableName
    , c.x.value('@name', 'varchar(max)') as ColumnName
FROM #T
    CROSS APPLY MetaData.nodes('root/object') as r(o)
    CROSS APPLY r.o.nodes('tables/table') as t(x)
    CROSS APPLY t.x.nodes('columns/column') as c(x)