SqlServer XML数据类型DML相关操作(图文结合)

XML操作很少用到,最近查询个语句,还得到官网查看用法。所以按照官方把相关的DML都操作一遍,作为记录!~

--  测试数据
--  DROP TABLE #XMLTab
CREATE TABLE #XMLTab(colxml XML)
GO
INSERT INTO #XMLTab
SELECT N'
<Record dt="2015-05-05">
  <Exception type="RING_BUFFER_EXCEPTION">
    <Task address="0x0062B8E8" />
    <Error>9003</Error>
    <Severity>error</Severity>
  </Exception>
  <Exception type="BUFFER_EXCEPTION">
    <Task address="0xC452BB39" />
    <Error>8008</Error>
    <Severity>true</Severity>
    <Other>00</Other>
  </Exception>
</Record>'
GO
INSERT INTO #XMLTab
SELECT N'
<p1:Record dt="2015-05-06" xmlns:p1="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">
  <p1:Exception type="RING_BUFFER_EXCEPTION">
    <p1:Task address="0x0062B8E8" />
    <p1:Error>9003</p1:Error>
    <p1:Severity>error</p1:Severity>
  </p1:Exception>
  <p1:Exception type="BUFFER_EXCEPTION">
    <p1:Task address="0xC452BB39" />
    <p1:Error>8008</p1:Error>
    <p1:Severity>true</p1:Severity>
	<p1:Other>00</p1:Other>
  </p1:Exception>
</p1:Record>'
GO 

‘XML 数据修改语言 (XML DML)‘

--节点插入

insert Expression1({asfirst
| as
last} into
| after|
before Expression2
)

--删除XML实例的节点

delete Expression

--在文档中更新节点的值

replace
value of Expression1with
Expression2

--	在根路径"/Record/"的第一个"/Exception"下,添加删除一个元素"<Address>".还可以使用{as first | as last}指定位置
UPDATE #XMLTab SET colxml.modify('insert <Address>insert test 1</Address> into (/Record/Exception)[1]');
UPDATE #XMLTab SET colxml.modify('insert <Address>insert test 1</Address> as first into (/Record/Exception)[1]');

--	删除所有元素"Address"
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception[1]/Address');
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception[1]/Address[1]');

--	在根路径"/Record/"的第二个"/Exception"下,添加删除一个元素"<Address>"
UPDATE #XMLTab SET colxml.modify('insert <Address>insert test 1</Address> into (/Record/Exception)[2]');

--	删除第二个节点"/Exception"下的所有元素"Address"
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception[2]/Address');
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception[2]/Address[1]');
--	删除"/Record/Exception/"下的第2个元素(即在Exception中第二行的删除)
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception/*[2]')
--	删除所有路径"/Record/Exception"下的元素"<Address>"
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception/Address[1]');
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception/Address');

各种路径表达式都指定“[1]”或者“[2]”等,要求每次只返回单个目标。

在重新删除创建测试表

--	插入一个元素变量(连续执行4次,方便下面测试)
DECLARE @newFeatures xml;
SET @newFeatures = N'<Address></Address>'

UPDATE #XMLTab SET colxml.modify('insert sql:variable("@newFeatures") into (/Record/Exception)[1]');

--	插入一个属性到元素"<Address />"(接上步操作)(多个元素相同,以Address[1]/[2]/[3]/[4]区分)
UPDATE #XMLTab SET colxml.modify('insert attribute attrName {"attributeA" } into (/Record/Exception/Address[1])[1]');
UPDATE #XMLTab SET colxml.modify('insert attribute attrName {"attributeB" } into (/Record/Exception/Address[2])[1]');
UPDATE #XMLTab SET colxml.modify('insert attribute attrName {"attributeA" } into (/Record/Exception/Address[3])[1]');
UPDATE #XMLTab SET colxml.modify('insert attribute attrName {"attributeB" } into (/Record/Exception/Address[4])[1]');

--	插入一个属性到元素"<Address />",其中条件为[attrName="attributeB"],(每个元素以Address[1]/[2]/[3]/[4]区分)
UPDATE #XMLTab SET colxml.modify('
	insert attribute attrName2 {"0.5" }
	into (/Record/Exception/Address[4][@attrName="attributeB"])[1]');--成功:第四个Address,attrName="attributeB"

UPDATE #XMLTab SET colxml.modify('
	insert attribute attrName3 {"0.5" }
	into (/Record/Exception/Address[4][@attrName="attributeA"])[1]');--失败:第四个Address,attrName<>"attributeA"

--	删除路径"/Record/Exception/Address"中"Address"的属性"attrName"(所有)
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception/Address/@attrName');
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception/Address/@attrName2');

--	变量插入属性值
DECLARE @Hrs FLOAT
SET @Hrs =0.5

UPDATE #XMLTab SET colxml.modify('insert attribute attrName {sql:variable("@Hrs")} into (/Record/Exception/Task)[1]');

--	插入多个属性值
UPDATE #XMLTab SET colxml.modify('
insert (
	attribute attrName2 {"0.5" },
	attribute attrName3 {".2"}
	)
into (/Record/Exception/Task)[1]');

--	插入注释元素(在第3个Address后插入)
UPDATE #XMLTab SET colxml.modify('insert <!-- some comment --> after (/Record/Exception/Address[3])[1]');

--	使用"before"在跟目录前(头部)插入处理指令
UPDATE #XMLTab SET colxml.modify('insert <?Program = "Instructions.exe" ?> before (/Record)[1]');

--	还可以利用"after" 和 "before" 的方法插入一个元素
UPDATE #XMLTab SET colxml.modify('insert <Address></Address> after (/Record/Exception/Address[1])[1]');
UPDATE #XMLTab SET colxml.modify('insert <Address></Address> before (/Record/Exception/Address[1])[1]');

--	添加删除文本(添加文本后,该元素格式显示成一行)
UPDATE #XMLTab SET colxml.modify('insert text{"Product Catalog Description"} as first into (/Record/Exception)[1]');

--	删除后查看,格式正常
UPDATE #XMLTab SET colxml.modify('delete /Record/Exception/text()');

--	以下为添加后的格式

--	按条件更改增加属性:
--如果"/Record/Exception/Address[3]"的属性attrName="attributeB",则增加属性attrName="10",否则增加属性attrName="50"
UPDATE #XMLTab SET colxml.modify('
insert
if (/Record/Exception/Address[3][@attrName="attributeB"])
	then attribute attrName {"10"}
else
	attribute attrName {"50"}
as first into (/Record/Exception/Address[3])[1] ');

--	将元素"<Error>9003</Error>"中的文本值"9003"改为"10000"()
UPDATE #XMLTab SET colxml.modify('replace value of (/Record/Exception/Error[1]/text())[1] with "10000" ');

--	将元素"Task"的属性"address"的值改为"100"
UPDATE #XMLTab SET colxml.modify('replace value of (/Record/Exception/Task/@address)[1] with "100" ');
UPDATE #XMLTab SET colxml.modify('replace value of (/Record/Exception/Task[1]/@address)[2] with "999" ');

--如果/Record/路径下第一个Exception中,元素Address个数大于3,则更新Exception[1]属性type为"10.0"否则为"20.0"
UPDATE #XMLTab SET colxml.modify('
  replace value of (/Record/Exception[1]/@type)[1]
  with (
       if (count(/Record/Exception[1]/Address) > 3) then "10.0"
       else "20.0"
  )');

-------------------------------------------------------------------------------------

以下为XML相关查询

-------------------------------------------------------------------------------------

--	查询某个元素中的所有所有子项
SELECT colxml.query('/Record/Exception') FROM #XMLTab

SELECT colxml.query('//Record/Exception/Address') FROM #XMLTab
--图为第二个查询语句的结果

--	元素带前缀的查询.之前在临时表插入的第二行数据,现在有用了!~
SELECT colxml.query('
declare namespace p1="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/p1:Record/p1:Exception')
FROM #XMLTab

--	条件查询用,如果在 exist() 方法中指定 true() 或 false() 函数,则总是返回 1
SELECT colxml FROM #XMLTab WHERE colxml.exist('true()')=1
SELECT colxml FROM #XMLTab WHERE colxml.exist('false()')=1
--	查看节点"/Record"的属性"@dt"日期是否为"2015-05-05"
--	元素中的属性转换为日志比较(也可以作为查询条件的判断)
--	参考构造函数:https://msdn.microsoft.com/zh-cn/library/ms189547.aspx
SELECT colxml
,colxml.exist('/Record[(@dt cast as xs:date?) eq xs:date("2015-05-05")]')
,colxml.exist('/Record[(@dt cast as xs:date?) eq xs:date("2015-05-10")]')
FROM #XMLTab

--	文本判断:"/Record/Exception/Error"中的文本,只要其中一个符合就返回"1"
SELECT colxml
,colxml.exist('/Record/Exception/Error[(text()[1] cast as xs:string ?) = xs:string("9003") ]')
,colxml.exist('/Record/Exception/Error[(text()[1] cast as xs:string ?) = xs:string("8008") ]')
,colxml.exist('/Record/Exception[1]/Error[(text()[1] cast as xs:string ?) = xs:string("9003") ]')
,colxml.exist('/Record/Exception[2]/Error[(text()[1] cast as xs:string ?) = xs:string("8008") ]')
FROM #XMLTab 

--	带前缀的查询方法
SELECT colxml
,colxml.exist('
	declare namespace p1="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
	/p1:Record/p1:Exception/p1:Error[(text()[1] cast as xs:string ?) = xs:string("9003") ]')
,colxml.exist('
	declare namespace p1="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
	/p1:Record/p1:Exception/p1:Error[(text()[1] cast as xs:string ?) = xs:string("8008") ]')
,colxml.exist('
	declare namespace p1="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
	/p1:Record/p1:Exception[1]/p1:Error[(text()[1] cast as xs:string ?) = xs:string("9003") ]')
,colxml.exist('
	declare namespace p1="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
	/p1:Record/p1:Exception[2]/p1:Error[(text()[1] cast as xs:string ?) = xs:string("8008") ]')
FROM #XMLTab 
--	还可以简写为:
WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS p1)
SELECT colxml
,colxml.exist('/p1:Record/p1:Exception/p1:Error[(text()[1] cast as xs:string ?) = xs:string("9003") ]')
,colxml.exist('/p1:Record/p1:Exception/p1:Error[(text()[1] cast as xs:string ?) = xs:string("8008") ]')
,colxml.exist('/p1:Record/p1:Exception[1]/p1:Error[(text()[1] cast as xs:string ?) = xs:string("9003") ]')
,colxml.exist('/p1:Record/p1:Exception[2]/p1:Error[(text()[1] cast as xs:string ?) = xs:string("8008") ]')
FROM #XMLTab
--	元素判断:元素中的其他元素是否存在.为1则是该节点中不包含的.
SELECT colxml
,colxml.exist('/Record/Exception[1][not(Other)]') --1:元素"Exception[1]"不包含元素"Other"
,colxml.exist('/Record/Exception[2][not(Other)]') --0:元素"Exception[2]"包含元素"Other"
,colxml.exist('
	declare namespace p1="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
	/p1:Record/p1:Exception[1][not(p1:Other)]')  --1:元素"p1:Exception[1]"不包含元素"p1:Other"
,colxml.exist('
	declare namespace p1="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
	/p1:Record/p1:Exception[2][not(p1:Other)]')  --0:元素"p1:Exception[2]"包含元素"p1:Other"
FROM #XMLTab

--	使用"value"查询属性值和元素文本值
SELECT
 colxml.value('(/Record/Exception/Task/@address)[1]','varchar(100)') AS [address1]
,colxml.value('(/Record/Exception[2]/Task/@address)[1]','varchar(100)') AS [address2]
,colxml.value('data(/Record/Exception[1]/Error)[1]','int') AS [Error1]
,colxml.value('data(/Record/Exception[2]/Error)[1]','int') AS [Error2]
,colxml.value('
	declare namespace p1="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
	data(/p1:Record/p1:Exception[2]/p1:Error)[1]
	','int') AS [p1:Error2]
FROM #XMLTab 

--	使用"query"查询属性值
SELECT
 CONVERT(NVARCHAR(100),colxml.query('data(/Record/@dt)')) AS [id]
,CONVERT(NVARCHAR(100),colxml.query('data(/Record/Exception/@type)[1]')) AS [type1]
,CONVERT(NVARCHAR(100),colxml.query('data(/Record/Exception/@type)[2]')) AS [type2]
,CONVERT(NVARCHAR(100),colxml.query('data(/Record/Exception[2]/@type)[1]')) AS [type2]
,CONVERT(NVARCHAR(100),colxml.query('data(/Record/Exception/@type)')) AS [type1 type2]
FROM #XMLTab

--	可以当做查询条件:
SELECT * FROM #XMLTab WHERE CONVERT(NVARCHAR(100),colxml.query('data(/Record/@dt)'))='2015-05-05'
--	使用"nodes"中"value"查询属性值和元素文本值
SELECT node.c1.query('data(/Record/@dt)')
,CONVERT(NVARCHAR(100),colxml.query('data(/Record/@dt)')) AS [id]
,node.c1.value('(@dt)','VARCHAR(50)') AS [id]
,node.c1.value('(@dt)[1]','VARCHAR(50)') AS [id]
,node.c1.value('(Exception/@type)[1]','VARCHAR(50)') AS [type1]
,node.c1.value('(Exception/Error)[1]','VARCHAR(50)') AS [Error1]
FROM #XMLTab
CROSS APPLY colxml.nodes('/Record') as node(c1)

好了!~21图,测试到这。

XML类型的DML操作开始并不好记,看来只有多写语句才能记得。而这只是XML相关操作中很小的一部分。XML还涉及有类型化和非类型化的XML、XML类型导入导出、XML索引(主索引/辅索引/全文索引)、FOR XML的使用、XML架构集合等。太多!~有待学习!

时间: 2024-10-09 23:45:43

SqlServer XML数据类型DML相关操作(图文结合)的相关文章

java对XML文件的相关操作(dom4j)

1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <Person university="SCAU" location="GuangZhou"> 4 <student> 5 <name>tester1</name> 6 </student> 7 <student> 8 <name/>teste

python数据类型及相关操作

python数据类型详解 目录1.字符串2.布尔类型3.整数4.浮点数5.数字6.列表7.元组8.字典9.日期 1.字符串1.1.如何在Python中使用字符串a.使用单引号(')用单引号括起来表示字符串,例如:str='this is string';print str; b.使用双引号(")双引号中的字符串与单引号中的字符串用法完全相同,例如:str="this is string";print str; c.使用三引号(''')利用三引号,表示多行的字符串,可以在三引号

Java基础一 变量和数据类型及相关操作

Java基本语法: 1):Java语言严格区分大小写,好比main和Main是完全不同的概念. 2):一个Java源文件里可以定义多个Java类,但其中最多只能有一个类被定义成public类.若源文件中包括了public类,源文件必须和该public类同名. 3):一个源文件中包含N个Java类时,成功编译后会生成N份字节码文件,即每个类都会生成一份单独的class文件,且字节码文件名和其对应的类名相同. 4):若一个类必须运行,则必须拥有main方法,因为main方法是程序的入口. 编程建议:

数据类型及相关操作

JS的数据类型:数字(number).字符串(string).对象(object).布尔值(boolean).函数.未定义(undefine) typeof判断数据类型 1.对象可以自定义属性,例如:var obj=document:obj.onOff=true:alert(document.onOff); 2.var a="test";a.charAt();  //根据下标去找子字符串 HTML 标签类型:block.line.line-block.table... 数组的常见操作:

Xml文件的相关操作

Xml文档很久没有用过了,今天开开鲜,新手专区,不喜勿喷,运用的是WinForm编写 XMl文件的创建 /// <summary> /// 创建Xml文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnCreateXml_Click(object send

Python基础语法,基本数据类型及相关操作

---恢复内容开始--- python文件 文件开头要有  #!/usr/bin/ python        --在linux中是告诉系统phthon的路径是在/usr/bin/ python目录下,在执行python文件时可以使用 ./文件名  ,如:./h.py  即可执行 所以python2.7文件开头都需要有 # -*- coding:utf-8 -*- 这句来设置编码格式 当有中文输出时,常会输出为乱码,这是因为代码是utf-8格式的,但显示终端的编码格式是gbk格式的.如果显示终端

Redis五大数据类型的常用操作

在上一篇博文<centos安装redis>中,已经详细介绍了如何在centos上安装redis,今天主要介绍下Redis五大数据类型及其五大数据类型的相关操作. Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sorted set:有序集合). 原文地址:https://www.cnblogs.com/toutou/p/redis_data_type.html

知方可补不足~sqlserver中对xml类型字段的操作

回到目录 在sqlserver中有很多种数据类型,而XML数据类型是比较新奇怪的一种格式,我们平常接触的可能比较少,用的也少,而在某些场合,使用XML类型可能会使我们的开发变简单,下面就是一种情况: 表test有字段Menu,它保存的信息可能有两种方式,对标准menu,扩展menu,自定义Menu等,而这些方式所需要的键/值是不同的,有些同学会说使用Json串来存储,这当然是一种很不错的方式,但是数据库并没有这种类型,所以在查询,聚合时非常困难,这些我们想到了xml格式,它是SQLSERVER的

java 使用xom对象数据序列化为xml、反序列化、Preferences相关操作小案例

package org.rui.io.xml; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.List; import nu.xom.Document; import nu.