3

我正在尝试从同一个查询中查询一个表以及该表的 XML 列之一的内容。

我的表模式基本上如下:

CREATE TABLE AuditLogs
(
    [AuditLogId] INT, 
    [ObjectType] VARCHAR(50), 
    [Action] VARCHAR(50), 
    [ObjectId] INT, 
    [Changes] XML
);

与 XML 中的Changes列类似:

<ArrayOfChange>
    <Change FieldName="ItemStatus">
        <OldValue>Unreconciled</OldValue>
        <NewValue>Reconciled</NewValue>
    </Change>
    <Change FieldName="Amount">
        <OldValue>50.00</OldValue>
        <NewValue>45.00</NewValue>
    </Change>
</ArrayOfChange>

最后,我渴望的结果是:

AuditLogId
Action
ObjectType
ObjectId
FieldName
OldValue
NewValue

在真正的 StackOverflow 传统中,我自己对此进行了一些尝试,取得了一些进展,我想我快到了,只是错过了一些东西。我遇到的问题是 OldValue 和 NewValue 列始终为空。

我的最新版本是:

SELECT
    [AuditLogId],
    [Action],
    [ObjectType],
    [ObjectId],
    c.n.value('@FieldName', 'varchar(50)') AS FieldName,
    c.n.value('(OldValue)[0]', 'varchar(50)') AS OldValue,
    c.n.value('(NewValue)[0]', 'varchar(50)') AS NewValue
FROM TMP
    CROSS APPLY [Changes].nodes('/ArrayOfChange/Change') c(n)

现在,我创建了一个SQLFiddle来让生活更轻松。

4

1 回答 1

2

你的 xpath 让你失望了。

改变

c.n.value('(OldValue)[0]', 'varchar(50)') AS OldValue,
c.n.value('(NewValue)[0]', 'varchar(50)') AS NewValue

c.n.value('OldValue[1]', 'varchar(50)') AS OldValue,
c.n.value('NewValue[1]', 'varchar(50)') AS NewValue

Xpath 是基于 1 的(这篇博文中有很多关于这个主题的想法);并且您不需要带有如此简单路径表达式的括号(它们是允许的,但在这里是不必要的)。

于 2013-05-24T15:23:36.397 回答