我们可以在Oracle中创建保存点,然后通过调用ROLLBACK TO SAVEPOINT <savepoint_name>
我们可以回滚到特定的保存点。
UPDATE employees
SET salary = 7000
WHERE last_name = 'Banda';
SAVEPOINT banda_sal;
UPDATE employees
SET salary = 12000
WHERE last_name = 'Greene';
SAVEPOINT greene_sal;
SELECT SUM(salary) FROM employees;
ROLLBACK; --> the rollback without the savepoint
UPDATE employees
SET salary = 11000
WHERE last_name = 'Greene';
COMMIT;
有人可以解释上面的代码是如何工作的吗?
这可以被视为一个愚蠢的问题。但是,在某些情况下,很难确定在复杂的PL SQL程序中执行ROLLBACK语句的位置(如果您只需对现有代码进行修改)。
答案 0 :(得分:3)
关于这个评论:
但是在某些情况下,很难确定在复杂的PL SQL程序中执行ROLLBACK语句的位置(如果您只需对现有代码进行修改)。
如果您正在运行Oracle Database 12c第2版实例(现在可从OTN,Github和Docker下载,或多个云服务),您可以利用PL / Scope查找代码中提交的所有位置并执行回滚(PL / Scope首先在11.1中添加,但在12.2中添加了对SQL语句的分析):
您必须首先启用范围数据的收集:
ALTER SESSION SET plscope_settings='identifiers:all, statements:all'
然后在编译程序单元时,将信息放入ALL_IDENTIFIERS(PL / SQL语句)和ALL_STATEMENTS(SQL语句,12.2中的新语句)。
完成后,以下查询将找到所有提交和回滚:
SELECT st.owner,
st.object_name,
st.object_type,
st.line,
src.text
FROM all_statements st, all_source src
WHERE st.TYPE = 'COMMIT'
AND st.object_name = src.name
AND st.owner = src.owner
AND st.line = src.line
ORDER BY st.owner,
st.object_name,
st.object_type
/
SELECT st.owner,
st.object_name,
st.object_type,
st.line,
src.text
FROM all_statements st, all_source src
WHERE st.TYPE = 'ROLLBACK'
AND st.object_name = src.name
AND st.owner = src.owner
AND st.line = src.line
ORDER BY st.owner,
st.object_name,
st.object_type
/
您可以找到有关PL / Scope here的更多信息和示例。
答案 1 :(得分:2)
如果你不使用&#34;保存点到&#34; rollback
会回滚到点(在您的示例中为first update
,因为您的交易从first update
开始),rollback
之后如果您使用的是DML
third update
(在您的示例中为third update
)最后&#34;提交&#34;将仅提交事务的最后一部分(在最后一次回滚部分之后,--- start transactions
UPDATE employees
SET salary = 7000
WHERE last_name = 'Banda';
SAVEPOINT banda_sal;
UPDATE employees
SET salary = 12000
WHERE last_name = 'Greene';
SAVEPOINT greene_sal;
SELECT SUM(salary) FROM employees;
ROLLBACK; -- roolback to first DML("start transactions" part,because there is no any savepoint to)
UPDATE employees
SET salary = 11000
WHERE last_name = 'Greene';
COMMIT; -- commit only last update
)
a_row + b_row