一个oracle面试题

某天,群里突然冒出一个道友询问oracle的面试题,特此记录一下

oracle面试题
一系列过程:
第一步建表:

DROP TABLE serv;
DROP TABLE terminal; 
CREATE TABLE serv(
       serv_id NUMBER(10),
       prod_id NUMBER(10),
       user_type VARCHAR2(30),
       terminal_name VARCHAR2(20)
)
tablespace ORAC_DATA
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 11M
    next 1M
    minextents 1
    maxextents unlimited
  );
COMMENT ON TABLE serv IS '用户资料表';
COMMENT ON COLUMN serv.serv_id IS '用户标识';
COMMENT ON COLUMN serv.prod_id IS '产品标识';
COMMENT ON COLUMN serv.user_type IS '用户类型';
COMMENT ON COLUMN serv.terminal_name IS '终端类型';
CREATE TABLE terminal(
       serv_id NUMBER(10),
       terminal_name VARCHAR2(20) 
)
tablespace ORAC_DATA
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 11M
    next 1M
    minextents 1
    maxextents unlimited
  );
COMMENT ON TABLE terminal IS '终端类型临时表';
COMMENT ON COLUMN terminal.serv_id IS '用户标识';
COMMENT ON COLUMN terminal.terminal_name IS '终端类型';

第二步,插入数据
我采用的手工添加,所用的方法如下
oracle 直接更新查询结果

SELECT * FROM serv FOR UPDATE;
SELECT * FROM terminal FOR UPDATE; 

serv 表结果如下:

结果
terminal 表结果如下
结果
第三步,创建存储过程如下:

--创建存储过程
CREATE OR REPLACE PROCEDURE sp_terminal
IS
BEGIN

--更新serv表  方法一
  UPDATE serv s SET s.terminal_name = (
        SELECT
        CASE
          WHEN s.PROD_ID = 1 AND s.USER_TYPE = 'A' THEN '固话'
          WHEN s.PROD_ID = 1 AND s.USER_TYPE = 'B' THEN '小灵通'
          WHEN S.PROD_ID = 2 THEN '宽带'
          WHEN S.USER_TYPE = 'C' THEN 'CDMA'
         ELSE '-1'
           END terminal_name
           FROM SERV S1
           WHERE S1.PROD_ID = S.PROD_ID AND S1.USER_TYPE = S.USER_TYPE
  ) WHERE EXISTS (
    SELECT NULL FROM SERV S1
           WHERE S1.PROD_ID = S.PROD_ID AND S1.USER_TYPE = S.USER_TYPE
  );
  COMMIT;
--更新serv表  方法二
UPDATE SERV S --用户资料表
SET S.TERMINAL_NAME=(SELECT
    CASE WHEN S.PROD_ID = 1 AND  S.USER_TYPE='A' THEN '固话'
         WHEN S.PROD_ID = 1 AND  S.USER_TYPE='B' THEN '小灵通'
         WHEN S.PROD_ID = 2   THEN '宽带'
         WHEN S.USER_TYPE='C' THEN 'CDMA'
          ELSE '-1'
          END  AS TERMINAL_NAME
    FROM TERMINAL T  --终端类型临时表
   WHERE  S.SERV_ID=T.SERV_ID)
   WHERE EXISTS (SELECT 1
   FROM TERMINAL T1 WHERE  S.SERV_ID=T1.SERV_ID);
   COMMIT;
--更新terminal表 方法一
  UPDATE terminal  T SET T.TERMINAL_NAME = (
        SELECT
              s1.TERMINAL_NAME
           FROM SERV S1
           INNER JOIN terminal T1
           ON S1.SERV_ID = t1.SERV_ID
           WHERE t1.SERV_ID = t.SERV_ID
  ) WHERE EXISTS (
          SELECT
              s1.TERMINAL_NAME
           FROM SERV S1
           INNER JOIN terminal T1
           ON S1.SERV_ID = t1.SERV_ID
           WHERE t1.SERV_ID = t.SERV_ID
  );
COMMIT; 
--更新terminal表 方法二
UPDATE terminal  T SET T.TERMINAL_NAME = (
       SELECT
       CASE
          WHEN s.PROD_ID = 1 AND s.USER_TYPE = 'A' THEN '固话'
          WHEN s.PROD_ID = 1 AND s.USER_TYPE = 'B' THEN '小灵通'
          WHEN S.PROD_ID = 2 THEN '宽带'
          WHEN S.USER_TYPE = 'C' THEN 'CDMA'
         ELSE '-1'
           END terminal_name
           FROM SERV S
           WHERE t.SERV_ID = s.SERV_ID
  ) WHERE EXISTS (
     SELECT
       CASE
          WHEN s.PROD_ID = 1 AND s.USER_TYPE = 'A' THEN '固话'
          WHEN s.PROD_ID = 1 AND s.USER_TYPE = 'B' THEN '小灵通'
          WHEN S.PROD_ID = 2 THEN '宽带'
          WHEN S.USER_TYPE = 'C' THEN 'CDMA'
         ELSE '-1'
           END terminal_name
           FROM SERV S
           WHERE t.SERV_ID = s.SERV_ID
  );
COMMIT; 
--------------
END sp_terminal;

后面,其他道友提出此种方法不适合数据量很大的情况,提出了一些方法,也记录在次

处于礼貌这里将聊天内容截图,仅仅展示相关文字

数据量大的话,这种更新就挂了。
buck into for all
数量大 采用 数组 批量更新
弄成分批提交。
引用块内容
bulk collect into for all
引用块内容
这里写图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值