一個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
引用塊內容
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章