回滚SQL:通过ROLLBACK SQL查询回滚事务

The rollback SQL statement is used to manually rollback transactions in MS SQL Server.

回滚SQL语句用于在MS SQL Server中手动回滚事务。

Transactions in SQL Server are used to execute a set of SQL statements in a group. With transactions, either all the statements in a group execute or none of the statements execute.

SQL Server中的事务用于在一个组中执行一组SQL语句。 使用事务时,将执行组中的所有语句,或者不执行任何语句。

In the case where one of the queries in a group of queries executed by a transaction fails, all the previously executed queries are rollbacked. Transactions in the SQL server are rollbacked automatically. However, with the rollback SQL statement, you can manually rollback a transaction based on certain conditions.

在由事务执行的一组查询中的一个查询失败的情况下,将回滚所有先前执行的查询。 SQL Server中的事务会自动回滚。 但是,使用回滚SQL语句,您可以根据特定条件手动回滚事务。

In this article, you will see what a transaction is and how it can be rollbacked both manually and automatically.

在本文中,您将看到什么是事务以及如何手动和自动回滚事务。

First, let’s create a dummy dataset for you to practice on unless you are 100% confident that your database is fully backed.

首先,让我们创建一个虚拟数据集供您练习,除非您100%确信数据库已完全支持

创建一个虚拟数据库 (Create a dummy database)

The following script creates a dummy database named BookStore with one table, i.e., Books. The Books table has four columns: id, name, category, and price:

以下脚本使用一个表(即Books)创建一个名为BookStore的虚拟数据库。 Books表包含四列: idnamecategoryprice

CREATE Database BookStore;
GO
USE BookStore;
CREATE TABLE Books
(
id INT,
name VARCHAR(50) NOT NULL,
category VARCHAR(50) NOT NULL,
price INT NOT NULL
)

Let’s now add some dummy records in the Books table:

现在让我们在Books表中添加一些虚拟记录:

USE BookStore
 
INSERT INTO Books
 
VALUES
(1, 'Book1', 'Cat1', 1800),
(2, 'Book2', 'Cat2', 1500),
(3, 'Book3', 'Cat3', 2000),
(4, 'Book4', 'Cat4', 1300),
(5, 'Book5', 'Cat5', 1500),
(6, 'Book6', 'Cat6', 5000),
(7, 'Book7', 'Cat7', 8000),
(8, 'Book8', 'Cat8', 5000),
(9, 'Book9', 'Cat9', 5400),
(10, 'Book10', 'Cat10', 3200)

The above script adds 10 dummy records to the Books table.

上面的脚本将10条虚拟记录添加到Books表中。

在不使用事务的情况下执行多个查询 (Executing multiple queries without using transactions)

In this section, we will see the problems that occur if we execute multiple queries in a group without transactions. In the latter section, we will see how transactions can be used to automatically and manually rollback SQL queries and deal with these issues.

在本节中,我们将看到如果在没有事务的组中执行多个查询,则会出现问题。 在后面的部分中,我们将看到如何使用事务来自动和手动回滚SQL查询并处理这些问题。

Look at the following script:

看下面的脚本:

INSERT INTO Books 
VALUES (15, 'Book15', 'Cat5', 2000)
UPDATE Books
SET price = '25 Hundred' WHERE id = 15
DELETE from Books
WHERE id = 15

In the script above, we execute three queries. The first query inserts a new record in the Books table where the id of the record is 15. The second query updates the price of the book with id 15. Finally, the third query deletes the record with id 15. If you execute the above query, you should see the following error:

在上面的脚本中,我们执行三个查询。 第一个查询在Books表中插入一条新记录,该记录的ID为15。第二个查询更新ID为15的书的价格。最后,第三个查询删除ID为15的记录。查询,您应该看到以下错误:

Error message shown when SQL query fails

The error is pretty self-explanatory. It says that we cannot assign the string value ‘25 Hundred’ to the ‘id’ column, which is of integer type. Hence, the second query fails to execute. However, the problem with the above script is that while the second query fails, the first query still executes. You can verify this by selecting all the records from the Books table, as shown below:

该错误是不言自明的。 它说我们不能将字符串值“ 25 Hundred”分配给整数类型的“ id”列。 因此,第二个查询无法执行。 但是,上述脚本的问题在于,尽管第二个查询失败,但第一个查询仍然执行。 您可以通过从“书籍”表中选择所有记录来验证这一点,如下所示:

Result of query to show that some of the SQL queries did execute.

What if you really want is that if the second query fails, the first query should be rollbacked as well so that you go back to how you were before you executed the queries?

如果您真正想要的是,如果第二个查询失败,那么也应该回滚第一个查询,以便回到执行查询之前的状态?

To achieve this, you need to use transactions.

为此,您需要使用事务。

自动回滚SQL事务 (Automatically rollback SQL transactions)

As I said earlier, if one of the queries in a group of queries executed inside a transaction fails, all the previously executed SQL statements are rollbacked. Let’s see how transactions can be used to rollback SQL queries:

如前所述,如果在事务内执行的一组查询中的一个查询失败,则将回滚所有先前执行SQL语句。 让我们看看如何使用事务回滚SQL查询:

BEGIN TRANSACTION
 
  INSERT INTO Books 
  VALUES (20, 'Book15', 'Cat5', 2000)
 
  UPDATE Books
  SET price = '25 Hundred' WHERE id = 20
 
  DELETE from Books
  WHERE id = 20
 
COMMIT TRANSACTION

To start a transaction, the BEGIN TRANSACTION statement is used, followed by the set of queries that you want to execute inside the transaction. To mark the end of a transaction, the COMMIT TRANSACTION statement can be used.

要开始事务,将使用BEGIN TRANSACTION语句,然后使用要在事务内部执行的查询集。 为了标记事务的结束,可以使用COMMIT TRANSACTION语句。

In the script above, we execute the same three SQL queries that we did in the last section. However, this time the queries have been executed inside a transaction. Again, the first query will execute successfully and an error will occur while executing the second query. Since the queries are being executed inside a transaction, the failure of the second query will cause all the previously executed queries to rollback. Now, if you select all the records from the Books table, you will not see the new record with id 20, inserted by the first query inside the transaction.

在上面的脚本中,我们执行与上一部分相同的三个SQL查询。 但是,这一次查询已在事务内执行。 同样,第一个查询将成功执行,并且在执行第二个查询时将发生错误。 由于查询是在事务内部执行的,因此第二个查询的失败将导致所有先前执行的查询回滚。 现在,如果您从Books表中选择所有记录,您将看不到ID为20的新记录,该记录是由事务内部的第一个查询插入的。

手动回滚SQL事务 (Manually rollback SQL transactions)

In the previous section, you saw how transactions automatically rollback themselves if one of the queries cannot be executed successfully. However, you may want to rollback a query based on certain conditions as well. For example, you may want to rollback a transaction that inserts a record in the books table if a book with the same name already exists.

在上一节中,您了解了如果其中一个查询无法成功执行,事务如何自动回滚自身。 但是,您可能还希望根据某些条件回滚查询。 例如,您可能想回滚一个事务,如果已经存在同名的书,则该事务会在books表中插入一条记录。

In that case, you can use the rollback SQL statement.

在这种情况下,您可以使用回滚SQL语句。

Look at the following example:

看下面的例子:

DECLARE @BookCount int
 
BEGIN TRANSACTION AddBook
 
  INSERT INTO Books
  VALUES (20, 'Book15', 'Cat5', 2000)
 
  SELECT @BookCount = COUNT(*) FROM Books WHERE name = 'Book15'
 
  IF @BookCount > 1
    BEGIN 
      ROLLBACK TRANSACTION AddBook
      PRINT 'A book with the same name already exists'
    END
  ELSE
    BEGIN
      COMMIT TRANSACTION AddStudent
      PRINT 'New book added successfully'
    END

In the script above, we declare a variable @BookCount. Next, we create a transaction named AddBook. To create a named transaction, you simply have to pass any string name for the transaction after the BEGIN TRANSACTION statement.

在上面的脚本中,我们声明一个变量@BookCount。 接下来,我们创建一个名为AddBook的事务。 要创建命名事务,您只需在BEGIN TRANSACTION语句之后传递该事务的任何字符串名称。

Inside the transaction, a book with id 20 and name Book15 is inserted in the Books table. After that, the COUNT function is used to count the Books with the name Book15.

在事务内部,将ID为20且名称为Book15的书插入Books表中。 之后,使用COUNT函数对名称为Book15的书进行计数。

If the count is greater than 1, that means a book already exists with the name Book15. In this case, the rollback SQL statement is used to rollback the AddBook transaction manually; otherwise, the transaction will be committed and an appropriate message is displayed to the reader.

如果计数大于1,则表示一本名为Book15的书已经存在。 在这种情况下,使用回滚SQL语句手动回滚AddBook事务。 否则,事务将被提交,并向阅读器显示一条适当的消息。

You can see that the syntax of the rollback SQL statement is simple. You just have to write the statement ROLLBACK TRANSACTION, followed by the name of the transaction that you want to rollback.

您可以看到回滚SQL语句的语法很简单。 您只需要编写语句ROLLBACK TRANSACTION,后跟要回滚的事务的名称。

Now, try to run the AddBook transaction to insert the record where the name is Book15 (make sure that no book with this name already exists in the Books table).

现在,尝试运行AddBook事务以插入名称为Book15的记录(确保“书籍”表中不存在具有该名称的书籍)。

You will see that the transaction will execute successfully, and the following message will be displayed to the reader:

您将看到事务将成功执行,并且以下消息将显示给阅读器:

Message showing successful execution of a transaction

Now, again try to run the AddBook transaction. You will see that this time the transaction will fail since a book with the name Book15 already exists in the database. Therefore the transaction will be rolled back with the following message displayed to the user:

现在,再次尝试运行AddBook事务。 您将看到这次交易将失败,因为数据库中已经存在名称为Book15的书。 因此,该事务将回滚,并向用户显示以下消息:

Error message set by transaction explaining that 'a book with this name already exists'

结论 (Conclusion)

The article explains how to rollback SQL queries using transactions. Queries can be automatically or manually rolled back via transactions. Automatic rollback happens when a query fails to execute for any reason. Manual rollback occurs depending on user-defined conditions. The rollback SQL statement is used to manually rollback SQL queries in SQL Server.

本文介绍了如何使用事务回滚SQL查询。 查询可以通过事务自动或手动回滚。 当查询由于任何原因而无法执行时,就会发生自动回滚。 手动回滚取决于用户定义的条件。 回滚SQL语句用于在SQL Server中手动回滚SQL查询。

翻译自: https://www.sqlshack.com/rollback-sql-rolling-back-transactions-via-the-rollback-sql-query/

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值