sqlserver xml 操作:2、对确定结构的xml进行操作
sqlserver xml 操作:2、对确定结构的xml进行操作
而sqlserver自2005版起,就对xml类型的数据进行了支持,且直接提供了5种操作,query()、value()、exist()、nodes()和modify(),有兴趣的同学可以到msdn中Microsoft SQL Server 2005 中的 XML 支持一文查看更多内容,包括xquery相关的部分,毕竟不是完整的xpath嘛,还是要看一下的。
然后,就是根据一个固定的xml文档,来作为演示依据了,xml文档如下:
<r>
<summary>
<title val="宁夏大学文献信息资源保障与服务提升建设数据库采购项目" />
<cls val="服务/信息技术服务/其他信息技术服务,服务/信息技术服务/其他信息技术服务,服务/信息技术服务/其他信息技术服务" />
<org val="宁夏大学" />
<city val="宁夏回族自治区" />
<publish_time val="2022年04月12日 09:54" />
<expert val="陈玉春(组长)、王维友、马勇、马文杰" />
<final_credit val="¥227.870000 万元(人民币)" />
<contact val="张莹" />
<contact_phone val="0951-5969335" />
<org_address val="宁夏银川市西夏区贺兰山西路489号" />
<org_phone val="09512061502" />
<agency val="宁夏恒盛招标有限公司" />
<agency_address val="宁夏银川市金凤区泰康街隆基商务大厦10楼" />
<agency_phone val="0951-5969335" />
</summary>
<result>
<url val="http://www.ccgp.gov.cn/cggg/dfgg/zbgg/202204/t20220412_17760138.htm" />
<type val="中标公告" />
<title val="宁夏大学文献信息资源保障与服务提升建设数据库采购项目中标公告" />
<category>
<main>
<ca id="2493" val="数据库" />
</main>
<more>
<ca id="2110" val="pad" />
<ca id="2493" val="数据库" />
</more>
</category>
<SN val="HSZB-2022ZC022">
<row name="项目编号" val="HSZB-2022ZC022" />
<row name="项目编号" val="HSZB-2022ZC022" />
<row name="采购编号" val="2022NCZ000812" />
</SN>
<budget />
<purchaser>
<org val="宁夏大学" />
<org_addr val="宁夏银川市西夏区贺兰山西路489号" />
<org_phone val="09512061502" />
<agency val="宁夏恒盛招标有限公司" />
<agency_addr val="宁夏银川市金凤区泰康街隆基商务大厦10楼" />
<agency_phone val="" />
</purchaser>
<date val="2022-04-12 09:54:00">
<row val="2022年04月13" pos="620" isDate="true" />
<row val="2022-04-12" pos="932" name="宁夏恒盛招标有限公司发布日期" isDate="true" />
</date>
<result>
<package>
<row>
<mode name="方式" val="表格" />
<company name="中标单位" val="北京华宇星航国际教育科技有限公司" />
<credit name="中标金额" val="1209500.00" />
</row>
<row>
<mode name="方式" val="表格" />
<company name="中标单位" val="山东数盟网络科技有限公司" />
<credit name="中标金额" val="564200.00" />
</row>
<row>
<mode name="方式" val="表格" />
<company name="中标单位" val="北京智诚阅品文化传播有限公司" />
<credit name="中标金额" val="505000.00" />
</row>
</package>
</result>
</result>
</r>
因为只是为了学习一下几种操作方法,所以,咱们就不用数据库里的内容了,直接 declare @xml xml然后set @xml = ‘上边的xml文档内容’
在介绍这些方法之前,先声明一下,别看各个指令里的内容都是字符串,但是,这里要说但是,他不支持字符串拼接!如果你想用变量代替到指令里,需要用sql:variable(“@变量名”)来代替!
1、exist(),节点是否存在
select @xml.exist('//*') -- 返回1,存在任意节点
select @xml.exist('//r') -- 返回1,存在以r为节点名的节点
select @xml.exist('//line') -- 返回0,不存在以line为节点名的节点
xquery、xpath语法这里就不讲了,有兴趣的同学自行百度
2、value(),取值
select @xml.value('(//org/@val)[1]','nvarchar(50)') -- 宁夏大学
select @xml.value('(//credit/@val)[1]','nvarchar(50)') -- 1209500.00,返回的是第一个credit的val属性的值
select @xml.value('.','nvarchar(max)') -- 以文本方式返回xml文档内容(无节点信息),注意,需要类型确定为xml类型,如果是for xml得到的内容,需要确定for xml后有参数type
3、nodes(),获取节点集合
select T.c.value('local-name(.)','varchar(50)') node -- 节点名
,T.c.value('./@name[1]','nvarchar(max)') name -- 节点中,name属性
,T.c.value('./@val[1]','nvarchar(max)') val -- 节点中,val属性
from @xml.nodes('//*') T(c)
select T.c.value('local-name(.)','varchar(50)') node
,T.c.value('./@name[1]','nvarchar(max)') name
,T.c.value('./@val[1]','nvarchar(max)') val
from @xml.nodes('//*[@val > 550000]') T(c)
4、query(),查询,用xquery语法进行查询,这个就比较复杂了,这里只做两个简单的例子
select @xml.query('count(//credit)').value('.','int') -- credit 节点共3个
,@xml.query('count(//credit[@val>550000])').value('.','int') -- val大于55万的credit节点共两个
,@xml.query('count(//*)').value('.','int') -- 所有节点共55个
select @xml.query('
for $i in //credit
let $val := $i/@val
where $val > 550000
order by (number($val))[1]
return <credit>{$val}</credit>
') -- 取得所有val大于55万的credit节点,并排序后返回
-----
<credit val="564200.00" />
<credit val="1209500.00" />
总之,query很好用,但想用好query,xquery语法一定要懂,xslt最好也了解一点,xpath最好也了解一点,反正是挺迷得,老顾平时基本上不怎么用这个
5、modify(),动态修改xml文档内信息
完全完全不推荐用这个玩意去修改xml数据,太繁琐了,什么增加、删除节点啦,什么增加、删除、修改属性啦,完完全全都是通过这一个方法实现的,而这个方法里有自己的指令集!需要使用 XML 数据操作语言 (DML) 中的字符串,又一个扩展的知识点!