歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> Linux文化 >> Oracle--毛病篇

Oracle--毛病篇

日期:2017/2/27 12:14:03   编辑:Linux文化

前言:

本文純為牢騷, 怨言, 一為筆者對ORACLE軟件如此這般的疑惑與不滿,

二來其實可以總結ORACLE中的一些不規則性, 為ORACLE學習者提供一些借鑒.

三來看起當時的心情頗為抓狂, 寫下來, 算是對一些不良心態的反思.

有一些是筆者早期初涉ORACLE時的一些誤解, 冤枉它了. 在後記中都有正名.

1. 改變當前用戶時SQLPLUS環境變量的設置是否被繼承到新的用戶環境下
  混亂, serverout 沒有被繼承, 而pagesize被繼承.

2. SQLPLUS環境下命令行編輯功能微弱得可憐, 看看readline, 看看MySQL

3. SQLPLUS環境的命令行沒有歷史記錄功能, 看看MySQL. gdb, bash

4. 命名規范混亂得一踏糊塗. user_tab_columns, user_con_constraints
  user_tables, usre_cons_columns

5. SQLPLUS環境的初始化文件的location的要求, 看看.bashrc, .vimrc, .netrc
  .emacs, .newsrc...摸一個都比它強, 我要使用你的login.sql還非得在每
  一個當前目錄下都弄一份, 隨身攜帶呀? 好在這一點可以通過SQLPATH環境
  變量的設置來搞定.

6. 注釋格式:--, 什麼玩意呀, HTML用, perl用#, php用#或/**/或
  //, C用/**/, C++用/**/和//, lisp用;;, 匯編用;, QBASIC用rem 和',
  SHELL,SED,AWK用#, 你干嗎要自創一種. 自以為很鳥啊, 與別人兼容一點會
  小你什麼身份.

7. 看看它的PL/SQL, 號稱第N代的高級語言, function因為必需返回一個值而
  存在, 除此之外我看不出它與其它的procedure有什麼區別. 又是trigger,
  又是package, 又是procedure, 又是function, 搞什麼東東呀. 別人是把
  復雜的東西簡單化, 我看ORACLE是要把簡單的東西復雜化, 同樣是PL/SQL
  程序, dbms_output.put_line被設計成在function裡單獨調用時不能輸出.
  非要一個procedure單獨調用它時它才會輸出.

8. 單引號問題, Javascript可以兼容使用單雙引號, perl可以, php也可以, 它
  們可以是因為它們想兼容, 想對用戶友好, C語言不允許, 那是因為它嚴謹.
  人家留著有大用場. 你ORACLE不允許使用雙引號又是什麼原由, 說來聽聽.

9. 別人的用戶界面設計是"沒有消息就是最好的消息", 或是"無論發生什麼, 都
  要讓用戶知道", 看看它在sqlplus下的變量:
  var i number;
  i:=5;
  print i;
  你什麼看見什麼, 什麼都沒有! 你又能從這知道什麼, 好消息?
  PS:我至今都不知道這說明了什麼? i的值為NULL?, i不能在這下面賦值?
  不能賦值你說呀, 你不說我怎麼知道不能賦值, 雖然你很能有意見地顯示了
  一個空行, 但是你還是要說呀, 你真的不能賦值嗎? 你不是真的不能賦值吧?
  ...
  後記: 好在我今天知道了要用
  SQL> exec :i := 5;
  SQL> print :i
  但總不能讓我掘地三尺才找得出來這些淺顯的東西吧.

10. 在sqlplus下help set看看, 找出一個叫set severout[put] on|off的選項
  注意, 它是severout, 你在sqlplus下set severout on試試,
  SP2-0158: unknown SET option "severout" 了吧?
  set serverout on
  是的, 就一個字母而已.
  編程大師說: 任何軟件都有BUG.
  但, 一個如此小的BUG可以讓一個全球第二大的軟件公司帶著它走過幾個版本?
  Oracle8.15 Oracle8.16 Oracle8.17...難道保留錯誤是為了兼容性?
  後記: 我終於看到Oracle9i版裡對此有了改進, 略感欣慰.

11. PL/SQL的用戶們, 看看下面:

  創建一個沒帶參數的procedure:
  create or replace procedure proc_name as
  i number;
  begin
  ...
  end proc_name;

  創建一個帶參數的procedure:
  create or replace procedure proc_name(arg1,...) as
  i number;
  begin
  ...
  end proc_name;
  你很習慣用declare來聲明嗎? 不行, 這裡不行, 你必需聽我的, 用as

  創建一個觸發器:
  create or replace trigger tri_name before insert on tname for each
  row
  declare
  i number;
  begin
  ..
  end;
  因為這是觸發器, 所以它要用declare來聲明變量, 盡管觸發器用的也是PL/
  SQL的語法. 但我們是為了區別於其它類型的存儲過程, 為了讓用戶覺得
  ORACLE高深莫測一點.
  怎麼就一個end;不是end tri_name嗎? 是的, procedure和function是這樣
  設計的, 但這樣可以讓用戶覺得更難用一點麼!
  
  (sqlplus下)你調用一個不帶參數的procedure:
  call proc_name();
  (sqlplus下)你調用一個不帶參數的procedure:
  call proc_name(arg1, arg2);
  是的, 它不是可選的, 它必需如此, 定義一個沒有參數的procedure就是不
  要空的()號, 但調用它的時侯就是要, 定義一個有參數的procedure當然也要.
  function的情況與這個也一樣.

  你調用一個function:
  ret_val := func_name();
  什麼? 你不需要ret_val, 不行, 這是強買強賣, 不要不行. 否則我不干活!
  而且, 哼哼, 我給出的錯誤信息保證你看不懂.

  你要玩更高級的設計方法, 用上包了:
  create or replace package pack_name as
  ....
  end pack_name;
  是的, 這只是包的聲明.
  要想定義這個包, 你還得:
  create or replace package body pack_name as
   procedure proc_name is
   --你不是說用as嗎? 是的, 但是這裡as已經被上一條語句用了, 呶! 你
   也看到了. 用is有什麼不好?
   end proc_name
   function func_name is
   ...
   end func_name
  end pack_name;

12. 看看出錯信息, 來自SQLPLUS的, 來自Pro*C預編譯器的, 來自其它工具如
  imp, exp, sqllda的. 說不准你也別誤導呀.

13. 疲憊不堪的Pro*C程序員們:
  在函數foo中你已經聲明了
  EXEC SQL WHENEVER SQLERROR GOTO sql_err;
  在另一個函數bar裡你只想默默地使用
  EXEC SQL WHENEVER SQLERROR CONTINUE;
  但你沒特別聲明, Pro*C的預編譯器會告訴你, 它在函數bar中找不到sql_err
  標號!!! 它可以跨函數使用標號. 它也敢自稱是一個預處理器跟編譯器沾沾
  邊, 剛才用陳橋五筆敲出來的處理器三個字恰好跟處理品是同樣的鍵碼, 我看
  叫處理品倒是名符其實.

14. DDL語句的用戶們:
  alter table tname add(col1 type...);
  alter table tname modify(col1 type...);
  alter table tname drop column(col1);
  為何非要在drop裡多出來一個column?

15. 命名
  user_cons_columns;
  user_constraints;
  user_rollback_segs;
  它真的要把segment統統縮寫為segs嗎? 把constraints縮寫為cons? 把
  columns縮寫為cols? 不, ORACLE的程序員們想怎麼樣就怎麼樣. 他們是覺得
  單詞的全稱太長了嗎? 不見得, desc dba_users;看一下
  看看INITIAL_RSRC_CONSUMER_GROUP字段, 看看temporary_tablespace字段.

  再來看看一下create table:
  create table tname (col1 type,...) storage(initial .. next ..
  minextents .. maxextents ..) ...;
  desc user_tables;
  inital_extent
  next_extent
  minextents
  maxextents
  不要問他們為什麼有的用單數有的用復數, 因為他們是ORACLE. 他們想這樣.
  dba_tables中owner
  dba_sequences中叫sequence_owner
  user_tab_columns是關於一張表中列信息的, _tab_columns
  user_cons_columns是關於表中字段的約束信息的, _cons_columns

後話: 牢騷發完了, 繼續得埋頭搞開發, 寫代碼, 畢竟, 人類在一個fortran語言 大行其道的年代就已經登上了月球, 所以, 爭論語言或工具的優劣強弱還不如把 現有的功能充分高效地利用起來. 如此一說, 算是什麼?


Copyright © Linux教程網 All Rights Reserved