当前位置: 首页 > 工具软件 > SQL2XML > 使用案例 >

SqlServer XML 类型数据操作

晏永康
2023-12-01

sqlserver 数据类型xml 对存入的数据有严格的要求,必须存放的是正确格式的xml. 一般的xml,头部信息为<?xml version="1.0" encoding="UTF-8"?> ,这会让你存入失败.
<data><name>aa</name></data> 这样不带头部信息的是可以存入的.

先建立一个获取xml的函数

CREATE FUNCTION [dbo].[FN_GETXML]()
RETURNS XML
AS 
BEGIN 
    DECLARE @XML XML;
    SET @XML = '
    <data>
        <budget_list type="aa">
            <PrpManpowers>
                <PrpManpower>
                    <itemName>天下为公</itemName>
                    <amount>100</amount>
                    <ename>aaa</ename>
                </PrpManpower>
                <PrpManpower>
                    <itemName>上善若水</itemName>
                    <amount>200</amount>
                    <ename>bbb</ename>
                </PrpManpower>
            </PrpManpowers>
        </budget_list>
        <budget_list type="bb">
            <PrpManpowers>
                <PrpManpower>
                    <itemName>大道至简</itemName>
                    <amount>300</amount>
                    <ename>ccc</ename>
                </PrpManpower>
            </PrpManpowers>
        </budget_list>
    </data>
    ';
    RETURN @XML;
END;

例子和要点下面已指出

--query 函数,query 的查询表达式,不要求定位的元素是唯一的.
DECLARE @xml1 XML;SET @xml1 = dbo.FN_GETXML();--第一个budget_list 找所有的itemName
SELECT @xml1.query('data/budget_list[1]/PrpManpowers/PrpManpower/itemName');

DECLARE @xml2 XML;SET @xml2 = dbo.FN_GETXML();--在第一个budget_list 里面找第二个PrpManpower 中的itemName
SELECT @xml2.query('data/budget_list[1]/PrpManpowers/PrpManpower[2]/itemName');

DECLARE @xml3 XML;SET @xml3 = dbo.FN_GETXML();--在第一个budget_list 里面找amount<150对应的PrpManpower,取找到结果的itemName 作为结果
SELECT @xml3.query('data/budget_list[1]/PrpManpowers/PrpManpower[amount<150]/itemName');

DECLARE @xml4 XML;SET @xml4 = dbo.FN_GETXML();--在所有的budget_list 里面找amount>100 对应的PrpManpower,取找到结果的itemName 作为结果
SELECT @xml4.query('data/budget_list/PrpManpowers/PrpManpower[amount>100]/itemName');

DECLARE @xml5 XML;SET @xml5 = dbo.FN_GETXML();--找到大道至简
SELECT @xml5.query('data/budget_list/PrpManpowers/PrpManpower[itemName="大道至简"]/itemName');

--带属性查找,使用@开头
DECLARE @xml6 XML;SET @xml6 = dbo.FN_GETXML();--在所有属性含有type="aa" 的budget_list,下面的itemName. 注意:属性是用@开头的.
SELECT @xml6.query('data/budget_list[@type="aa"]/PrpManpowers/PrpManpower/itemName');

---value()函数,必须保证查询表达式要求定位的元素是唯一的.,(../../..)[index] 这是固定写法. 前面必须有(),后面必须有[index]. 
DECLARE @xml7 XML;SET @xml7 = dbo.FN_GETXML();DECLARE @rs NVARCHAR(100);--在所有属性含有type="aa" 的budget_list,下面的itemName. 注意:属性是用@开头的.
SELECT @xml7.value('(data/budget_list[@type="aa"]/PrpManpowers/PrpManpower/itemName)[1]','nvarchar(100)');--这一句,SELECT 换成 PRINT 报错.如要打印,如下
SET @rs = @xml7.value('(data/budget_list[@type="aa"]/PrpManpowers/PrpManpower/itemName)[1]','nvarchar(100)');
PRINT @rs;

-- 如果定位的结果不是叶子节点,那么会把该节点下所有的子节点的value拼接到一起.
--如下面定位到PrpManpower,可是PrpManpower有<itemName><amount><ename>子节点. 三个节点的拼在一起了
DECLARE @xml8 XML;SET @xml8 = dbo.FN_GETXML();
SELECT @xml8.value('(data/budget_list[@type="aa"]/PrpManpowers/PrpManpower)[1]','nvarchar(100)');


--1.修改已有节点的值.使用rupalace,必须保证查询表达式要求定位的元素是唯一的,否则报错.replace 一次只能改一个节点.
--replace 中使用常量(cccc)
DECLARE @xml9 XML;SET @xml9 = dbo.FN_GETXML();
SET @xml9.modify('replace value of (data/budget_list[@type="aa"]/PrpManpowers/PrpManpower/itemName/text())[1] with "cccc"');
SELECT @xml9.value('(data/budget_list[@type="aa"]/PrpManpowers/PrpManpower/itemName)[1]','nvarchar(100)');---cccc
SELECT @xml9; --原有已经修改

--replace 中使用变量
DECLARE @xml10 XML;SET @xml10 = dbo.FN_GETXML(); DECLARE @itemName1 NVARCHAR(100);SET @itemName1 = '123456';
SET @xml10.modify('replace value of (data/budget_list[@type="aa"]/PrpManpowers/PrpManpower/itemName/text())[1] with sql:variable("@itemName1")');
SELECT @xml10.value('(data/budget_list[@type="aa"]/PrpManpowers/PrpManpower/itemName)[1]','nvarchar(100)');---123456
SELECT @xml10; --原有已经修改

--删除节点 (可以多删除)
DECLARE @xml11 XML;SET @xml11 = dbo.FN_GETXML();
SET @xml11.modify('delete data/budget_list/PrpManpowers/PrpManpower/itemName');
SELECT @xml11; --原有已经修改


--删除节点的值
DECLARE @xml12 XML;SET @xml12 = dbo.FN_GETXML();
SET @xml12.modify('delete (data/budget_list/PrpManpowers/PrpManpower/itemName/text())');
SELECT @xml12; --原有已经修改

--插入节点1(定位唯一) first
DECLARE @xml13 XML;SET @xml13 = dbo.FN_GETXML();DECLARE @temp13_1 NVARCHAR(100);SET @temp13_1='CCC';DECLARE @temp13_2 NVARCHAR(100);SET @temp13_2='苏轼';
SET @xml13.modify('insert <cname type="{sql:variable("@temp13_1")}">{sql:variable("@temp13_2")}</cname> as first into (data/budget_list[1]/PrpManpowers/PrpManpower)[1]');
SELECT @xml13; --原有已经修改

--插入节点2(定位唯一) last
DECLARE @xml14 XML;SET @xml14 = dbo.FN_GETXML();
SET @xml14.modify('insert <cname type="CCC">苏轼</cname> as last into (data/budget_list[1]/PrpManpowers/PrpManpower)[1]');
SELECT @xml14; --原有已经修改

--插入节点3(定位唯一) before
DECLARE @xml15 XML;SET @xml15 = dbo.FN_GETXML();DECLARE @temp15_1 NVARCHAR(100);SET @temp15_1='CCC';DECLARE @temp15_2 NVARCHAR(100);SET @temp15_2='苏轼';
SET @xml15.modify('insert <cname type="{sql:variable("@temp15_1")}">{sql:variable("@temp15_2")}</cname> before (data/budget_list[1]/PrpManpowers/PrpManpower[1]/ename)[1]');
SELECT @xml15; --原有已经修改

--插入节点4(定位唯一)  after
DECLARE @xml16 XML;SET @xml16 = dbo.FN_GETXML();DECLARE @temp16_1 NVARCHAR(100);SET @temp16_1='CCC';DECLARE @temp16_2 NVARCHAR(100);SET @temp16_2='苏轼';
SET @xml16.modify('insert <cname type="{sql:variable("@temp16_1")}">{sql:variable("@temp16_2")}</cname> after (data/budget_list[1]/PrpManpowers/PrpManpower[1]/ename)[1]');
SELECT @xml16; --原有已经修改


--使用常量增加属性值
--为指定的manpower 增加一个id 属性(使用常量),增加之后<PrpManpower id="123">
DECLARE @xml17 XML;SET @xml17 = dbo.FN_GETXML();
SET @xml17.modify('insert attribute id {123} into (data/budget_list[1]/PrpManpowers/PrpManpower)[1]')
SELECT @xml17 AS RS;

--使用变量增加属性值.
--为指定的manpower 增加一个id 属性(使用变量),增加之后<PrpManpower id="456">
DECLARE @xml18 XML;SET @xml18 = dbo.FN_GETXML();DECLARE @id1 NVARCHAR(10);SET @id1 ='456';--(变量)
SET @xml18.modify('insert attribute id {sql:variable("@id1")} into (data/budget_list[1]/PrpManpowers/PrpManpower)[1]')
SELECT @xml18 AS RS;

--使用常量修改属性值. 修改budget_list 的type 属性
DECLARE @xml19 XML;SET @xml19 = dbo.FN_GETXML();
SET @xml19.modify('replace value of (data/budget_list)[1]/@type with "CCC"')
SELECT @xml19 AS RS;

--使用变量修改属性值. 修改budget_list 的type 属性
DECLARE @xml20 XML;SET @xml20 = dbo.FN_GETXML();DECLARE @id2 NVARCHAR(100);SET @id2= 'DDD';
SET @xml20.modify('replace value of (data/budget_list)[1]/@type with sql:variable("@id2")')
SELECT @xml20 AS RS;

--查找属性
DECLARE @xml21 XML;SET @xml21 = dbo.FN_GETXML();
SELECT @xml21.value('(data/budget_list)[1]/@type','nvarchar(100)');

--exist. 查找到了返回1,为查找到返回0
DECLARE @xml22 XML;SET @xml22 = dbo.FN_GETXML();
SELECT @xml22.exist('data/budget_list[1]/PrpManpowers/PrpManpower[1]');--1
SELECT @xml22.exist('data/budget_list[1]/PrpManpowers/PrpManpower[itemName="道济天下"]');--0
SELECT @xml22.exist('data/budget_list[1]/PrpManpowers/PrpManpower[itemName="天下为公"]');--1
SELECT @xml22.exist('data/budget_list[1]/PrpManpowers/PrpManpower[itemName="天下为公"]/amount');--1
SELECT @xml22.exist('data/budget_list[1]/PrpManpowers/PrpManpower[itemName="天下为公"]/amount1');--0
 类似资料: