>

事务处理,中的回滚

- 编辑:澳门新葡亰平台游戏 -

事务处理,中的回滚

Use TestDB

Begin TransAction
    Insert Into Person(PersonId,PersonName)
                Values('1','Name1')
    Insert Into Person(PersonId,PersonName)
                Values('1','Name1')
    Insert Into Person(PersonId,PersonName)
                Values('3','Name3')
Commit TransAction
/*
    Select 一下 有'1','Name1'和'3','Name3',
    说明只有第二句的错误被取消了
*/

  COMMIT TRAN Tran_2015_09_30 --执行事务

  • Oracle:alter table table_name modify column_name datatype
  • SQL Server:alter table table_name alter column_name datatype

全部回滚方法2:使用Try...Catch

insert into [water].[dbo].[ErrorInf]([ID],ErrorMessage,[Description])
Values(1,'test1','test1')

3.多表连接
  对于自然连接,Oracle支持natural join以及using关键字的用法,而SQL Server不支持。
  在from子句中使用子查询时,Oracle使用或不使用表别名都是可以的。若使用表别名,则不能附带as关键字。如下面子查询:

默认情况下如果执行一个事务中出现错误,则只回滚错误操作语句(就是说这句不执行了,算不上回滚),错误处之前或之后的正确操作语句还是会被提交。如:

  insert into tb1(Id, c1) values(2,'2')  

select * from dept where dname like '[0-9][0-9][a-z]%';
USE [TestDB]
GO
/****** 对象:  Table [dbo].[Person]    脚本日期: 11/23/2008 13:37:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Person](
    [PersonId] [nchar](18) NOT NULL,
    [PersonName] [nchar](20) NOT NULL,
 CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED 
(
    [PersonId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

begin tran t1 ---启动一个事务

2.字符串条件
  SQL Server除了支持like关键字、“%”及“_”作为通配符以及使用escape关键字指定转义字符进行模糊匹配查询,还支持正则表达式中的方括号用法,以匹配指定范围内或者方括号所指定集合中的任意单个字符。
  SQL Server支持的方括号用法有两种形式,[]与[^],前者用于包含某些字符,后者用于不包含某些字符,举例如下。

Use TestDB
Declare @tranError int -- 定义变量
Set @tranError=0
    Begin TransAction
        Insert Into Person(PersonId,PersonName)
                    Values('1','Name1')
            Set @tranError = @tranError + @@Error
        Insert Into Person(PersonId,PersonName)
                    Values('1','Name1')
            Set @tranError = @tranError + @@Error
        Insert Into Person(PersonId,PersonName)
                    Values('3','Name3')
            Set @tranError = @tranError + @@Error
    If @tranError = 0
        Commit TransAction
    Else
        Rollback TransAction
/*
    自定义一个变量来判断最后是否发生过错误。
*/

GO

select emp_name=ename,salary=sal from emp;
Use TestDB
SET XACT_ABORT ON -- 打开
Begin TransAction
    Insert Into Person(PersonId,PersonName)
                Values('1','Name1')
    Insert Into Person(PersonId,PersonName)
                Values('1','Name1')
    Insert Into Person(PersonId,PersonName)
                Values('3','Name3')
Commit TransAction
/*
    当 SET XACT_ABORT 为 ON 时,
    如果执行 Transact-SQL 语句产生运行时错误,
    则整个事务将终止并回滚。 
    默认情况下它是OFF状态。
*/

CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED

select top 3 ename,sal from emp order by sal desc
except
select top 2 ename,sal from emp order by sal desc;

全部回滚的方法1:打开 XACT_ABORT

  set @iErrorCount=@iErrorCount+@@error  

但是SQL Server要修必须使用表别名,且附带或不附带as都支持:

最后要注意的是:如果一个事务写了 Begin TransAction 而没写 Commit TransAction 或 Rollback TransAction 则相关操作的数据(也许是表,也许是列,这我还没测试。。。)会被锁住。。。而对于锁住的解决办法就是单独执行一下Commit TransAction 或 Rollback TransAction

     [c2] [datetime] NULL,

如果要查询排序后的第n航记录,可以由前n行结果除去前n-1行结果,如要查询emp表中sql值排名第三的记录:

Use TestDB
Begin Try
    Begin TransAction
        Insert Into Person(PersonId,PersonName)
                    Values('1','Name1')
        Insert Into Person(PersonId,PersonName)
                    Values('1','Name1')
        Insert Into Person(PersonId,PersonName)
                    Values('3','Name3')
    Commit TransAction
End Try
Begin Catch
    Rollback TransAction
End Catch
/*
    使用TryCatch来捕获异常。
    如果 TRY 块内生成的错误导致当前事务的状态失效,
    则将该事务归类为不可提交的事务。
    如果通常在 TRY 块外中止事务的错误在 TRY 内发生时,
    就会导致事务进入不可提交状态。
    不可提交的事务只能执行读操作或 ROLLBACK TRANSACTION。
    该事务不能执行任何可能生成写操作或 COMMIT TRANSACTION 的 Transact-SQL 语句。
    如果事务被分类为不可提交的事务,则 XACT_STATE 函数会返回值 -1。
*/

--解决方案(三)

4.查询排序后的前n行或第n行记录

全部回滚方法3:自定义错误变量

declare   @iErrorCount   int  

select a.ename,a.sal from
(select top 3 ename,sal from emp order by sal desc) as a
except
select a.ename,a.sal from
(select top 2 ename,sal from emp order by sal desc) as a;

  insert into tb1(Id, c1) values('xxxx3','3')  

1.列别名
  除了支持oracle的列表名语法形式之外,还支持把列别名置于列名之前,并附加等号:

set @iErrorCount = 0  

①修改数据类型
  Oracle和SQL Server分别使用modify与alter column关键字修改列的数据类型,两者的语法为:

if @iErrorCount=0

5.集合运算
  对与集合的差运算,Oracle使用minus运算符,而SQL Server使用except运算符。

     [Id] ASC

②修改列名
  Oracle使用alter table附加rename column子句来修改列名:

 SQL Server 事务处理 回滚事务  ;

GO

#未使用别名
select ename from (select * from emp where deptno=20);
#使用别名
select ename from (select * from emp where deptno=20) e;

(

6.null值在排序(order by)中的处理
  在SQL Server的查询中,如果order by附加了asc选项,即升序排序,则null值排在其他非空值之前;如果order by子句附加了desc,则null值排在其他非空值之后,也可以认为在SQL Server中,null值最小,这与Oracle的处理方式正好相反。

 

SQL Server不支持Oracle中的rownum关键字,而row_number()函数的用法与Oracle相同。
  相对于Oracle的实现方式,使用top n的用法,在SQL Server中可以很容易地实现取出表中前n行的目的。如查询emp表中的sal值最高的前3条记录:

 

  • [amd]:表示包含a、m、d三个字符中的任意一个
  • [^amd]:表示不包含a、m、d三个字符中的任意一个
  • [b-f]:表示英文字母表中b到f之中的任意一个
  • [0-9]:表示0到9这10个数字中的任意一个
      如查询dept表的dname列中的第一及第二字符为数字,第三个字符为小写英文字母的记录,可以使用如下语句:

  set @iErrorCount=@iErrorCount+@@error  

8.修改表结构

--创建表:

但是SQL不支持以下做法:

begin try
     begin tran Tran_2015_09_30
 
        insert into tb1(Id, c1) values(1,'1')
 
        insert into tb1(Id, c1) values(2,'2')
 
        insert into tb1(Id, c1) values('xxxx3','3')
 
        insert into tb1(Id, c1) values(4,'4')
 
        insert into tb1(Id, c1) values(5,'5')
 
    COMMIT TRAN Tran_2015_09_30
end try
begin catch
     raiserror 50005N'出错了'
     ROLLBACK TRAN Tran_2015_09_30  --回滚事务
end catch

7.null处理函数
  对应于Oracle的nvl()函数,SQL Server提供的null处理函数为isnull(),其用法与Oracle的nvl()相同。

begin    

select ename from (select * from emp where deptno=20) e;
select ename from (select * from emp where deptno=20) as e;

end

  • top n
  • row_number()

end

SQL Server中实现取出表中的前n行,可以使用两种方法:

)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY] )

select top 3 ename,sal from emp order by sal desc;

--解决方案(二)

select ename,sal+isnull(comm,0) from emp;

 

alter table tablename rename column old_column_name to new_column_name;

     [c1] [nvarchar](50) NULL,

begin tran Tran_2015_09_30

ON [PRIMARY]

--set XACT_ABORT ON   ---如果不设置该项为ON,在sql中默认为OFF,那么只只回滚产生错误的 Transact-SQL 语句;设为ON,回滚整个事务

  set @iErrorCount=@iErrorCount+@@error  

 

else  

  ROLLBACK TRAN Tran_2015_09_30 --回滚事务

  insert into tb1(Id, c1) values(1,'1')  

begin    

 

--解决方案(一)

 

2. 代码泪 SQL Server 事务及回滚事务

GO

  insert into tb1(Id, c1) values(4,'4')  

  set @iErrorCount=@iErrorCount+@@error  

--//参考:

 

  insert into tb1(Id, c1) values(5,'5')  

CREATE TABLE [dbo].[tb1](

GO

  1. EmanLee, Eman Lee's Space (blog, website)

commit tran t1  ---提交事务

     [Id] [int] NOT NULL,

 

  set @iErrorCount=@iErrorCount+@@error  

 

 

update [water].[dbo].[ErrorInf]
set ErrorMessage='test'
where ID=6

GO

SET XACT_ABORT ON  --语句产生运行时错误,则整个事务将终止并回滚。
Begin Tran
    INSERT INTO tb1(Id, c1) VALUES(1,'1')
    INSERT INTO tb1(Id, c1) VALUES('XX2','2') --此句产生错误时,就会回滚整个事务
Commit Tran

本文由数据库发布,转载请注明来源:事务处理,中的回滚