相关疑难解决方法(0)

Oracle:DDL和事务回滚

在Oracle DDL(创建/更改)中是否可以像MS SQL(从2005年开始)那样是事务性的?

oracle ddl transactions

18
推荐指数
2
解决办法
1万
查看次数

UPDATE 语句在存储过程中不起作用;没有错误且没有异常发生

我在 Oracle 中创建了一个存储过程。程序编译成功,没有错误。该过程有 3 个 UPDATE 查询,它们更新 3 个表“TBLHOTEL”、“TBLHOTELDETAIL”和“TBLHOTELFARE”。

在每个 Update 语句之后,一个变量 successCnt1 会递增以获取成功插入查询的数量。最后将 successCnt1 分配给 successCnt 以存储最终结果。如果在任何查询中发生异常,则将其设置为 0 ,以指示不发生插入。

问题也不例外,数据库也没有发生更新。

这是我的代码:

架构:

TBLHOTEL 架构: {DATE1 (DATE) , ACROOMS (NUMBER) , NACROOMS (NUMBER), HOTELID (VARCHAR2(10)) }

TBLHOTELFARE 架构: {HOTELID (VARCHAR2(10)), CLASS (VARCHAR2(5)), FARE (NUMBER)}

TBLHOTELDETAIL 架构: {HOTELID (VARCHAR2(10)) , PLACE (VARCHAR2(15)) , HOTELNAME (VARCHAR2(15)) }

程序:

CREATE OR REPLACE PROCEDURE TableUpdateByParameter (acrooms   in number,
                                           nacrooms  in number,
                                           date1      in date,
                                           hotelid   in varchar2,
                                           fare in number,
                                           place in varchar2, …
Run Code Online (Sandbox Code Playgroud)

sql plsql stored-procedures oracle10g sql-update

3
推荐指数
1
解决办法
2万
查看次数

关于pl/sql异常的问题

以下文本是oracle文档的摘录Oracle®DatabasePL/SQL语言参考11g第1版(11.1):

未处理的异常也会影响子程序.如果成功退出子程序,PL/SQL会将值分配给OUT参数.但是,如果退出时出现未处理的异常,则PL/SQL不会为OUT参数赋值(除非它们是NOCOPY参数).此外,如果存储的子程序因未处理的异常而失败,则PL/SQL不会回滚子程序完成的数据库工作.

注意粗体文字,这是真的吗?我很好奇,所以我写了下面的例子来测试它.

-- create a test table
CREATE TABLE e AS SELECT * FROM HR.EMPLOYEES;   

-- create p1 which will update a row in table e
CREATE OR REPLACE PROCEDURE p1
IS
    ex EXCEPTION;
    row e%ROWTYPE;
BEGIN
    select * into row from e where employee_id=100;

    row.employee_id := 100;
    row.first_name := 'yang';

    -- update
    UPDATE e set ROW = row where employee_id = 100;
    -- and raise an error
    RAISE ex;
END;


BEGIN
    -- call the upper …
Run Code Online (Sandbox Code Playgroud)

oracle plsql transactions exception

2
推荐指数
1
解决办法
2181
查看次数

PL/SQL:关于隐式回滚的Oracle文档中的矛盾

Oracle Database PL/SQL语言参考11g第2版(11.2)文档中,"隐式回滚"部分以此文本开头:

"在运行INSERT,UPDATE,DELETE或MERGE语句之前,数据库标记一个隐式保存点(对您不可用).如果语句失败,数据库将回滚到保存点.通常,只会回滚失败的SQL语句,不是整个交易."

因此,如果我将一个SQL语句运行到PL/SQL程序中,并且句子失败,那么该句子将自动回滚.那没问题.

但同一部分以本文结尾:

"如果退出存储的子程序时出现未处理的异常,PL/SQL不会为OUT参数赋值,也不会进行任何回滚."

它似乎与第一个文本相反:如果我的程序以未捕获的异常结束,则不执行回滚.但是第一篇文章说如果SQL语句失败,则会自动完成回滚.

因此,如果我的存储程序包含一个SQL语句,句子失败,异常没有被捕获,我的程序结束,那么SQL语句应该回滚吗?该文件是否有矛盾?

Stack Overflow中的相关问题:


更新(已解决):感谢DrabJay的示例,现在更清楚了:

  • 一件事是回滚SQL语句.
  • 另一件事是包含SQL语句的程序的回滚.

失败的SQL语句的回滚总是完成(无论是否进入程序).程序的回滚取决于调用者:

  • 如果回滚应用于调用方,则会对程序应用回滚.
  • 如果没有对调用者应用回滚,则不会对程序应用回滚.

如果程序是一个匿名块(无来电显示存在),它相当于从用户的语句被调用,而一个失败的用户语句回自动回滚,所以匿名块被回滚.

我认为该文件应该更清楚,特别是"并且不做任何回滚"这两个词:

"如果退出存储的子程序时出现未处理的异常,PL/SQL不会为OUT参数赋值,也不会进行任何回滚."

oracle plsql exception rollback

2
推荐指数
1
解决办法
758
查看次数