新建两个需统一事务处理的数据表

--学生信息表
CREATE TABLE [dbo].[Student](
[Id] [int] NOT NULL,
[Name] [varchar](50) NOT NULL,
[Age] [int] NOT NULL,
[Address] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] --学生成绩表
CREATE TABLE [dbo].[Result](
[Id] [int] IDENTITY(1,1) NOT NULL,
[StudentId] [int] NOT NULL,
[Subject] [varchar](50) NOT NULL,
[Score] [int] NOT NULL,
CONSTRAINT [PK_Result] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

代码中定义相应的实体类

public class Student
{
/// <summary>
///编号
/// </summary>
public int StudentId { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
/// <summary>
/// 地址
/// </summary>
public string Address { get; set; }
}
public class Result
{
/// <summary>
/// 学生编号
/// </summary>
public int StudentId { get; set; }
/// <summary>
/// 科目
/// </summary>
public string Subject { get; set; }
/// <summary>
/// 得分
/// </summary>
public int Score { get; set; }
}

初始化对象

Student student = new Student { StudentId = , Name = "Johh", Age = , Address = "中国上海" };
List<Result> resultList = new List<Result> { new Result { StudentId = , Subject = "语文", Score = },
new Result { StudentId = , Subject = "数学", Score = } };

定义一个把实体转换成XML的通用方法

        /// <summary>
/// 把实体对象转换成Xml
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
protected string GetSerializer<T>(T model)
where T : new()
{
StringBuilder sb = new StringBuilder();
XmlSerializer x = new XmlSerializer(typeof(T));
StringWriter sw = new StringWriter(sb);
x.Serialize(sw, model);
return ProcessXmlStr(sb.ToString());
}
/// <summary>
/// 处理Xml中的特殊字符
/// </summary>
/// <param name="xml"></param>
/// <returns></returns>
public string ProcessXmlStr(string xml)
{
string xmlHead = "<?xml version=\"1.0\" encoding=\"utf-16\"?>";
string strSpace = "\r\n";
string strXlnsxsi = " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
string strXlnsxsd = "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"";
string strNil = "xsi:nil=\"true\"";
return xml.Replace(xmlHead, "").Replace(strSpace, "").Replace(strXlnsxsi, "").Replace(strXlnsxsd, "")
.Replace("> <", "><").Replace(strNil, "").Replace("<", "&lt;").Replace(">", "&gt;");
}

把实体转换成Xml格式

     /// <summary>
/// 获取单个对象sql执行脚本
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parameterValue">参数值</param>
/// <param name="procName">存储过程名称</param>
/// <param name="procIndex">存储过程执行顺序</param>
/// <param name="parameterName">参数名称</param>
/// <returns></returns>
protected string GetSingleExcuteSql<T>(T parameterValue, string procName, int procIndex, string parameterName) where T : new()
{
StringBuilder sb = new StringBuilder();
sb.Append(string.Format("<SP Name=\"{0}\" ProcIndex=\"{1}\" ParameterName=\"{2}\" ParameterValue=\"{3}\"></SP>",
procName, procIndex, parameterName, parameterValue != null ? GetSerializer(parameterValue) : ""));
return sb.ToString();
}
/// <summary>
/// 获取sql执行脚本
/// </summary>
/// <param name="student">学生信息</param>
/// <param name="resultList">学生成绩</param>
/// <returns></returns>
protected string GetExcuteSql(Student student, List<Result> resultList)
{
StringBuilder sb = new StringBuilder();
sb.Append(GetSingleExcuteSql<Student>(student, "Proc_Insert_Student", (int)SqlExcuteIndex.CurrentStep, "StudentXml"));
sb.Append(GetSingleExcuteSql<List<Result>>(resultList, "Proc_Insert_Result", (int)SqlExcuteIndex.CurrentStep + , "ResultXml"));
return sb.ToString();
}

组装Xml,并统一执行

        /// <summary>
/// 使用事务进行存储
/// </summary>
/// <returns></returns>
public bool ExcuteTransaction()
{
return new TestDAL().ProcessOverall("<SPList>"+GetExcuteSql(student,resultList)+"</SPList>");
}      /// <summary>
/// 事件统一执行
/// </summary>
/// <param name="allInfo"></param>
/// <returns></returns>
public bool ProcessOverall(string allInfo)
{
bool result = false;
SqlParameter param = new SqlParameter("@AllInfo", allInfo);
result = Excute("proc_flow_ProcessOverall", param, CommandType.StoredProcedure);
return result;
}

数据库创建XML处理函数

-- =============================================
-- Author: Casper
-- Create date: 2014/09/30
-- Description: 预处理xml字符串,替换特殊字符
-- =============================================
CREATE FUNCTION [dbo].[func_sys_PreProcessXmlStr] ( @xmlStr NVARCHAR(MAX) )
RETURNS NVARCHAR(MAX)
AS
BEGIN
RETURN REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@xmlStr
, '&amp;gt;','>')
, '&amp;amp;gt;','>')
, '&amp;lt;','<')
, '&amp;amp;lt;', '<')
, '&lt;', '<')
, '&gt;', '>')
, '0001-01-01T00:00:00', '') END

数据库创建单表保存存储过程

-- =============================================
-- Author: Casper
-- Create date: 2014-09-30
-- Description: 学生成绩保存
-- =============================================
CREATE PROCEDURE [dbo].[Proc_Insert_Result]
@ResultXml NVARCHAR(MAX)
AS
BEGIN
IF @ResultXml <> ''
BEGIN
--DECLARE @ResultXml NVARCHAR(MAX)='&lt;ArrayOfResult &gt;&lt;Result&gt; &lt;StudentId&gt;1&lt;/StudentId&gt; &lt;Subject&gt;语文&lt;/Subject&gt; &lt;Score&gt;80&lt;/Score&gt;&lt;/Result&gt;&lt;Result&gt; &lt;StudentId&gt;1&lt;/StudentId&gt; &lt;Subject&gt;数学&lt;/Subject&gt; &lt;Score&gt;60&lt;/Score&gt;&lt;/Result&gt;&lt;/ArrayOfResult&gt;' DECLARE @a INT
SET @ResultXml = dbo.func_sys_PreProcessXmlStr(@ResultXml) --替换XML特殊字符
EXEC sp_xml_preparedocument @a OUTPUT, @ResultXml
SELECT *
INTO #ResultInfo
FROM OPENXML(@a,'ArrayOfResult/Result',2) WITH
(
StudentId INT,
[Subject] VARCHAR(50),
Score INT
)
SELECT *
FROM #ResultInfo IF EXISTS ( SELECT * --判断新增记录是否存在,如果存在则修改,否则插入
FROM dbo.Result
WHERE Id = ( SELECT Id
FROM #ResultInfo
) )
BEGIN
UPDATE a
SET StudentId = b.StudentId ,
[Subject] = b.[Subject] ,
Score = b.Score
FROM dbo.Result a
INNER JOIN #ResultInfo b ON a.Id = b.Id
END
ELSE
BEGIN
INSERT INTO dbo.Result
( StudentId ,
Subject ,
Score
)
SELECT StudentId ,
Subject ,
Score
FROM #ResultInfo
END
END DROP TABLE #ResultInfo
END -- =============================================
-- Author: Casper
-- Create date: 2014-09-30
-- Description: 学生成绩信息保存
-- =============================================
CREATE PROCEDURE [dbo].[Proc_Insert_Result]
@ResultXml NVARCHAR(MAX)
AS
BEGIN
IF @ResultXml <> ''
BEGIN
--DECLARE @ResultXml NVARCHAR(MAX)='&lt;ArrayOfResult &gt;&lt;Result&gt; &lt;StudentId&gt;1&lt;/StudentId&gt; &lt;Subject&gt;语文&lt;/Subject&gt; &lt;Score&gt;80&lt;/Score&gt;&lt;/Result&gt;&lt;Result&gt; &lt;StudentId&gt;1&lt;/StudentId&gt; &lt;Subject&gt;数学&lt;/Subject&gt; &lt;Score&gt;60&lt;/Score&gt;&lt;/Result&gt;&lt;/ArrayOfResult&gt;'
DECLARE @a INT
SET @ResultXml = dbo.func_sys_PreProcessXmlStr(@ResultXml) --替换XML特殊字符
EXEC sp_xml_preparedocument @a OUTPUT, @ResultXml
SELECT *
INTO #ResultInfo
FROM OPENXML(@a,'ArrayOfResult/Result',2) WITH
(
Id INT,
StudentId INT,
[Subject] VARCHAR(50),
Score INT
) IF EXISTS ( SELECT * --判断新增记录是否存在,如果存在则修改,否则插入
FROM dbo.Result
WHERE Id = ( SELECT Id
FROM #ResultInfo
) )
BEGIN
UPDATE a
SET StudentId = b.StudentId ,
[Subject] = b.[Subject] ,
Score = b.Score
FROM dbo.Result a
INNER JOIN #ResultInfo b ON a.Id = b.Id
END
ELSE
BEGIN
INSERT INTO dbo.Result
( StudentId ,
Subject ,
Score
)
SELECT StudentId ,
[Subject] ,
Score
FROM #ResultInfo
END
END
END

最后创建统一事务处理存储过程

---- =============================================
---- Author: Caper
---- Create date: 2014-09-30
---- Description: 统一事务处理
CREATE PROCEDURE [dbo].[proc_flow_ProcessOverall] @AllInfo NVARCHAR(MAX)
AS
BEGIN
--DECLARE @a INT
--DECLARE @AllInfo NVARCHAR(MAX)
--SET @AllInfo = '<SPList><SP Name="Proc_Insert_Student" ProcIndex="1" ParameterName="StudentXml" ParameterValue="&lt;Student &gt;&lt;StudentId&gt;1&lt;/StudentId&gt;&lt;Name&gt;Johh&lt;/Name&gt;&lt;Age&gt;18&lt;/Age&gt;&lt;Address&gt;中国上海&lt;/Address&gt;&lt;/Student&gt;"></SP><SP Name="Proc_Insert_Result" ProcIndex="2" ParameterName="ResultXml" ParameterValue="&lt;ArrayOfResult &gt;&lt;Result&gt; &lt;StudentId&gt;1&lt;/StudentId&gt; &lt;Subject&gt;语文&lt;/Subject&gt; &lt;Score&gt;80&lt;/Score&gt;&lt;/Result&gt;&lt;Result&gt; &lt;StudentId&gt;1&lt;/StudentId&gt; &lt;Subject&gt;数学&lt;/Subject&gt; &lt;Score&gt;60&lt;/Score&gt;&lt;/Result&gt;&lt;/ArrayOfResult&gt;"></SP></SPList>' EXEC sp_xml_preparedocument @a OUTPUT, @AllInfo SELECT *
INTO #temp
FROM OPENXML (@a, 'SPList/SP',1) WITH
(
Name VARCHAR(500),
ProcIndex INT,
ParameterName VARCHAR(100),
ParameterValue NVARCHAR(MAX)
)
SELECT * FROM #temp
SELECT DISTINCT
ProcIndex ,
' exec ' + NAME
+ ( STUFF(( SELECT ',' + ' @' + ParameterName + '='''
+ ParameterValue + ''''
FROM #temp
WHERE NAME = t1.name
FOR
XML PATH('')
), 1, 1, '') ) AS ProcStr
INTO #TEMP1
FROM #temp t1 SELECT * FROM #TEMP1 --按存储过程执行顺序排序
SELECT *
INTO #TEMP2
FROM #TEMP1
ORDER BY ProcIndex SELECT * FROM #TEMP2
--
--执行存储过程
DECLARE @sql NVARCHAR(MAX)
SELECT @sql = '
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET XACT_ABORT ON
BEGIN TRANSACTION FlowProcessOverall
' + STUFF(( SELECT ';' + ProcStr
FROM #TEMP2
FOR
XML PATH('')
), 1, 1, '') +
' COMMIT TRANSACTION FlowProcessOverall '
SELECT @sql
EXECUTE sp_executesql @sql DROP TABLE #temp ,#TEMP1 ,#TEMP2
END

国庆快乐

SQL多表插入事务处理的更多相关文章

  1. C# SQL 整表插入 分类: C# 2014-09-17 16:18 369人阅读 评论(2) 收藏

    说明: (1)表A的一部分数据插入到表B (2)DataAccess 类,是放在DAL层下的底层类; da.StrConnection 写在DataAccess类中; //整表插入方法 private ...

  2. C# SQL 整表插入

    说明: (1)表A的一部分数据插入到表B (2)DataAccess 类,是放在DAL层下的底层类; da.StrConnection 写在DataAccess类中; //整表插入方法 private ...

  3. SQL数据表插入随机数(转)

    declare @T TABLE (id int identity(1,1),[Name] nvarchar(20), Randnum int) insert @T ([Name]) select ' ...

  4. MySQL中的多表插入更新与MS-SQL的对比

    MySQL多表插入: INSERT INTO tdb_goods_cates (cate_name) SELECT goods_cate FROM tdb_goods GROUP BY goods_c ...

  5. 如何往有自增标识字段的表插入数据时,同时给自增标识字段插入值呢,在Inset Into语句前后加上SQL语句:SET IDENTITY_INSERT TableName ON和SET IDENTITY_INSERT TableName OFF

    当要往有设置自增标识字段的表插入数据,并希望同时设置好自增字段的值时,可以在insert into 的SQL语句前后分别加上一句sql语句,SET IDENTITY_INSERT TableName  ...

  6. SQL将一个表中的某一列值全部插入到另一个表中

    1.  SQL将一个表中的某一列值全部插入到另一个表中 插入的话: insert into a(col) select col from b; 更新的话: update a set col=selec ...

  7. 09Microsoft SQL Server 表数据插入,更新,删除

    Microsoft SQL Server 表数据插入,更新,删除 向表中插入数据 INSERT INTO insert into tb1 values(0004,'张凤凤') insert into ...

  8. sql将一个表中的数据插入到另一个表中

    sql将一个表中的数据插入到另一个表中 列名不一定要相同,只要你在HH中列出要插入列的列表跟select   from   mm表中的选择的列的列表一一对应就可以了,当然两边的数据类型应该是兼容的.  ...

  9. sql实现同时向主表和子表插入数据方法

    使用sql语句实现同时向主表和子表插入数据方法: Oracle: -- oracle创建sequence create sequence SEQ_test minvalue 1 maxvalue 99 ...

随机推荐

  1. 动态SQL语句:定义(一)

    文章系列 动态SQL语句:定义(一) 静态SQL与动态SQL 静态SQL:程序运行前,具有固定的形式和结构的SQL. 动态SQL:程序运行时,能够动态改变形式或结构的SQL. 一些思考和想法 在实际的 ...

  2. 【使用教程】论Windows下必备的抓包工具Fiddler2如何安装证书(查看Https)

    一.写在前面 好久没更新博客了,最近也是忙着年前的一些事情,所以一直没来得及弄一些有价值的东西,还是来冒个泡.随着苹果公司要求的2017年开始上架审核必须是Https,而原本Http的上架需要提交强烈 ...

  3. Java实践 — SSH远程执行Shell脚本(转)

    原文地址:http://www.open-open.com/lib/view/open1384351384024.html 1. SSH简介         SSH是Secure Shell的缩写,一 ...

  4. Spring IOC的理解

            学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理 ...

  5. input中的name,value以及label中的for

    input具有很多属性,比较常用的有type,value,name,placeholder,multiple,checked等.对于其中的name.value.label相关以及标签外的文字,我一直是 ...

  6. Ch2 空间配置器(allocator) ---笔记

    2.1 空间配置器的标准接口 allocator的必要接口: allocator::value_type allocator::pointer allocator::const_pointer all ...

  7. C# CacheHelper

    using System; using System.Collections; using System.Collections.Generic; using System.Linq; using S ...

  8. 有哪些可以将网页另存图片的chrome插件?功能类似网页截图

    说实话chrome插件哪些,想找出最好最强的还真不容易,各有千秋.今天就概括性介绍下一些网页打印,图片另存为等常见需求的chrome插件.1.Awesome ScreenshotAwesome scr ...

  9. Substring (nyoj 308)

    练习使用字符串函数了. 1.字串的反转也是它的字串,2.最长,3.最先出现 string: #include<iostream> #include<cstdio> #inclu ...

  10. bat脚本学习

    工作需求,写个bat脚本来启动自己的守护进程:bat方面完全空白啊~稍微学习了下,记录下来,后面复习! 直接上代码: 示例一:for字符串切割,切割文本中的字符串: test.txt 文本内容如下: ...