SQL 中的 Savepoint17 Mar 2025 | 5 分钟阅读 - Savepoint 是 SQL 中的一个命令,与 rollback 命令一起使用。
- 它是事务控制语言 (TCL) 中的一个命令,用于标记表中的事务。
- 假设您正在创建一个非常大的表,并且只想回滚到表中的某个特定位置,那么可以使用 savepoint 来实现这一点。
- 如果您在表中进行了事务操作,您可以为该事务标记一个特定的名称,之后如果您想回滚到该点,您可以通过事务的名称轻松实现。
- 当我们需要回滚表的一部分而不是整个表时,Savepoint 非常有用。简单来说,我们可以说 savepoint 是 SQL 中的一个书签。
让我们通过实际示例来更清楚地理解这个概念。我们将使用 MySQL 数据库来编写所有查询。 要在数据库中创建表,首先需要选择要在其中创建表的数据库。 然后我们将编写一个查询,在选定的数据库 'dbs' 中创建一个名为 student 的表。 现在,我们将编写一个查询来一次性向 student 表插入多条记录。
 为了验证多条记录是否已插入 student 表,我们将执行 SELECT 查询。
ID | 名称 | 百分比 | 地点 | 出生日期 |
---|
1 | Manthan Koli | 79 | 德里 | 2003-08-20 | 2 | Dev Dixit | 75 | Pune | 1999-06-17 | 3 | Aakash Deshmukh | 87 | 孟买 | 1997-09-12 | 4 | Aaryan Jaiswal | 90 | 金奈 | 2005-10-02 | 5 | Rahul Khanna | 92 | Ambala | 1996-03-04 | 6 | Pankaj Deshmukh | 67 | Kanpur | 2000-02-02 | 7 | Gaurav Kumar | 84 | 昌迪加尔 | 1998-07-06 | 8 | Sanket Jain | 61 | 西姆拉 | 1990-09-08 | 9 | Sahil Wagh | 90 | 加尔各答 | 1968-04-03 |
结果表明所有十条记录都已成功插入。 要使用 SQL 中的 TCL 命令,我们首先需要使用 BEGIN / START TRANSACTION 命令来启动事务。
 我们将使用 SAVEPOINT 命令以及一些特定的 savepoint 名称来保存已启动的事务。 在这里,我们已将启动的事务保存为名为 'ini' 的 savepoint。  然后,我们决定插入 ID 为 10 的新记录到现有的 student 表中。
 我们将执行 SELECT 查询来验证 ID 为 10 的新记录是否已成功插入。
ID | 名称 | 百分比 | 地点 | 出生日期 |
---|
1 | Manthan Koli | 79 | 德里 | 2003-08-20 | 2 | Dev Dixit | 75 | Pune | 1999-06-17 | 3 | Aakash Deshmukh | 87 | 孟买 | 1997-09-12 | 4 | Aaryan Jaiswal | 90 | 金奈 | 2005-10-02 | 5 | Rahul Khanna | 92 | Ambala | 1996-03-04 | 6 | Pankaj Deshmukh | 67 | Kanpur | 2000-02-02 | 7 | Gaurav Kumar | 84 | 昌迪加尔 | 1998-07-06 | 8 | Sanket Jain | 61 | 西姆拉 | 1990-09-08 | 9 | Sahil Wagh | 90 | 加尔各答 | 1968-04-03 | 10 | Saurabh Singh | 54 | Kashmir | 1989-01-06 |
为了保存包含此新插入记录的事务,我们将创建一个新的 savepoint。
 在这里,新插入的记录表已保存为名为 'ins' 的 savepoint。 为了在 student 表中更新 ID 为 1 的记录,并将其名称设置为 'Mahesh Kuwar',我们将执行以下查询。
 为了验证 ID 为 1 的记录的 name 字段是否已成功更新,我们将再次执行 SELECT 查询。
ID | 名称 | 百分比 | 地点 | 出生日期 |
---|
1 | Mahesh Kuwar | 79 | 德里 | 2003-08-20 | 2 | Dev Dixit | 75 | Pune | 1999-06-17 | 3 | Aakash Deshmukh | 87 | 孟买 | 1997-09-12 | 4 | Aaryan Jaiswal | 90 | 金奈 | 2005-10-02 | 5 | Rahul Khanna | 92 | Ambala | 1996-03-04 | 6 | Pankaj Deshmukh | 67 | Kanpur | 2000-02-02 | 7 | Gaurav Kumar | 84 | 昌迪加尔 | 1998-07-06 | 8 | Sanket Jain | 61 | 西姆拉 | 1990-09-08 | 9 | Sahil Wagh | 90 | 加尔各答 | 1968-04-03 | 10 | Saurabh Singh | 54 | Kashmir | 1989-01-06 |
为了保存包含此更新记录的事务,我们将创建一个新的 savepoint。
 在这里,包含更新记录的表已保存为名为 'upd' 的 savepoint。 为了从 student 表中删除 ID 为 6 的记录,我们将执行以下查询。
 我们将再次执行 SELECT 查询,以验证 ID 为 6 的记录是否已成功删除。
ID | 名称 | 百分比 | 地点 | 出生日期 |
---|
1 | Mahesh Kuwar | 79 | 德里 | 2003-08-20 | 2 | Dev Dixit | 75 | Pune | 1999-06-17 | 3 | Aakash Deshmukh | 87 | 孟买 | 1997-09-12 | 4 | Aaryan Jaiswal | 90 | 金奈 | 2005-10-02 | 5 | Rahul Khanna | 92 | Ambala | 1996-03-04 | 7 | Gaurav Kumar | 84 | 昌迪加尔 | 1998-07-06 | 8 | Sanket Jain | 61 | 西姆拉 | 1990-09-08 | 9 | Sahil Wagh | 90 | 加尔各答 | 1968-04-03 | 10 | Saurabh Singh | 54 | Kashmir | 1989-01-06 |
为了保存包含此已删除记录的事务,我们将创建一个新的 savepoint。
 在这里,包含已删除记录的表已保存为名为 'del' 的 savepoint。 之后,我们决定需要 student 表中已在上一 D 步中删除的记录。 由于我们在每一步操作中都创建了一个 savepoint。使用该 savepoint,我们可以跳转到事务的任何一个点。要做到这一点,我们将执行 ROLLBACK 命令以及我们要跳转到的 savepoint 名称。
 由于我们不希望 ID 为 6 的记录从 student 表中删除,因此我们已回滚到名为 upd 的 savepoint。 为了验证我们是否已获得与先前步骤中更新 student 表后的精确表状态相同,我们将再次执行 SELECT 查询。
ID | 名称 | 百分比 | 地点 | 出生日期 |
---|
1 | Mahesh Kuwar | 79 | 德里 | 2003-08-20 | 2 | Dev Dixit | 75 | Pune | 1999-06-17 | 3 | Aakash Deshmukh | 87 | 孟买 | 1997-09-12 | 4 | Aaryan Jaiswal | 90 | 金奈 | 2005-10-02 | 5 | Rahul Khanna | 92 | Ambala | 1996-03-04 | 6 | Pankaj Deshmukh | 67 | Kanpur | 2000-02-02 | 7 | Gaurav Kumar | 84 | 昌迪加尔 | 1998-07-06 | 8 | Sanket Jain | 61 | 西姆拉 | 1990-09-08 | 9 | Sahil Wagh | 90 | 加尔各答 | 1968-04-03 | 10 | Saurabh Singh | 54 | Kashmir | 1989-01-06 |
上面的结果表明我们已成功回滚到名为 'upd' 的 savepoint。
|