sql - 在SQL Server中将XML元素选择到表行中

标签 sql xml tsql xpath xquery

我在表中的一行中有如下所示的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>


我需要编写一个查询(在SQL Server 2008中),对于源表中的每一行,该查询将为XML中的EACH Property元素输出一行。因此,如果我查询上面的记录,则会得到以下结果集:

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


我的源表如下所示:

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


显然,这仅在只有一个property元素的情况下有效,并且在源表中每条记录仅返回一行。如何编写此查询,使其返回我要查找的结果集?

最佳答案

看一下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) 


希望能帮助到你

关于sql - 在SQL Server中将XML元素选择到表行中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30471049/

相关文章:

mysql - 当我尝试使用大于聚合时出现错误代码 1064

php - 如何使用触发器在SQL中递增?

php - Magento 管理菜单 block 未显示在配置选项卡中?

php - 无法使用 php 从 mysql 显示 XML 数据

java - 使用 Spring MVC 的 XML View

sql - 插入/更新/删除记录会自动更新索引吗?

mysql - 找不到父 key 解决方法

sql - Oracle - 如何使用 FAST REFRESH 和 JOINS 创建物化 View

sql - 删除早于 N 天的记录的存储过程

sql - 使用 DateDiff 查找持续时间(以分钟为单位)