Sql server 在tsql中提交每个x记录

Sql server 在tsql中提交每个x记录,sql-server,tsql,Sql Server,Tsql,我来自oracle,对SQL Server有点困惑 我想在insert命令上停止SQL Server自动提交。因此,我正在使用开始事务。在下面的演示中,我将向测试表中插入100行,并在事务结束时回滚。我期望的结果是90行(commit应该是30、60和90行),rest10记录应该回滚 CREATE TABLE test (TEST_ID INT); GO DECLARE @cnt INT=0; BEGIN TRANSACTION t1; WHILE @cnt < 100 BEGIN

我来自oracle,对SQL Server有点困惑

我想在insert命令上停止SQL Server自动提交。因此,我正在使用
开始事务
。在下面的演示中,我将向测试表中插入100行,并在事务结束时回滚。我期望的结果是90行(commit应该是30、60和90行),rest10记录应该回滚

CREATE TABLE test (TEST_ID INT);
GO

DECLARE @cnt INT=0;
BEGIN TRANSACTION t1;

WHILE @cnt < 100
BEGIN
  INSERT INTO test values (@cnt); 
  SET @cnt += 1;

  if (@cnt %30 = 0)
    print 'commit '+cast(@cnt as varchar(100))
    COMMIT TRANSACTION t1;
END

rollback transaction t1;
GO
之后,我运行了脚本,但我得到了错误的结果和一些错误的地方

回滚事务请求没有相应的BEGIN事务

行数是100

我试图关闭我的连接并再次打开它bcs在oracle中插入100行,而不提交最后10行,其他人可以看到90行,但我看到100行,因为它已经保存在我的会话中。但看起来SQLServer在会话和事务中的行为有所不同

我面临的另一个问题是关于while循环内的commit,看起来它无法访问循环外的begin事务。当我运行命令时,我没有选择任何东西。只需按f5。即使我尝试了select命令并运行,但它仍然给了我以下错误:

提交事务请求没有相应的开始事务


我对SQL Server越来越着迷,我可以很容易地使用mysql和oracle,但是SQL Server…

分号没有达到您期望的效果。尝试更改此部分:

if (@cnt%30=0)
    BEGIN
        print 'commit '+cast(@cnt as varchar(100))
        COMMIT TRANSACTION t1
    END --IF @cnt
END --WHILE @cnt

代码在
WHILE
循环之外启动一个事务,尝试提交100次,然后尝试回滚。你说100?您的
IF
语句没有
BEGIN
/
END
来控制复合语句。
PRINT
将执行三次,但是
COMMIT
将执行100次

单个事务不能提交(或回滚)多次,因此会出现错误。如果,您可以提交一个事务,然后在
中启动另一个事务,但这会将回滚限制为仅插入最后一行。通常,您会启动一个事务,执行所有插入,然后提交或回滚

CREATE TABLE test (TEST_ID INT);
GO

DECLARE @cnt INT=0;
BEGIN TRANSACTION t1;

WHILE @cnt < 100
BEGIN
  INSERT INTO test values (@cnt); 
  SET @cnt += 1;

  if (@cnt %30 = 0)
    print 'commit '+cast(@cnt as varchar(100))
    COMMIT TRANSACTION t1;
END

rollback transaction t1;
GO

旁白:SQL Server中的嵌套事务不会按您的想法执行。有关详细信息,请参阅。

实际上Sql Server不支持嵌套事务。它将允许您开始嵌套事务,但不允许在这里和那里回滚。实现这一点的唯一方法是使用savetransaction语句。您可以向循环中的事务添加一些保存点,然后在循环外回滚到该保存点并提交事务。以下是一个例子:

DECLARE @cnt INT=0
Begin transaction

WHILE @cnt<100
BEGIN
  INSERT INTO test values (@cnt)
  SET @cnt+=1

  if (@cnt%30=0)
  begin
      save transaction t1
  end
END;

rollback transaction t1;
commit;

Select * from test
DECLARE@cnt INT=0
开始交易

@cntIt非常简单,真的:一旦你开始一个事务(
T1
),它就会一直存在,直到你对它调用
COMMIT
ROLLBACK
。所以,一旦您插入了30行,并调用
COMMIT
,事务
T1
就完成了。时期现在已经没有事务
T1
了-那么下次调用
COMMIT T1
ROLLBACK T1
?!?!?没有交易anymore@marc_s,感谢您的编辑,正如Giorgi Nakeuri所写,我需要保存事务,而不是提交。或者,我后来添加了打印以测试我的提交是否正确,最初它不在那里。如果我删除了print-i-get-commit-error,那么无论您尝试提交单个事务100次还是3次,它都看不到
T1
,这仍然太多了。你只有一次机会。