Select XML 个元素到 SQL 服务器中的 table 行

Select XML elements into table rows in SQL Server

我在 table 中的一行中有如下 XML(table 中有很多行):

<?xml version="1.0" encoding="UTF-8"?>
<AuditTrail>
   <Action />
   <ActionDetail />
   <ChangesXML>
      <Details>
         <Object ObjectType="Data.Review_Extension" AuditType="Modified" FriendlyName="Review">
            <ObjectKeys>
               <ReviewExtID>21482283</ReviewExtID>
            </ObjectKeys>
            <Properties>
               <Property name="Document Type 01" FieldName="Document_Type_01" TemplateFieldID="644140" ReviewExtensionID="214822182" PropertyType="System.String">
                  <OldValue />
                  <NewValue><![CDATA[1145]]></NewValue>
               </Property>
               <Property name="Document Type 02" FieldName="Document_Type_02" TemplateFieldID="644141" ReviewExtensionID="21482283" PropertyType="System.String">
                  <OldValue />
                  <NewValue><![CDATA[123]]></NewValue>
               </Property>
            </Properties>
         </Object>
      </Details>
   </ChangesXML>
</AuditTrail>

我需要编写一个查询(在 SQL Server 2008 中),对于我的源 table 中的每一行,为每个 [=18= 输出一行] XML 中的元素。所以如果我查询上面的记录,我会得到以下结果集:

UserId    Timestamp               PropertyName
-------------------------------------------------
1         1-1-2011 00:11:22:11   Document_Type_01
2         1-1-2011 00:11:22:11   Document_Type_02

我的来源 table 看起来是这样的:

UserId    Timestamp               XML
--------------------------------------
1         1-1-2011 00:11:22:11   <XML>
2         4-1-2011 00:22:33:22   <XML>
3         4-2-2011 00:14:33:22   <XML>

我的第一次尝试是这样的:

SELECT  UserId, Timestamp,
      CAST(AuditXml AS XML).value('(/AuditTrail/ChangesXML/Details/Object/Properties/Property/@FieldName)[1]', 'varchar(50)')  AS PropertyName
FROM  History order by timestamp desc

显然,这仅在有一个 属性 元素且源 table 中每条记录只有 return 一行时才有效。我如何编写此查询才能 return 我要查找的结果集?

查看 OUTER APPLY 运算符并考虑以下示例:

DECLARE @x XML = '<?xml version="1.0" encoding="UTF-8"?>
<AuditTrail>
   <Action />
   <ActionDetail />
   <ChangesXML>
      <Details>
         <Object ObjectType="Data.Review_Extension" AuditType="Modified" FriendlyName="Review">
            <ObjectKeys>
               <ReviewExtID>21482283</ReviewExtID>
            </ObjectKeys>
            <Properties>
               <Property name="Document Type 01" FieldName="Document_Type_01" TemplateFieldID="644140" ReviewExtensionID="214822182" PropertyType="System.String">
                  <OldValue />
                  <NewValue><![CDATA[1145]]></NewValue>
               </Property>
               <Property name="Document Type 02" FieldName="Document_Type_02" TemplateFieldID="644141" ReviewExtensionID="21482283" PropertyType="System.String">
                  <OldValue />
                  <NewValue><![CDATA[123]]></NewValue>
               </Property>
            </Properties>
         </Object>
      </Details>
   </ChangesXML>
</AuditTrail>'

DECLARE @t TABLE (userid INT, [xml] XML)
INSERT @t VALUES(1, @x)

SELECT t.userid, r.z.value('@FieldName', 'nvarchar(MAX)')
FROM @t t
OUTER APPLY t.xml.nodes('//Property') as r(z) 

希望对您有所帮助