sqlserver 操作xml

【参考文档】

xml的核心操作~~~官网(必看):https://docs.microsoft.com/zh-cn/sql/t-sql/xml/xml-data-type-methods?view=sql-server-ver15

xquery:https://docs.microsoft.com/zh-cn/sql/xquery/xquery-language-reference-sql-server?view=sql-server-ver15

参考引用:https://www.cnblogs.com/a14907/p/6084526.html

【XML与表格的互相转换】

【0】转换成表格

declare @temp xml;
set @temp='<root><note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Dont forget the meeting!</body>
</note>
<note>
<to>tom</to>
<from>cat</from>
<heading>test</heading>
<body>test 123</body>
</note>
</root>';
select [to]=o.value('to[1]','nvarchar(500)'),
               [from]=o.value('from[1]','nvarchar(500)'),
               [heading]=o.value('heading[1]','nvarchar(500)'),
               [body]=o.value('body[1]','nvarchar(500)')               
             from (select x=@temp) a
             cross apply x.nodes('root/note') x(o) 

  

【1】xml测试数据

<event name="sql_batch_completed" package="sqlserver" timestamp="2020-08-19T06:41:42.542Z">
  <data name="cpu_time">
    <value>141000</value>
  </data>
  <data name="duration">
    <value>2947856</value>
  </data>
  <data name="physical_reads">
    <value>12517</value>
  </data>
  <data name="logical_reads">
    <value>10411</value>
  </data>
  <data name="writes">
    <value>0</value>
  </data>
  <data name="row_count">
    <value>0</value>
  </data>
  <data name="result">
    <value>2</value>
    <text>Abort</text>
  </data>
  <data name="batch_text">
    <value>SELECT  * FROM match_nndouble </value>
  </data>
  <action name="task_time" package="sqlos">
    <value>28573288</value>
  </action>
  <action name="database_name" package="sqlserver">
    <value>test</value>
  </action>
  <action name="nt_username" package="sqlserver">
    <value>WIN-OFM2A36CRMD\admin</value>
  </action>
  <action name="sql_text" package="sqlserver">
    <value>SELECT  * FROM match_nndouble </value>
  </action>
  <action name="transaction_id" package="sqlserver">
    <value>0</value>
  </action>
  <action name="username" package="sqlserver">
    <value>WIN-OFM2A36CRMD\admin</value>
  </action>
</event>

【2】xml转换成表格形式查看

with d as (
SELECT CONVERT(XML,event_data) AS data
from sys.Fn_xe_file_target_read_file(N'E:\dba_tools\eventlog\slow_query_0_132422809173040000.xel',NULL,NULL,NULL)
)
select
data.value('(/event/@timestamp)[1]','datetime') as record_time, --获取最上方标题行的内容
data.value('(/event/@name)[1]','nvarchar(128)') as operation_name, --获取最上方标题行的内容
--data.value('(/event/data[@name="cpu_time"]/value)[1]','int')/1000 as 'cpu_time(ms)',--获得 event=>data name=cpu_time 的 value
data.value('(/event/data[@name="duration"]/value)[1]','int')/1000 as 'exec_time(ms)',--获得 event=>data name=duration 的 value
--data.value('(/event/data[@name="physical_reads"]/value)[1]','int') as 'physical_reads',--获得 event=>data name=physical_reads 的 value
--data.value('(/event/data[@name="logical_reads"]/value)[1]','int') as 'logical_reads',--获得 event=>data name=logical_reads 的 value
--data.value('(/event/data[@name="writes"]/value)[1]','int') as 'writes',--获得 event=>data name=writes 的 value
data.value('(/event/data[@name="row_count"]/value)[1]','int') as 'row_count',--获得 event=>data name=row_count 的 value
data.value('(/event/data[@name="result"]/value)[1]','int') as 'result_flag',--获得 event=>data name=result 的 value
data.value('(/event/data[@name="result"]/text)[1]','nvarchar(128)') as 'result_desc',--获得 event=>data name=result 的 text
data.value('(/event/data[@name="batch_text"]/value)[1]','nvarchar(max)') as 'batch_text',--获得 event=>data name=batch_text 的 text

data.value('(/event/action[@name="sql_text"]/value)[1]','nvarchar(4000)') as 'current_sql',--获得 event=>action name=sql_text 的 value
--data.value('(/event/action[@name="task_time"]/value)[1]','int')/1000 as 'task_time(ms)',--获得 event=>action name=task_time 的 value
data.value('(/event/action[@name="database_name"]/value)[1]','nvarchar(400)') as 'database_name',--获得 event=>action name=database_name 的 value
data.value('(/event/action[@name="transaction_id"]/value)[1]','nvarchar(400)') as 'transaction_id',--获得 event=>action name=transaction_id 的 value
data.value('(/event/action[@name="username"]/value)[1]','nvarchar(400)') as 'username',--获得 event=>action name=transaction_id 的 value
data.value('(/event/action[@name="nt_username"]/value)[1]','nvarchar(400)') as 'nt_username'--获得 event=>action name=transaction_id 的 value
from d

 

结果:

  

 

 

 

XML本身的5大操作

1.xml.exist 
   输入为XQuery表达式,返回0,1或是Null。0表示不存在,1表示存在,Null表示输入为空 
2.xml.value 
   输入为XQuery表达式,返回一个SQL Server标量值 
3.xml.query 
   输入为XQuery表达式,返回一个SQL Server XML类型流 
4.xml.nodes 
   输入为XQuery表达式,返回一个XML格式文档的一列行集 
5.xml.modify 
   使用XQuery表达式对XML的节点进行insert , update 和 delete 操作。

下面通过例子对上面的五种操作进行说明:

测试数据

declare @XMLVar xml = '

<catalog> 

       <book category="ITPro">   
              <title>Windows Step By Step</title>   
              <author>Bill Zack</author>   
              <price>49.99</price> 
       </book> 

       <book category="Developer">   
              <title>Developing ADO .NET</title>   
              <author>Andrew Brust</author>   
              <price>39.93</price> 
       </book> 

       <book category="ITPro">   
              <title>Windows Cluster Server</title>   
              <author>Stephen Forte</author>   
              <price>59.99</price> 
       </book>

</catalog>'

 

1.xml.exist

   select @XMLVar.exist('/catalog/book')-----返回1  

   select @XMLVar.exist('/catalog/book/@category')-----返回1  

   select @XMLVar.exist('/catalog/book1')-----返回0  

   set @XMLVar = null  

   select @XMLVar.exist('/catalog/book')-----返回null

2.xml.value

   select @XMLVar.value('/catalog[1]/book[1]','varchar(MAX)')  

   select @XMLVar.value('/catalog[1]/book[2]/@category','varchar(MAX)')  

   select @XMLVar.value('/catalog[2]/book[1]','varchar(MAX)')  

   结果集为:  

   Windows Step By StepBill Zack49.99  

  Developer  

  NULL

3.xml.query

 select @XMLVar.query('/catalog[1]/book')   

   select @XMLVar.query('/catalog[1]/book[1]')  

   select @XMLVar.query('/catalog[1]/book[2]/author')

   结果集分别为: 
<book category="ITPro"> 
  <title>Windows Step By Step</title> 
  <author>Bill Zack</author> 
  <price>49.99</price> 
</book> 
<book category="Developer"> 
  <title>Developing ADO .NET</title> 
  <author>Andrew Brust</author> 
  <price>39.93</price> 
</book> 
<book category="ITPro"> 
  <title>Windows Cluster Server</title> 
  <author>Stephen Forte</author> 
  <price>59.99</price> 
</book>


<book category="ITPro"> 
  <title>Windows Step By Step</title> 
  <author>Bill Zack</author> 
  <price>49.99</price> 
</book>


<author>Andrew Brust</author>

 

4.xml.nodes

   select T.c.query('.') as result from @XMLVar.nodes('/catalog/book') as T(c)  

   select T.c.query('title') as result from @XMLVar.nodes('/catalog/book') as T(c)

   结果集分别为:

<book category="ITPro"><title>Windows Step By Step</title><author>Bill …………

<book category="Developer"><title>Developing ADO .NET</title><author>Andrew …………
<book category="ITPro"><title>Windows Cluster Server</title><author>Stephen …………


<title>Windows Step By Step</title>
<title>Developing ADO .NET</title>
<title>Windows Cluster Server</title>

 5.xml.modify

SQL Server 2005/2008增加了对XML数据的支持,同时也新增了几种操作XML的方法,本文主要以SQL Server 2008为例介绍如何对XML数据进行insert、update、delete。

      SQL Server中新增加了XML.Modify()方法,分别为xml.modify(insert),xml.modify(delete),xml.modify(replace)对应XML的插入,删除和修改操作。

      本文以下面XML为例,对三种DML进行说明:

declare @XMLVar xml = '
<catalog>
  <book category="ITPro">
    <title>Windows Step By Step</title>
    <author>Bill Zack</author>
    <price>49.99</price>
  </book>
  <book category="Developer">
    <title>Developing ADO .NET</title>
    <author>Andrew Brust</author>
    <price>39.93</price>
  </book>
  <book category="ITPro">
    <title>Windows Cluster Server</title>
    <author>Stephen Forte</author>
    <price>59.99</price>
  </book>
</catalog>
'

 

深入 XML.Modify

1.XML.Modify(Insert)语句介绍

A.利用as first,at last,before,after 四个参数将元素插入指定的位置

set @XMLVar.modify(
    'insert <first name="at first" /> as first into (/catalog[1]/book[1])')
set @XMLVar.modify(
    'insert <last name="at last"/> as last into (/catalog[1]/book[1])')
set @XMLVar.modify(
    'insert <before name="before"/> before (/catalog[1]/book[1]/author[1])')
set @XMLVar.modify(
    'insert <after name="after"/> after (/catalog[1]/book[1]/author[1])')
SELECT @XMLVar.query('/catalog[1]/book[1]');

 

结果集为:

   1:  <book category="ITPro">
   2:    <first name="at first" />
   3:    <title>Windows Step By Step</title>
   4:    <before name="before" />
   5:    <author>Bill Zack</author>
   6:    <after name="after" />
   7:    <price>49.99</price>
   8:    <last name="at last" />
   9:  </book>

 

B.将多个元素插入文档中

--方法一:利用变量进行插入
DECLARE @newFeatures xml;
SET @newFeatures = N';        
<first>one element</first>          
<second>second element</second>'
SET @XMLVar.modify('           )      
insert sql:variable("@newFeatures")           
into (/catalog[1]/book[1])'

 

--方法二:直接插入 
set @XMLVar.modify(')
insert (<first>one element</first>,<second>second element</second>) 
into (/catalog[1]/book[1]/author[1])'
SELECT @XMLVar.query('/catalog[1]/book[1]');
结果集为:
  1:  <book category="ITPro">
   2:    <title>Windows Step By Step</title>
   3:    <author>Bill Zack
   4:      <first>one element</first>
   5:      <second>second element</second>
   6:    </author>
   7:    <price>49.99</price>
   8:    <first>one element</first>
   9:    <second>second element</second>
  10:  </book>

 

C.将属性插入文档中

--使用变量插入
declare @var nvarchar(10) = '变量插入'
set @XMLVar.modify(
'insert (attribute var {sql:variable("@var")}))
into (/catalog[1]/book[1])'
--直接插入
set @XMLVar.modify(
'insert (attribute name {"直接插入"}))
into (/catalog[1]/book[1]/title[1])'
--多值插入
set @XMLVar.modify(
'insert (attribute Id {"多值插入1"},attribute name {"多值插入2"}) )
into (/catalog[1]/book[1]/author[1])'
SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:

   1:  <book category="ITPro" var="变量插入">
   2:    <title name="直接插入">Windows Step By Step</title>
   3:    <author Id="多值插入1" name="多值插入2">Bill Zack</author>
   4:    <price>49.99</price>
   5:  </book>

 

D.插入文本节点

set @XMLVar.modify(
'insert text{"at first"} as first)
into (/catalog[1]/book[1])'
SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:

 1:  <book category="ITPro">
   2:    at first
   3:    <title>Windows Step By Step</title>
   4:    <author>Bill Zack</author>
   5:    <price>49.99</price>
   6:  </book>

注意:插入本文同样具体 as first,as last,before,after四种选项,可以参考A中的使用方法

 

E.插入注释节点

set @XMLVar.modify(
'insert <!--插入评论-->)
before (/catalog[1]/book[1]/title[1])'
SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:

 1:  <book category="ITPro">
   2:    <!--插入评论-->
   3:    <title>Windows Step By Step</title>
   4:    <author>Bill Zack</author>
   5:    <price>49.99</price>
   6:  </book>
注意插入注释节点同样具体 as first,as last,before,after四种选项,可以参考A中的使用方法

F.插入处理指令

set @XMLVar.modify(
'insert <?Program "Instructions.exe" ?>)
before (/catalog[1]/book[1]/title[1])'
SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:
   1:  <book category="ITPro">
   2:    <?Program "Instructions.exe" ?>
   3:    <title>Windows Step By Step</title>
   4:    <author>Bill Zack</author>
   5:    <price>49.99</price>
   6:  </book>
注意插入处理指令同样具体 as first,as last,before,after四种选项,可以参考A中的使用方法

G.根据 if 条件语句进行插入 

set @XMLVar.modify(
'insert )
if (/catalog[1]/book[1]/title[2]) then
    text{"this is a 1 step"}
else ( text{"this is a 2 step"} )
    into (/catalog[1]/book[1]/price[1])'
SELECT @XMLVar.query('/catalog[1]/book[1]');

 

结果集为:
   1:  <book category="ITPro">
   2:    <title>Windows Step By Step</title>
   3:    <author>Bill Zack</author>
   4:    <price>49.99this is a 2 step</price>
   5:  </book>
 

2.XML.Modify(delete)语句介绍

--删除属性
set @XMLVar.modify('delete /catalog[1]/book[1]/@category')
--删除节点
set @XMLVar.modify('delete /catalog[1]/book[1]/title[1]')
--删除内容
set @XMLVar.modify('delete /catalog[1]/book[1]/author[1]/text()')
--全部删除
set @XMLVar.modify('delete /catalog[1]/book[2]')
 
SELECT @XMLVar.query('/catalog[1]');

 

结果集为:

   1:  <catalog>
   2:    <book>
   3:      <author />
   4:      <price>49.99</price>
   5:    </book>
   6:    <book category="ITPro">
   7:      <title>Windows Cluster Server</title>
   8:      <author>Stephen Forte</author>
   9:      <price>59.99</price>
  10:    </book>
  11:  </catalog>

 

3.XML.Modify(replace)语句介绍

--替换属性
set @XMLVar.modify('replace value of(/catalog[1]/book[1]/@category))
 with ("替换属性")'
--替换内容
set @XMLVar.modify('replace value of(/catalog[1]/book[1]/author[1]/text()[1]))
 with("替换内容")'
--条件替换
set @XMLVar.modify('replace value of (/catalog[1]/book[2]/@category))
with( 
if(count(/catalog[1]/book)>4) then
    "条件替换1"
else
    "条件替换2")'
 
SELECT @XMLVar.query('/catalog[1]');
 
结果集为:

   1:  <catalog>
   2:    <book category="替换属性">
   3:      <title>Windows Step By Step</title>
   4:      <author>替换内容</author>
   5:      <price>49.99</price>
   6:    </book>
   7:    <book category="条件替换2">
   8:      <title>Developing ADO .NET</title>
   9:      <author>Andrew Brust</author>
  10:      <price>39.93</price>
  11:    </book>
  12:    <book category="ITPro">
  13:      <title>Windows Cluster Server</title>
  14:      <author>Stephen Forte</author>
  15:      <price>59.99</price>
  16:    </book>
  17:  </catalog>



[案例]【sql server使用T-SQL读取扩展事件

sql server使用T-SQL读取扩展事件

 
posted @ 2018-05-30 11:21  郭大侠1  阅读(2352)  评论(0编辑  收藏  举报