xml类型使用注意事项

xml 的数据类型在平常的开发也是很常用的,燃鹅。也是有一些地方需要留意。今天我就分享几个测试的例子。

使用 xquery.exist (有但不仅仅限于)的注意事项。通常使用来判断节点是否存在,值是否存在。常用例子是

DECLARE @xml XML = '
<Root>
    <ID>1</ID>
    <ID>2</ID>
</Root>
'
SELECT @xml.exist('Root/ID[text()=1]')
SELECT @xml.exist('Root/ID[text()=0]')

显然结果就是第一条就是1,第二条语句就是0。这是基本应用,也没有什么问题。

然后我们根据实际情况测试一下。比方说我们使用exist 来配对表里面的值,比如使用以下例子,将包含在xml节点的员工密码修改为默认123456

SET NOCOUNT ON;
DECLARE @T AS TABLE (
Staff NVARCHAR(50),
Age INT,
PSW VARCHAR(50)
)

INSERT INTO @T
        ( Staff, Age, PSW )
VALUES  ( 'Joe', 30,'JJJJJ' ),
        ( 'Mary',25,'KKK')

DECLARE @Xml XML ='
<Staffs>
    <Staff>Joe</Staff>
</Staffs>
'

SELECT * FROM @T
UPDATE a SET PSW = '123456'
    FROM @T a
    WHERE @Xml.exist('Staffs/Staff[text()=sql:column("a.Staff")]') = 1
SELECT * FROM @T




Staff                                              Age         PSW
-------------------------------------------------- ----------- --------------------------------------------------
Joe                                                30          JJJJJ
Mary                                               25          KKK

Staff                                              Age         PSW
-------------------------------------------------- ----------- --------------------------------------------------
Joe                                                30          123456
Mary                                               25          KKK

 这样看没有什么问题,因为测试用例都比较规范。但是如果变点花样就不一样了。比如说

SET NOCOUNT ON;
DECLARE @T AS TABLE (
Staff NCHAR(50),  --只是将数据类型从NVarchar(50) 调整为 NChar(50)
Age INT,
PSW VARCHAR(50)
)

INSERT INTO @T
        ( Staff, Age, PSW )
VALUES  ( 'Joe', 30,'JJJJJ' ),
        ( 'Mary',25,'KKK')

DECLARE @Xml XML ='
<Staffs>
    <Staff>Joe</Staff>
</Staffs>
'

SELECT * FROM @T
UPDATE a SET PSW = '123456'
    FROM @T a
    WHERE @Xml.exist('Staffs/Staff[text()=sql:column("a.Staff")]') = 1
SELECT * FROM @T


Staff Age PSW
-------------------------------------------------- ----------- --------------------------------------------------
Joe 30 JJJJJ
Mary 25 KKK

 
  

Staff Age PSW
-------------------------------------------------- ----------- --------------------------------------------------
Joe 30 JJJJJ
Mary 25 KKK

 

表里面的数据没有被更改,换句话来说用 xquery.exist 判断不了这种情况。原因好明确,就因为@T里面的Staff 实际上后面带了N多个空格嘛,所以和xml进行匹配就懵逼了。导致根本生成不了结果。

如果数据是这样的,不妨改一下方法,也可以实现修改的功能。下面的例子是先把xml里面的节点值先提取出来,再和数据库表变量进行一个比对,因为在默认情况下,数据库的比对会去除后面空格再进行比对。所以更新就可以成功了。

 

SET NOCOUNT ON;
DECLARE @T AS TABLE (
Staff NCHAR(50),
Age INT,
PSW VARCHAR(50)
)

INSERT INTO @T
        ( Staff, Age, PSW )
VALUES  ( 'Joe', 30,'JJJJJ' ),
        ( 'Mary',25,'KKK')

DECLARE @Xml XML ='
<Staffs>
    <Staff>Joe</Staff>
</Staffs>
'

SELECT * FROM @T
;WITH CTE AS
(
    SELECT t.c.value('.[text()]','Nvarchar(50)') Staff
        FROM @Xml.nodes('Staffs/Staff') AS t(c)
)
UPDATE a SET PSW = '123456'
    FROM @T a
    WHERE EXISTS(SELECT * FROM CTE WHERE a.Staff = CTE.Staff)
SELECT * FROM @T

 

 

这个例子也告诉我们当遇到有些语句在查询有问题出不来的时候,多一个途径,看下是不是查询的方法和和本身数据是否不符合。也多一种检查的路子。

燃鹅关键还是要多练习一下下 

 

转载于:https://www.cnblogs.com/Gin-23333/p/5676647.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值