简单的几个 T-SQL 操作 XML 的小例子

XML 就是一种数据类型,应用场景必须要有相应的编程语言,我们以 TSQL 为例,讨论下如何装载 XML 数据,以及如何解析 XML 数据.

XML 数据,完全的表现形式,是 element , element attributes, sub-element, sub-element attribute & content 。那么其实就有两种表现形式:
1 元素形式, 只有元素和元素内容: element + subelement content

    <order>
              <orderid> 0001</orderid>
              <amount> 20000</amount>
    </oreder>

2 属性的形式,只有元素和属性:element + attributes

    <orederid="0001" amount=2000 />

TSQL 中,装载最简单的 XML 数据,用 select for xml 就可以实现了。这里简单的介绍下几个应用例子,方便日后查询。

应用一: 针对只有元素与内容
1 用指令 elements

 select * from sales_history for xml, elements

应用二:针对属性元素
1 不带任何参数的 RAW,Auto 模式都将列转化成为元素

 selec * from sales_history for xml raw
 select * from sales_history for xml auto

2 Path 模式下,在列前面加@符号,将列映射成为属性

select orderid as "@orderid", order_totals from sales_history for xml path('orders')

同样,如果要解析这 XML 数据,可以选择的方法是 value (), query()

应用一: 针对只有元素与内容
1. value(‘path’,’type’)

应用二:针对属性元素
1. value(‘/xpath/@attributename’,’type’)

MSDN 是这样对装载 XML 数据做总结的:

select ...for xml:
  RAW
  AUTO
  EXPLICIT
  PATH

其中, RAW, AUTO 比较简单直观,将每一行的数据,分别以 row 和 表名或者其他复合对象名(heuristic) 作为元素,将每一个列作为属性集合起来。后两者比较难,EXPLICIT 特别是作为重武器应用的。

模式后面带指令,模式及指令都可以自带参数:

select * from sales
for xml  Raw('order'),  Type, Root('sales')

一个简单的返回子存储过程运行结果的例子:

ALTER procedure dbo.innerInsertionOne
@ResultMessage xml output 
as 
begin 
BEGIN TRY 
    insert into dbo.region(regionId,regionName) values(100,'JiangSu-Wuxi') ;
    set @ResultMessage = (
    select 'InnerInsertionOne' as EntityPart
    , 'Success' as Result
    , 'Successfully Inserted' as ErrorMessage
    for XML PATH('WorkPart'),ROOT('ResultSet'), TYPE,ELEMENTS ) ;
END TRY 
BEGIN CATCH
    IF @@TRANCOUNT>0 ROLLBACK TRANSACTION ;
    SET @ResultMessage = (
    select 'InnerInsertionOne' as EntityPart
    , 'Failure' as Result
    , 'Failed to be Inserted' as ErrorMessage
    for XML PATH('WorkPart'),ROOT('ResultSet'), TYPE,ELEMENTS ) ;
END CATCH 
END
GO 
ALTER procedure dbo.innerInsertionTwo
@ResultMessage xml output 
as 
begin 
BEGIN TRY 
    insert into dbo.region(regionId,regionName) values('1-100X','JiangSu-Wuxi') ;
    set @ResultMessage = (
    select 'InnerInsertionTwo' as EntityPart
    , 'Success' as Result
    , 'Successfully Inserted' as ErrorMessage
    for XML PATH('WorkPart'),ROOT('ResultSet'), TYPE,ELEMENTS ) ;
END TRY 
BEGIN CATCH
    IF @@TRANCOUNT>0 ROLLBACK TRANSACTION ;
    SET @ResultMessage = (
    select 'InnerInsertionTwo' as EntityPart
    , 'Failure' as Result
    , 'Failed to be Inserted' as ErrorMessage
    for XML PATH('WorkPart'),ROOT('ResultSet'), TYPE,ELEMENTS ) ;
END CATCH 
END
GO 
ALTER PROCEDURE dbo.MainInsert
AS
BEGIN 
BEGIN TRY 
    DECLARE @RESULTMESSAGE XML ;
    DECLARE @RESULTRETURN INT = -1 ;
    DECLARE @WORKFLOW TABLE(Entity varchar(100), ProcessDetail XML) ;
    EXEC @RESULTRETURN = dbo.innerInsertionOne @ResultMessage = @RESULTMESSAGE output ;
    SELECT @RESULTRETURN;
    INSERT INTO @WORKFLOW(Entity,ProcessDetail)VALUES('dbo.innerInsertionOne',@RESULTMESSAGE);
    EXEC @RESULTRETURN = dbo.innerInsertionTwo @ResultMessage = @RESULTMESSAGE OUTPUT ;
    INSERT INTO @WORKFLOW(Entity,ProcessDetail)VALUES('dbo.innerInsertionTwo',@RESULTMESSAGE);
    IF EXISTS(SELECT TOP 1 1 FROM (SELECT ProcessDetail, 
           ProcessDetail.value('(/ResultSet/WorkPart/Result)[1]','VARCHAR(MAX)')AS RESULT
    FROM @WORKFLOW ) RES WHERE RESULT = 'Failure')
    BEGIN 
        IF EXISTS(SELECT TOP 1 1 FROM (
        SELECT ProcessDetail.value('(/ResultSet/WorkPart/Result)[1]','VARCHAR(MAX)')AS RESULT
        ,ProcessDetail.value('(/ResultSet/WorkPart/EntityPart)[1]','VARCHAR(MAX)')AS EntityPart
        ,ProcessDetail.value('(/ResultSet/WorkPart/ErrorMessage)[1]','VARCHAR(MAX)')AS ErrorMessage
        FROM @WORKFLOW 
        WHERE ProcessDetail.value('(/ResultSet/WorkPart/Result)[1]','VARCHAR(MAX)') ='Failure')tmp
        WHERE EntityPart = 'InnerInsertionTwo' ) 
        BEGIN 
            RAISERROR('FatalProcessFailed',16,1) ;
        END
        RETURN 10 ;
    END
END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT> 0 ROLLBACK TRANSACTION ;

    set @ResultMessage = (
    select 'MainTransaction' as EntityPart
    , 'Failure' as Result
    , ERROR_MESSAGE() as ErrorMessage
    for XML PATH('WorkPart'),ROOT('ResultSet'), TYPE,ELEMENTS ) ;
    INSERT INTO @WORKFLOW(Entity,ProcessDetail)VALUES('MainProcess',@RESULTMESSAGE);

        SELECT ProcessDetail.value('(/ResultSet/WorkPart/Result)[1]','VARCHAR(MAX)')AS RESULT
        ,ProcessDetail.value('(/ResultSet/WorkPart/EntityPart)[1]','VARCHAR(MAX)')AS EntityPart
        ,ProcessDetail.value('(/ResultSet/WorkPart/ErrorMessage)[1]','VARCHAR(MAX)')AS ErrorMessage
        FROM @WORKFLOW 
        WHERE ProcessDetail.value('(/ResultSet/WorkPart/Result)[1]','VARCHAR(MAX)') ='Failure'
        AND ProcessDetail.value('(/ResultSet/WorkPart/ErrorMessage)[1]','VARCHAR(MAX)') <>'FatalProcessFailed';

        RETURN 999 ;
END CATCH 
END 
GO 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 MyBatis 中,可以在 mapper.xml 文件中使用 `<select>`, `<insert>`, `<update>`, `<delete>` 标签来定义 SQL 语句。这些标签中的 SQL 语句可以使用参数,参数的传递方式有多种,以下是其中几种常用的方式: 1. 使用 `#{}` 占位符来传递参数。例如: ```xml <select id="getUserById" resultType="User"> SELECT * FROM user WHERE id = #{userId} </select> ``` 在这个例子中,`#{userId}` 表示一个占位符,MyBatis 会在执行 SQL 语句时将其替换为实际的参数值。 2. 使用 `${}` 占位符来传递参数。例如: ```xml <select id="getUserByName" resultType="User"> SELECT * FROM user WHERE name = '${userName}' </select> ``` 在这个例子中,`${userName}` 表示一个占位符,MyBatis 会在执行 SQL 语句时将其替换为实际的参数值。需要注意的是,使用 `${}` 传递参数存在 SQL 注入的风险,因为实际的参数值直接拼接到 SQL 语句中,建议尽量避免使用。 3. 使用 `@Param` 注解来传递参数。例如: ```java public interface UserMapper { List<User> getUserByNameAndAge(@Param("name") String name, @Param("age") int age); } ``` ```xml <select id="getUserByNameAndAge" resultType="User"> SELECT * FROM user WHERE name = #{name} AND age = #{age} </select> ``` 在这个例子中,`@Param` 注解用于指定参数的名称,MyBatis 会根据参数名称来匹配 SQL 语句中的占位符。 这些方式都可以用于传递参数,具体选择哪种方式取决于具体的情况。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dbLenis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值