查看: 3583|回复: 9

[每日一题] 有奖活动:PL/SQL Challenge 每日一题:2012-3-2 自治事务

[复制链接]
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
跳转到指定楼层
1#
发表于 2012-3-6 06:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最快答对的puber将获得彩蛋章一枚,其他会员如果提供有价值的分析、讨论也可获得彩蛋章一枚。

以往旧题索引:
http://www.itpub.net/thread-1499223-1-1.html

原始出处:
http://www.plsqlchallenge.com/

作者:Steven Feuerstein
难度:高

我创建了如下的日志表并填入数据:

CREATE TABLE plch_log
(
   code         NUMBER PRIMARY KEY
, text         VARCHAR2 (4000)
, created_on   DATE
, created_by   VARCHAR2 (30)
)
/

BEGIN
   INSERT INTO plch_log
        VALUES (-1422
              , 'Problem encountered'
              , SYSDATE
              , USER);

   COMMIT;
END;
/

然后我创建了这个过程来管理表的内容:
CREATE OR REPLACE PROCEDURE plch_log_action (
   action_in   IN VARCHAR2
, code_in     IN plch_log.code%TYPE DEFAULT NULL
, text_in     IN plch_log.text%TYPE DEFAULT NULL)
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   CASE action_in
      WHEN 'DELETE'
      THEN
         DELETE FROM plch_log
               WHERE code = code_in;
      WHEN 'UPDATE'
      THEN
         UPDATE plch_log
            SET code = code * 10
          WHERE 1 = 2;
      WHEN 'INSERT'
      THEN
         INSERT INTO plch_log
              VALUES (code_in, text_in, SYSDATE, USER);
      ELSE
         NULL;
   END CASE;
END;
/

哪些选项在执行之后屏幕上会显示 "Action completed" ?

(A)
BEGIN
   plch_log_action ('DELETE', 1000);
   DBMS_OUTPUT.put_line ('Action completed');
END;
/


(B)
BEGIN
   plch_log_action ('DELETE', -1422);
   DBMS_OUTPUT.put_line ('Action completed');
END;
/

(C)
BEGIN
   plch_log_action ('UPDATE');
   DBMS_OUTPUT.put_line ('Action completed');
END;
/

(D)
BEGIN
   plch_log_action ('INSERT', 2000, 'Save it!');
   DBMS_OUTPUT.put_line ('Action completed');
END;
/

(E)
BEGIN
   plch_log_action ('MERGE'
                  , 2000
                  , 'Insert-Update Together');
   DBMS_OUTPUT.put_line ('Action completed');
END;
/

论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
2#
发表于 2012-3-6 06:53 | 只看该作者
e

使用道具 举报

回复
论坛徽章:
10
生肖徽章2007版:兔
日期:2009-09-07 16:55:06蜘蛛蛋
日期:2012-04-19 16:07:40ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262011新春纪念徽章
日期:2011-01-04 10:38:442010广州亚运会纪念徽章:自行车
日期:2010-12-10 14:38:512010广州亚运会纪念徽章:皮划艇
日期:2010-11-08 19:06:152010世博会纪念徽章
日期:2010-08-27 19:57:102010年世界杯参赛球队:德国
日期:2010-03-20 11:44:332010新春纪念徽章
日期:2010-03-01 11:20:05三菱
日期:2013-09-15 14:27:20
3#
发表于 2012-3-6 08:40 | 只看该作者
D,E

使用道具 举报

回复
论坛徽章:
15
最佳人气徽章
日期:2013-03-14 11:03:26兰博基尼
日期:2013-08-05 16:44:02凯迪拉克
日期:2013-08-05 16:45:47
4#
发表于 2012-3-6 08:45 | 只看该作者
本帖最后由 hudingchen 于 2012-3-6 08:54 编辑

e,
If you try to exit an active autonomous transaction without committing or rolling back, Oracle raises an exception. If the exception goes unhandled, or if the transaction ends because of some other unhandled exception, the transaction is rolled back.
来自http://docs.oracle.com/cd/B19306 ... agma.htm#sthref2466
含有自治事务的程序中,第一个SQL语句会开启一个事务,所以a,b,c,d,都执行了SQL语句,只有e没有执行SQL,也就没有开启事务,不会抛出异常。

使用道具 举报

回复
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
5#
发表于 2012-3-6 08:57 | 只看该作者
OO起得真早

使用道具 举报

回复
论坛徽章:
144
至尊黑钻
日期:2012-03-14 14:38:13至尊黑钻
日期:2012-03-14 14:38:13紫钻
日期:2012-03-14 14:38:13紫钻
日期:2011-12-27 22:24:53粉钻
日期:2012-03-14 14:46:10粉钻
日期:2011-12-27 22:25:06绿钻
日期:2012-03-14 14:38:13绿钻
日期:2012-11-30 13:30:03黄钻
日期:2011-12-27 22:24:36黄钻
日期:2012-03-14 14:38:13
6#
发表于 2012-3-6 09:17 | 只看该作者
自治事务DML应该要显示地结束,否则主事务被挂起,所以是E

使用道具 举报

回复
论坛徽章:
2
开发板块每日发贴之星
日期:2009-01-20 01:01:03紫蛋头
日期:2012-03-14 11:15:43
7#
发表于 2012-3-6 13:49 | 只看该作者
E
自治事务内没有提交,只有E是没有事物发生的case

使用道具 举报

回复
论坛徽章:
25
奥运会纪念徽章:射击
日期:2013-01-28 09:12:182014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-03-20 16:13:24马上有房
日期:2014-03-20 16:14:11马上有钱
日期:2014-03-20 16:14:11马上有对象
日期:2014-03-20 16:14:11马上加薪
日期:2014-03-20 16:14:11喜羊羊
日期:2015-04-09 18:46:34秀才
日期:2016-03-24 09:20:52
8#
发表于 2012-3-6 15:20 | 只看该作者
E必须的
如果在过程能处理异常就没有问题了

CREATE OR REPLACE PROCEDURE plch_log_action (
   action_in   IN VARCHAR2
, code_in     IN plch_log.code%TYPE DEFAULT NULL
, text_in     IN plch_log.text%TYPE DEFAULT NULL)
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   CASE action_in
      WHEN 'DELETE'
      THEN
         DELETE FROM plch_log
               WHERE code = code_in;
      WHEN 'UPDATE'
      THEN
         UPDATE plch_log
            SET code = code * 10
          WHERE 1 = 2;
      WHEN 'INSERT'
      THEN
         INSERT INTO plch_log
              VALUES (code_in, text_in, SYSDATE, USER);
      ELSE
         NULL;
   END CASE;
   exception
     when others then
       null;
END;
/

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
9#
 楼主| 发表于 2012-3-6 22:57 | 只看该作者
答案E,OO起个大早没白费。
如果自治事务里面执行了DML, 哪怕这个DML没有修改任何数据,在退出之前也必须显式提交或回滚事务。

使用道具 举报

回复
论坛徽章:
8
2014年世界杯参赛球队: 意大利
日期:2014-07-15 13:14:472015年新春福章
日期:2015-03-04 14:55:132015年新春福章
日期:2015-03-06 11:59:47美羊羊
日期:2015-05-06 13:24:21秀才
日期:2015-07-13 09:48:14天蝎座
日期:2015-09-21 17:14:18巨蟹座
日期:2016-02-14 16:04:51乌索普
日期:2017-03-13 10:29:43
10#
发表于 2016-2-19 17:09 | 只看该作者
测试验证,DML事务中没有commit或rollback或异常抛出。
create or replace procedure dbmonitor.plch_log_action(
action_in in varchar2,
code_in in plch_log.code%TYPE DEFAULT NULL,
text_in in plch_log.text%TYPE DEFAULT NULL)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
        CASE action_in
                WHEN 'DELETE' THEN
                DELETE FROM plch_log WHERE code = code_in;
                COMMIT;
                WHEN 'UPDATE' THEN
                UPDATE plch_log SET code = code *10 where 1 = 2;
                COMMIT;
                WHEN 'INSERT' THEN
                INSERT INTO plch_log VALUES(code_in,text_in,SYSDATE,USER);
                COMMIT;
                ELSE
                        NULL;
        END CASE;
END;
/
create or replace procedure dbmonitor.plch_log_action(
action_in in varchar2,
code_in in plch_log.code%TYPE DEFAULT NULL,
text_in in plch_log.text%TYPE DEFAULT NULL)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
        CASE action_in
                WHEN 'DELETE' THEN
                DELETE FROM plch_log WHERE code = code_in;
                ROLLBACK;
                WHEN 'UPDATE' THEN
                UPDATE plch_log SET code = code *10 where 1 = 2;
                ROLLBACK;
                WHEN 'INSERT' THEN
                INSERT INTO plch_log VALUES(code_in,text_in,SYSDATE,USER);
                ROLLBACK;
                ELSE
                        NULL;
        END CASE;
END;
/

17:08:07 SQL> BEGIN
17:08:15   2    plch_log_action('DELETE',-1422);
17:08:15   3    DBMS_OUTPUT.put_line('Action completed');
17:08:15   4  END;
17:08:15   5  /
Action completed

PL/SQL 程序順利完成.

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表