求一简单存储过程 求一个简单存储过程 table id name 001 aa 002 bb 我要用存储过程往这表中插入记录当插入成功就返回一个标识给我 ,,用事务提交当插入失败就也返回一个标识给我 ,,事务就回滚请问怎么来写!! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 事务全攻略1.1. 事务的属性事务具有ACID属性即 Atomic原子性, Consistent一致性, Isolated隔离性, Durable永久性原子性 就是事务应作为一个工作单元,事务处理完成,所有的工作要么都在数据库中保存下来,要么完全回滚,全部不保留一致性 事务完成或者撤销后,都应该处于一致的状态隔离性 多个事务同时进行,它们之间应该互不干扰.应该防止一个事务处理其他事务也要修改的数据时,不合理的存取和不完整的读取数据永久性 事务提交以后,所做的工作就被永久的保存下来1.2. 事务并发处理会产生的问题丢失更新 当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题、每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。脏读 当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。 第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。不可重复读 当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。 不一致的分析与未确认的相关性类似,因为其它事务也是正在更改第二个事务正在读取的数据。 然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其它事务更改;因而该行被非重复读取。幻像读 当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。 事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。1.3. 事务处理类型自动处理事务 系统默认每个T-SQL命令都是事务处理 由系统自动开始并提交隐式事务 当有大量的DDL 和DML命令执行时会自动开始,并一直保持到用户明确提交为止,切换隐式事务可以用SET IMPLICIT_TRANSACTIONS为连接设置隐性事务模式.当设置为 ON 时,SET IMPLICIT_TRANSACTIONS 将连接设置为隐性事务模式。当设置为 OFF 时,则使连接返回到自动提交事务模式用户定义事务 由用户来控制事务的开始和结束 命令有: begin tran commit tran rollback tran 命令分布式事务 跨越多个服务器的事务称为分布式事务,sql server 可以由DTc microsoft distributed transaction coordinator来支持处理分布式事务,可以使用 BEgin distributed transaction 命令启动一个分布式事务处理。1.4. 事务处理的隔离级别使用SET TRANSACTION ISOLATION LEVEL来控制由连接发出的所有语句的默认事务锁定行为从低到高依次是:READ UNCOMMITTED执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。举例设table1(A,B,C)A B Ca1 b1 c1a2 b2 c2a3 b3 c3新建两个连接在第一个连接中执行以下语句select * from table1begin tranupdate table1 set c='c'select * from table1waitfor delay '00:00:10' --等待10秒rollback transelect * from table1在第二个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDprint '脏读'select * from table1if @@rowcount>0begin waitfor delay '00:00:10' print '不重复读' select * from table1en第二个连接的结果脏读A B Ca1 b1 ca2 b2 ca3 b3 c'不重复读'A B Ca1 b1 c1a2 b2 c2a3 b3 c3READ COMMITTED指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是 SQL Server 的默认值。在第一个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL READ COMMITTEDbegin tranprint '初始'select * from table1waitfor delay '00:00:10' --等待10秒print '不重复读'select * from table1rollback tran在第二个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL READ COMMITTEDupdate table1 set c='c'第一个连接的结果初始A B Ca1 b1 c1a2 b2 c2a3 b3 c3 不重复读A B Ca1 b1 ca2 b2 ca3 b3 c REPEATABLE READ锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。在第一个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL REPEATABLE READbegin tranprint '初始'select * from table1waitfor delay '00:00:10' --等待10秒print '幻像读'select * from table1rollback tran在第二个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL REPEATABLE READinsert table1 select 'a4','b4','c4'第一个连接的结果初始A B Ca1 b1 c1a2 b2 c2a3 b3 c3幻像读A B Ca1 b1 c1a2 b2 c2a3 b3 c3a4 b4 c4 SERIALIZABLE在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。 在第一个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL SERIALIZABLEbegin tranprint '初始'select * from table1waitfor delay '00:00:10' --等待10秒print '没有变化'select * from table1rollback tran在第二个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL SERIALIZABLEinsert table1 select 'a4','b4','c4'第一个连接的结果初始A B Ca1 b1 c1a2 b2 c2a3 b3 c3 没有变化A B Ca1 b1 c1a2 b2 c2a3 b3 c31.5. 事务处理嵌套语法和对@@TRANCOUNT的影响l ? BEGIN TRAN @@TRANCOUNT+1l ? COMMIT TRAN @@TRANCOUNT-1l ? ROLLBACK TRAN 使@@TRANCOUNT回归0l ? SAVE TRAN 不影响@@TRANCOUNT例一SELECT '事务处理前', @@TRANCOUNT --值为 0BEGIN TRAN SELECT '第一个事务', @@TRANCOUNT --值为 1 SELECT * FROM table1 BEGIN TRAN SELECT '第二个事务', @@TRANCOUNT --值为 2 DELETE table1 COMMIT TRAN SELECT '递交第二个事务', @@TRANCOUNT --值为 1ROLLBACK TRANSELECT '回滚第一个事务', @@TRANCOUNT --值为 0 例二SELECT '事务处理前', @@TRANCOUNT --值为 0BEGIN TRAN SELECT '第一个事务', @@TRANCOUNT --值为 1 SELECT * FROM table1 SAVE TRAN t1 SELECT '保存第一个事务后', @@TRANCOUNT --值为 1 BEGIN TRAN SELECT '第二个事务', @@TRANCOUNT --值为 2 DELETE table1 ROLLBACK TRAN t1 SELECT '回滚到保存点t1', @@TRANCOUNT --注意这里的值为 2 IF @@TRANCOUNT>0ROLLBACK TRANSELECT '处理结束', @@TRANCOUNT --为 0 SET XACT_ABORT控制语句产生运行时错误时,是否自动回滚当前事务比如SET XACT_ABORT ONBEGIN TRAN SELECT * FROM 一个不存在的表ROLL BACKTRANPRINT '处理完毕' --执行结果没有到这一步goSELECT @@TRANCOUNT --值为1 产生孤立事务1.6. 事务调试语句DBCC OPENTRAN如果在指定数据库内存在最旧的活动事务和最旧的分布和非分布式复制事务,则显示与之相关的信息。示例下例获得当前数据库和 pubs 数据库的事务信息。-- Display transaction information only for the current database.DBCC OPENTRANGO-- Display transaction information for the pubs database.DBCC OPENTRAN('pubs')GO1.7. 事务嵌套的例子1) 如果内层事务出错就取消所有事务BEGIN TRAN t1 UPDATE tablename SET colname='37775' WHERE id='140' BEGIN TRAN t2 UPDATE tablename SET colname='37775' WHERE id='140' --id不存在 IF (@@rowcount=0) BEING ROLLBAKC TRAN END ELSE BEGIN COMMIT TRAN t2 COMMIT TRAN t1 END2) 事务处理中只要有一个出错就回滚BEGIN TRAN UPDATE tablename SET colname='37775' WHERE id=170 IF ( @@rowcount=0 ) ROLLBACK TRAN UPDATE tablename SET colname='37775' WHERE id=870 --此id不存在 IF ( @@rowcount=0 ) ROLLBACK TRAN3) 有关循环处理事务的问题,要求循环处理中,如果一个条件不满足就取消所有循环DECLARE @id INTSET @id=1 WHILE (@id<280) --注表中实际id最大为260,所以此循环执行到@id=261 update语句就没有作用了 BEGIN BEGIN TRAN UPDATE tablename SET colname='37775' WHERE id=@id IF ( @@rowcount=0 ) ROLLBACK TRAN SET @id=@id+1 END 如何将数据库中同一列的字符串都连接起来 discuz 最新版有什么功能了? 怎么解决一台机安装MSSQL2000和2005时默认实例更改 好难写的sql啊,关于DISTINCT,大家来帮忙看下 如何在SQL Server的存储过程里调用HTTP请求? sql 查询问题 存储过程创建中insert into select from 出错 大力快帮帮我?? 有关sql server2005 express float varchar类型转换 like后面不能跟子查询,如何实现这种功能? 大侠救命 EXCEL和SQL连接问题
事务全攻略
1.1. 事务的属性
事务具有ACID属性即 Atomic原子性, Consistent一致性, Isolated隔离性, Durable永久性
原子性
就是事务应作为一个工作单元,事务处理完成,所有的工作要么都在数据库中保存下来,要么完全回滚,全部不保留
一致性
事务完成或者撤销后,都应该处于一致的状态
隔离性
多个事务同时进行,它们之间应该互不干扰.应该防止一个事务处理其他事务也要修改的数据时,不合理的存取和不完整的读取数据
永久性
事务提交以后,所做的工作就被永久的保存下来1.2. 事务并发处理会产生的问题
丢失更新
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题、每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。
脏读
当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。
第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。
不可重复读
当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。
不一致的分析与未确认的相关性类似,因为其它事务也是正在更改第二个事务正在读取的数据。
然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其它事务更改;因而该行被非重复读取。
幻像读
当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。
事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。
1.3. 事务处理类型
自动处理事务
系统默认每个T-SQL命令都是事务处理 由系统自动开始并提交
隐式事务
当有大量的DDL 和DML命令执行时会自动开始,并一直保持到用户明确提交为止,切换隐式事务可以用SET IMPLICIT_TRANSACTIONS为连接设置隐性事务模式.当设置为 ON 时,SET IMPLICIT_TRANSACTIONS 将连接设置为隐性事务模式。当设置为 OFF 时,则使连接返回到自动提交事务模式
用户定义事务
由用户来控制事务的开始和结束 命令有: begin tran commit tran rollback tran 命令
分布式事务
跨越多个服务器的事务称为分布式事务,sql server 可以由DTc microsoft distributed transaction coordinator来支持处理分布式事务,可以使用 BEgin distributed transaction 命令启动一个分布式事务处理。
1.4. 事务处理的隔离级别
使用SET TRANSACTION ISOLATION LEVEL来控制由连接发出的所有语句的默认事务锁定行为
从低到高依次是:
READ UNCOMMITTED
执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。
举例
设table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3
新建两个连接
在第一个连接中执行以下语句
select * from table1
begin tran
update table1 set c='c'
select * from table1
waitfor delay '00:00:10' --等待10秒
rollback tran
select * from table1
在第二个连接中执行以下语句
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDprint '脏读'select * from table1if @@rowcount>0begin waitfor delay '00:00:10' print '不重复读' select * from table1en第二个连接的结果脏读A B Ca1 b1 ca2 b2 ca3 b3 c
'不重复读'A B Ca1 b1 c1a2 b2 c2a3 b3 c3READ COMMITTED指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是 SQL Server 的默认值。在第一个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL READ COMMITTEDbegin tranprint '初始'select * from table1waitfor delay '00:00:10' --等待10秒print '不重复读'select * from table1rollback tran在第二个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL READ COMMITTEDupdate table1 set c='c'第一个连接的结果初始
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3
不重复读
A B C
a1 b1 c
a2 b2 c
a3 b3 c
REPEATABLE READ
锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。在第一个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
begin tran
print '初始'
select * from table1
waitfor delay '00:00:10' --等待10秒
print '幻像读'
select * from table1
rollback tran在第二个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL REPEATABLE READinsert table1 select 'a4','b4','c4'第一个连接的结果
初始
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3幻像读
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3
a4 b4 c4 SERIALIZABLE
在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。
在第一个连接中执行以下语句
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin tran
print '初始'
select * from table1
waitfor delay '00:00:10' --等待10秒
print '没有变化'
select * from table1
rollback tran在第二个连接中执行以下语句SET TRANSACTION ISOLATION LEVEL SERIALIZABLEinsert table1 select 'a4','b4','c4'
第一个连接的结果初始A B Ca1 b1 c1a2 b2 c2a3 b3 c3 没有变化A B Ca1 b1 c1a2 b2 c2a3 b3 c31.5. 事务处理嵌套语法和对@@TRANCOUNT的影响
l ? BEGIN TRAN @@TRANCOUNT+1l ? COMMIT TRAN @@TRANCOUNT-1l ? ROLLBACK TRAN 使@@TRANCOUNT回归0l ? SAVE TRAN 不影响@@TRANCOUNT例一SELECT '事务处理前', @@TRANCOUNT --值为 0BEGIN TRAN SELECT '第一个事务', @@TRANCOUNT --值为 1 SELECT * FROM table1 BEGIN TRAN SELECT '第二个事务', @@TRANCOUNT --值为 2 DELETE table1 COMMIT TRAN SELECT '递交第二个事务', @@TRANCOUNT --值为 1ROLLBACK TRANSELECT '回滚第一个事务', @@TRANCOUNT --值为 0 例二SELECT '事务处理前', @@TRANCOUNT --值为 0BEGIN TRAN SELECT '第一个事务', @@TRANCOUNT --值为 1 SELECT * FROM table1 SAVE TRAN t1 SELECT '保存第一个事务后', @@TRANCOUNT --值为 1 BEGIN TRAN SELECT '第二个事务', @@TRANCOUNT --值为 2 DELETE table1 ROLLBACK TRAN t1 SELECT '回滚到保存点t1', @@TRANCOUNT --注意这里的值为 2 IF @@TRANCOUNT>0ROLLBACK TRANSELECT '处理结束', @@TRANCOUNT --为 0 SET XACT_ABORT控制语句产生运行时错误时,是否自动回滚当前事务比如SET XACT_ABORT ONBEGIN TRAN SELECT * FROM 一个不存在的表ROLL BACKTRANPRINT '处理完毕' --执行结果没有到这一步goSELECT @@TRANCOUNT --值为1 产生孤立事务1.6. 事务调试语句
DBCC OPENTRAN如果在指定数据库内存在最旧的活动事务和最旧的分布和非分布式复制事务,则显示与之相关的信息。示例下例获得当前数据库和 pubs 数据库的事务信息。-- Display transaction information only for the current database.DBCC OPENTRANGO-- Display transaction information for the pubs database.DBCC OPENTRAN('pubs')GO1.7. 事务嵌套的例子
1) 如果内层事务出错就取消所有事务BEGIN TRAN t1 UPDATE tablename SET colname='37775' WHERE id='140' BEGIN TRAN t2 UPDATE tablename SET colname='37775' WHERE id='140' --id不存在 IF (@@rowcount=0) BEING ROLLBAKC TRAN END ELSE BEGIN COMMIT TRAN t2 COMMIT TRAN t1 END2) 事务处理中只要有一个出错就回滚BEGIN TRAN UPDATE tablename SET colname='37775' WHERE id=170 IF ( @@rowcount=0 ) ROLLBACK TRAN UPDATE tablename SET colname='37775' WHERE id=870 --此id不存在 IF ( @@rowcount=0 ) ROLLBACK TRAN3) 有关循环处理事务的问题,要求循环处理中,如果一个条件不满足就取消所有循环DECLARE @id INTSET @id=1 WHILE (@id<280) --注表中实际id最大为260,所以此循环执行到@id=261 update语句就没有作用了 BEGIN BEGIN TRAN UPDATE tablename SET colname='37775' WHERE id=@id IF ( @@rowcount=0 ) ROLLBACK TRAN SET @id=@id+1 END