SQL多表插入事务处理
新建两个需统一事务处理的数据表
--学生信息表
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("<", "<").Replace(">", ">");
}
把实体转换成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
, '&gt;','>')
, '&amp;gt;','>')
, '&lt;','<')
, '&amp;lt;', '<')
, '<', '<')
, '>', '>')
, '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)='<ArrayOfResult ><Result> <StudentId>1</StudentId> <Subject>语文</Subject> <Score>80</Score></Result><Result> <StudentId>1</StudentId> <Subject>数学</Subject> <Score>60</Score></Result></ArrayOfResult>' 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)='<ArrayOfResult ><Result> <StudentId>1</StudentId> <Subject>语文</Subject> <Score>80</Score></Result><Result> <StudentId>1</StudentId> <Subject>数学</Subject> <Score>60</Score></Result></ArrayOfResult>'
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="<Student ><StudentId>1</StudentId><Name>Johh</Name><Age>18</Age><Address>中国上海</Address></Student>"></SP><SP Name="Proc_Insert_Result" ProcIndex="2" ParameterName="ResultXml" ParameterValue="<ArrayOfResult ><Result> <StudentId>1</StudentId> <Subject>语文</Subject> <Score>80</Score></Result><Result> <StudentId>1</StudentId> <Subject>数学</Subject> <Score>60</Score></Result></ArrayOfResult>"></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多表插入事务处理的更多相关文章
- C# SQL 整表插入 分类: C# 2014-09-17 16:18 369人阅读 评论(2) 收藏
说明: (1)表A的一部分数据插入到表B (2)DataAccess 类,是放在DAL层下的底层类; da.StrConnection 写在DataAccess类中; //整表插入方法 private ...
- C# SQL 整表插入
说明: (1)表A的一部分数据插入到表B (2)DataAccess 类,是放在DAL层下的底层类; da.StrConnection 写在DataAccess类中; //整表插入方法 private ...
- SQL数据表插入随机数(转)
declare @T TABLE (id int identity(1,1),[Name] nvarchar(20), Randnum int) insert @T ([Name]) select ' ...
- MySQL中的多表插入更新与MS-SQL的对比
MySQL多表插入: INSERT INTO tdb_goods_cates (cate_name) SELECT goods_cate FROM tdb_goods GROUP BY goods_c ...
- 如何往有自增标识字段的表插入数据时,同时给自增标识字段插入值呢,在Inset Into语句前后加上SQL语句:SET IDENTITY_INSERT TableName ON和SET IDENTITY_INSERT TableName OFF
当要往有设置自增标识字段的表插入数据,并希望同时设置好自增字段的值时,可以在insert into 的SQL语句前后分别加上一句sql语句,SET IDENTITY_INSERT TableName ...
- SQL将一个表中的某一列值全部插入到另一个表中
1. SQL将一个表中的某一列值全部插入到另一个表中 插入的话: insert into a(col) select col from b; 更新的话: update a set col=selec ...
- 09Microsoft SQL Server 表数据插入,更新,删除
Microsoft SQL Server 表数据插入,更新,删除 向表中插入数据 INSERT INTO insert into tb1 values(0004,'张凤凤') insert into ...
- sql将一个表中的数据插入到另一个表中
sql将一个表中的数据插入到另一个表中 列名不一定要相同,只要你在HH中列出要插入列的列表跟select from mm表中的选择的列的列表一一对应就可以了,当然两边的数据类型应该是兼容的. ...
- sql实现同时向主表和子表插入数据方法
使用sql语句实现同时向主表和子表插入数据方法: Oracle: -- oracle创建sequence create sequence SEQ_test minvalue 1 maxvalue 99 ...
随机推荐
- Ubuntu下JDK+Tomcat+MySql环境的搭建
主机在阿里云上,所以网络的配置都省了,只剩下软件的安装和配置 1.安装mysql 1.1 apt-get install mysql-server-5.5 安装过程中,有两次提示输入 mysql 的 ...
- Oracle多关键字查询
因项目需要,在某查询页面的查询字段支持多关键字查询,支持空格隔开查询条件,故实现如下: 使用的原理是:ORACLE中的支持正则表达式的函数REGEXP_LIKE, '|' 指明两项之间的一个选择.例子 ...
- HostingEnvironment RegisterObject和QueueBackgroundWorkItem
其实网上关于HostingEnvironment 的RegisterObject和QueueBackgroundWorkItem文章已经很多了,典型是的 QueueBackgroundWorkItem ...
- CodeForces 157C Message
$dp$. $dp[i][j]$表示$s[i]$到$s[j]$和$t[lent-1+i-j]$到$t[lent-1]$有$dp[i][j]$位相同,然后枚举一遍$dp[i][j]$就可以算出答案了. ...
- sw代码问题
1.环境版本问题,myeclipse 配 jdk1.7 不能用jdk1.8 :jdk1.6满足不了代码本身 报错为:The type java.io.ObjectInputStream cannot ...
- Python2 基于urllib2 的HTTP请求类
一个利用urllib2模块编写的下载器,虽然有了requests模块,但是毕竟标准库 import urllib2,random class strong_down(): def __init__(s ...
- Python批量重命名
某无聊的下午的一个小需求 import os dirPath = r'' #路径 format = r'' #后缀 name = 0 for file in os.listdir(dirPath): ...
- public static void speckOnWin7(string text),在win7中读文字
public static void speckOnWin7(string text) { //洪丰写的,转载请注明 try { string lsSource = ""; ...
- VS辅助工具
tfs签入策略修改工具Team Foundation Server 2015 Power Tools(tfpt) 添加签入禁止策略 \*/bin \*/obj \*/Release \*/Debug ...
- Theos 工程make package时报错
错误: /Applications/Xcode.app/Contents/Developer/usr/bin/make package requires you to have a layout/ d ...