PostRank

顯示具有 Oracle DBA 標籤的文章。 顯示所有文章
顯示具有 Oracle DBA 標籤的文章。 顯示所有文章

2009/09/08

如何解決Unable to Find 'kshell' in Path When Running adcfgclone.pl

Symptoms

Receive the following error when running perl adcfgclone.pl dbTier in a new target environment:-

Checking for ksh...
Unable to find 'kshell' in path

Cause

This is caused by the checks for pdksh in adchkutil.sh. The checking made sense for previous Linux versions but this has changed. Moreover the pdksh is not needed on the DB tier hence the check became obsolete.

Solution

Workaround:
-----------------
Before running the perl utility on the adcfgclone.pl script set the KSH_VERSION. The following is applicable to the Linux Red Hat 5 platform

$ export KSH_VERSION='@(#)PD KSH v5.2.14 99/07/13.2'

Repeat the 'perl adcfgclone.pl dbTier' and it should now run successfully.

Permanent fix:
------------------
Apply Patch 5972212 "ADCHKUTL.SH FAILS IN SLES 10 DUE TO PDKSH REQUIREMENT" for 11i or R12 which will bring the correct version of adchkutl.sh 115.6 which no longer checks for pdksh
 

2009/05/23

Oracle 常見問題集

摘自:網路
 
Oracle 常見問題集

  1. Oracle安裝完成後的初始口令
  internal/oracle
  sys/change_on_install
  system/manager
  scott/tiger
  sysman/oem_temp
  2. ORACLE9IAS WEB CACHE的初始默認用戶和密碼?
  administrator/administrator
  3. oracle 8.0.5怎麽創建資料庫
  用orainst。如果有motif介面,可以用orainst /m
  4. oracle 8.1.7怎麽創建資料庫
  dbassist
  5. oracle 9i 怎麽創建資料庫
  dbca
  6. oracle中的裸設備指的是什麽
  裸設備就是繞過文件系統直接訪問的儲存空間
  7. oracle如何區分 64-bit/32bit 版本???
  $ sqlplus '/ AS SYSDBA'
  SQL*Plus: Release 9.0.1.0.0 - Production on Mon Jul 14 17:01:09
  2003
  (c) Copyright 2001 Oracle Corporation. All rights reserved.
  Connected to:
  Oracle9i Enterprise Edition Release 9.0.1.0.0 - Production
  With the Partitioning option
  JServer Release 9.0.1.0.0 - Production
  SQL> select * from v$version;
  BANNER
  ----------------------------------------------------------------
  Oracle9i Enterprise Edition Release 9.0.1.0.0 - Production
  PL/SQL Release 9.0.1.0.0 - Production
  CORE 9.0.1.0.0 Production
  TNS for Solaris: Version 9.0.1.0.0 - Production
  NLSRTL Version 9.0.1.0.0 - Production
  SQL>
  8. SVRMGR什麽意思?
  svrmgrl,Server Manager.
  9i下沒有,已經改爲用SQLPLUS了
  sqlplus /nolog
  變爲歸檔日誌型的
  9. 請問如何分辨某個用戶是從哪台機器登陸ORACLE的
  SELECT machine , terminal FROM V$SESSION;
  10. 用什麽語句查詢欄位呢?
  desc table_name 可以查詢表的結構
  select field_name,... from ... 可以查詢欄位的值
  select * from all_tables where table_name like '%'
  select * from all_tab_columns where table_name=' '
  11. 怎樣得到觸發器、過程、函數的創建腳本?
  desc user_source
  user_triggers
  12. 怎樣計算一個表佔用的空間的大小?
  select owner,table_name,
  NUM_ROWS,
  BLOCKS*AAA/1024/1024 "Size M",
  EMPTY_BLOCKS,
  LAST_ANALYZED
  from dba_tables
  where table_name='XXX';
  Here: AAA is the value of db_block_size ;
  XXX is the table name you want to check
  13. 如何查看最大會話數?
  SELECT * FROM V$PARAMETER WHERE NAME LIKE 'proc%';
  SQL>
  SQL> show parameter processes
  NAME TYPE VALUE
  ------------------------------------ -------
  ------------------------------
  aq_tm_processes integer 1
  db_writer_processes integer 1
  job_queue_processes integer 4
  log_archive_max_processes integer 1
  processes integer 200
  這裏爲200個用戶。
  select * from v$license;
  其中sessions_highwater紀錄曾經到達的最大會話數
  14. 如何查看系統被鎖的事務時間?
  select * from v$locked_object ;
  15. 如何以archivelog的方式運行oracle。
  init.ora
  log_archive_start = true
  RESTART DATABASE
  16. 怎麽獲取有哪些用戶在使用資料庫
  select username from v$session;
  17. 資料表中的欄位最大數是多少
  表或視圖中的最大列數爲 1000
  18. 怎樣查得資料庫的SID
  select name from v$database;
  也可以直接查看 init.ora文件
  19. 如何在Oracle伺服器上通過SQLPLUS查看本機IP位址
  select sys_context('userenv','ip_address') from dual;
  如果是登陸本機資料庫,只能返回127.0.0.1,呵呵
  20. unix 下怎麽調整資料庫的時間?
  su -root
  date -u 08010000
  21. 在ORACLE TABLE中如何抓取MEMO類型欄位為空的資料記錄
  select remark from oms_flowrec where trim(' ' from remark) is not
  null ;
  22. 如何用BBB表的資料去更新AAA表的資料(有關聯的欄位)
  UPDATE AAA SET BNS_SNM=(SELECT BNS_SNM FROM BBB WHERE
  AAA.DPT_NO=BBB.DPT_NO) WHERE BBB.DPT_NO IS NOT NULL;
  23. P4電腦安裝方法
  將SYMCJIT.DLL改為SYSMCJIT.OLD
  24. 何查詢SERVER是不是OPS
  SELECT * FROM V$OPTION;
  如果PARALLEL SERVER=TRUE則有OPS能
  25. 何查詢每個用戶的權限
  SELECT * FROM DBA_SYS_PRIVS;
  26. 如何將表移動表空間
  ALTER TABLE TABLE_NAME MOVE TABLESPACE_NAME;
  27. 如何將索引移動表空間
  ALTER INDEX INDEX_NAME REBUILD TABLESPACE TABLESPACE_NAME;
  28. 在LINUX,UNIX下如何啟動DBA STUDIO
  OEMAPP DBASTUDIO
  29. 查詢鎖的狀況的對象有
  V$LOCK, V$LOCKED_OBJECT, V$SESSION, V$SQLAREA, V$PROCESS ;
  查詢鎖的表的方法:
  SELECT S.SID SESSION_ID, S.USERNAME, DECODE(LMODE, 0, 'None', 1,
  'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4, 'Share', 5, 'S/Row-X
  (SSX)', 6, 'Exclusive', TO_CHAR(LMODE)) MODE_HELD, DECODE(REQUEST,
  0, 'None', 1, 'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4,
  'Share', 5, 'S/Row-X (SSX)', 6, 'Exclusive', TO_CHAR(REQUEST))
  MODE_REQUESTED, O.OWNER||'.'||O.OBJECT_NAME||'
  ('||O.OBJECT_TYPE||')', S.TYPE LOCK_TYPE, L.ID1 LOCK_ID1, L.ID2
  LOCK_ID2 FROM V$LOCK L, SYS.DBA_OBJECTS O, V$SESSION S WHERE L.SID
  = S.SID AND L.ID1 = O.OBJECT_ID ;
  30. 如何解鎖
  ALTER SYSTEM KILL SESSION 'SID,SERIR#';
  31. SQLPLUS下如何修改編輯器
  DEFINE _EDITOR="<編輯器的完整路經>" -- 必須加上雙引號
  來定義新的編輯器,也可以把這個寫在$ORACLE_HOME/sqlplus/admin/glogin.sql裏面使它永久有效。
  32. ORACLE產生隨機函數是
  DBMS_RANDOM.RANDOM
  33. LINUX下查詢磁盤競爭狀況命令
  Sar -d
  33. LINUX下查詢CPU競爭狀況命令
  sar -r
  34. 查詢當前用戶對象
  SELECT * FROM USER_OBJECTS;
  SELECT * FROM DBA_SEGMENTS;
  35. 如何獲取錯誤資訊
  SELECT * FROM USER_ERRORS;
  36. 如何獲取鏈接狀況
  SELECT * FROM DBA_DB_LINKS;
  37. 查看數據庫字元狀況
  SELECT * FROM NLS_DATABASE_PARAMETERS;
  SELECT * FROM V$NLS_PARAMETERS;
  38. 查詢表空間資訊
  SELECT * FROM DBA_DATA_FILES;
  39. ORACLE的INTERAL用戶要口令
  修改 SQLNET.ORA
  SQLNET.AUTHENTICATION_SERVICES=(NTS)
  40. 出現JAVA.EXE的解決辦法
  一般是將ORACLEORAHOMEXIHTTPSERVER改成手工啟動可以的
  X是8或9
  41. 如何給表、列加注釋?
  SQL>comment on table 表 is '表注釋';
  注釋已創建。
  SQL>comment on column 表.列 is '列注釋';
  注釋已創建。
  SQL> select * from user_tab_comments where comments is not null;
  42. 如何查看各個表空間佔用磁片情況?
  SQL> col tablespace format a20
  SQL> select
  b.file_id 文件ID號,
  b.tablespace_name 表空間名,
  b.bytes 位元組數,
  (b.bytes-sum(nvl(a.bytes,0))) 已使用,
  sum(nvl(a.bytes,0)) 剩餘空間,
  sum(nvl(a.bytes,0))/(b.bytes)*100 剩餘百分比
  from dba_free_space a,dba_data_files b
  where a.file_id=b.file_id
  group by b.tablespace_name,b.file_id,b.bytes
  order by b.file_id
  43. 如把ORACLE設置爲MTS或專用模式?
  #dispatchers="(PROTOCOL=TCP) (SERVICE=SIDXDB)"
  加上就是MTS,注釋就是專用模式,SID是指你的實例名。
  44. 如何才能得知系統當前的SCN號
  select max(ktuxescnw * power(2, 32) + ktuxescnb) from x$ktuxe;
  45. 請問如何在ORACLE中取毫秒
  9i之前不支援,9i開始有timestamp.
  9i可以用select systimestamp from dual;
  大家在應用ORACLE的時候可能會遇到很多看起來不難的問題, 特別對新手來說, 今天我簡單把它總結一下, 發布給大家,
  希望對大家有幫助! 和大家一起探討, 共同進步!
  對ORACLE高手來說是不用看的.
  46. 如何在字串里加回車?
  select 'Welcome to visit'||chr(10)||'www.CSDN.NET' from dual ;
  47. 中文是如何排序的?
  Oracle9i之前,中文是按照二進位編碼進行排序的。
  在oracle9i中新增了按照拼音、部首、筆畫排序功能。設置NLS_SORT值
  SCHINESE_RADICAL_M 按照部首(第一順序)、筆劃(第二順序)排序
  SCHINESE_STROKE_M 按照筆劃(第一順序)、部首(第二順序)排序
  SCHINESE_PINYIN_M 按照拼音排序
  48. Oracle8i中物件名可以用中文嗎?
  可以
  49. 如何改變WIN中SQL*Plus啓動選項?
  SQL*PLUS自身的選項設置我們可以在$ORACLE_HOME/sqlplus/admin/glogin.sql中設置。
  50. 怎樣修改oracel資料庫的默認日期
  alter session set nls_date_format='yyyymmddhh24miss';
  OR
  可以在init.ora中加上一行
  nls_date_format='yyyymmddhh24miss'
  51. 如何將小表放入keep池中
  alter table xxx storage(buffer_pool keep);
  52. 如何檢查是否安裝了某個patch
  check that oraInventory
  53. 如何使select語句使查詢結果自動生成序號
  select rownum,COL from table;
  54. 如何知道資料褲中某個表所在的tablespace
  select tablespace_name from user_tables where table_name='TEST';
  select * from user_tables中有個欄位TABLESPACE_NAME,(oracle);
  select * from dba_segments where …;
  55. 怎麽可以快速做一個和原表一樣的備份表
  create table new_table as (select * from old_table);
  55. 怎麽在sqlplus下修改procedure
  select line,trim(text) t from user_source where name ='A' order by
  line;
  56. 怎樣解除PROCEDURE被意外鎖定
  alter system kill session ,把那個session給殺掉,不過你要先查出她的session id
  or
  把該過程重新改個名字就可以了。
  57. SQL Reference是個什麽東西?
  是一本sql的使用手冊,包括語法、函數等等,oracle官方網站的文檔中心有下載.
  58. 如何查看資料庫的狀態
  unix下
  ps -ef | grep ora
  windows下
  看服務是否起來
  是否可以連上資料庫
  59. 請問如何修改一張表的主鍵
  alter table aaa
  drop constraint aaa_key ;
  alter table aaa
  add constraint aaa_key primary key(a1,b1) ;
  60. 改變資料檔案的大小
  用 ALTER DATABASE .... DATAFILE .... ;
  手工改變資料檔案的大小,對於原來的 資料檔案有沒有損害。
  61. 怎樣查看ORACLE中有哪些程式在運行之中?
  查看v$sessions表
  62. 怎麽可以看到資料庫有多少個tablespace
  select * from dba_tablespaces;
  63. 如何修改oracle資料庫的用戶連接數?
  修改initSID.ora,將process加大,重啓資料庫.
  64. 如何查出一條記錄的最後更新時間
  可以用logminer 察看
  65. 如何在PL/SQL中讀寫文件?
  UTL_FILE包允許用戶通過PL/SQL讀寫作業系統文件。
  66. 怎樣把"&"放入一條記錄中?
  insert into a values (translate ('at{&}t','at{}','at'));
  67. EXP如何加QUERY參數?
  EXP USER/PASS FILE=A.DMP TABLES(BSEMPMS)
  QUERY='"WHERE EMP_NO=\'S09394\'\" ﹔
  68. 關於oracle8i支援簡體和繁體的字元集問題?
  ZHS16GBK可以支
  69. Data Guard是什麽軟體?
  就是Standby的換代産品
  70. 如何創建SPFILE
  SQL> connect / as sysdba
  SQL> select * from v$version;
  SQL> create pfile from spfile;
  SQL> CREATE SPFILE FROM
  PFILE='E:\ora9i\admin\eygle\pfile\init.ora';
  文件已創建。
  SQL> CREATE SPFILE='E:\ora9i\database\SPFILEEYGLE.ORA' FROM
  PFILE='E:\ora9i\admin\eygle\pfile\init.ora';
  文件已創建。
 71. 內核參數的應用
  shmmax
  含義:這個設置並不決定究竟Oracle資料庫或者作業系統使用多少實體記憶體,只決定了最多可以使用的記憶體數目。這個設置也不影響作業系統的內核資源。
  設置方法:0.5*實體記憶體
  例子:Set shmsys:shminfo_shmmax=10485760
  shmmin
  含義:共用記憶體的最小大小。
  設置方法:一般都設置成爲1。
  例子:Set shmsys:shminfo_shmmin=1:
  shmmni
  含義:系統中共用記憶體段的最大個數。
  例子:Set shmsys:shminfo_shmmni=100
  shmseg
  含義:每個用戶進程可以使用的最多的共用記憶體段的數目。
  例子:Set shmsys:shminfo_shmseg=20:
  semmni
  含義:系統中semaphore identifierer的最大個數。
  設置方法:把這個變數的值設置爲這個系統上的所有Oracle的實例的init.ora中的最大的那個processes的那個值加10。
  例子:Set semsys:seminfo_semmni=100
  semmns
  含義:系統中emaphores的最大個數。
  設置方法:這個值可以通過以下方式計算得到:各個Oracle實例的initSID.ora裏邊的processes的值的總和(除去最大的Processes參數)+最大的那個Processes×2+10×Oracle實例的個數。
  例子:Set semsys:seminfo_semmns=200
  semmsl:
  含義:一個set中semaphore的最大個數。
  設置方法:設置成爲10+所有Oracle實例的InitSID.ora中最大的Processes的值。
  例子:Set semsys:seminfo_semmsl=-200
  72. 怎樣查看哪些用戶擁有SYSDBA、SYSOPER許可權?
  SQL>conn sys/change_on_install
  SQL>select * from V_$PWFILE_USERS;
  73. 如何單獨備份一個或多個表?
  exp 用戶/密碼 tables=(表1,…,表2)
  74. 如何單獨備份一個或多個用戶?
  exp system/manager owner=(用戶1,用戶2,…,用戶n) file=導出文件
  75. 如何對CLOB欄位進行全文檢索?
  SELECT * FROM A WHERE dbms_lob.instr(a.a,'K',1,1)>0;
  76. 如何顯示當前連接用戶
  SHOW USER
  77. 如何查看資料檔案放置的路徑
  col file_name format a50
  SQL> select tablespace_name,file_id,bytes/1024/1024,file_name from
  dba_data_files order by file_id;
  78. 如何查看現有回滾段及其狀態
  SQL> col segment format a30
  SQL> SELECT
  SEGMENT_NAME,OWNER,TABLESPACE_NAME,SEGMENT_ID,FILE_ID,STATUS FROM
  DBA_ROLLBACK_SEGS
  79. 如何改變一個欄位初始定義的Check範圍?
  SQL> alter table xxx drop constraint constraint_name;
  之後再創建新約束:
  SQL> alter table xxx add constraint constraint_name check();
  80. Oracle常用系統文件有哪些?
  通過以下視圖顯示這些文件資訊:v$database,v$datafile,v$logfile v$controlfile
  v$parameter;
  81. 內連接INNER JOIN
  Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no;
  82. 如何外連接
  Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no(+);
  Select a.* from bsempms a,bsdptms b wherea.dpt_no(+)=b.dpt_no;
  83. 如何執行腳本SQL文件
  SQL>@$PATH/filename.sql;
  84. 如何快速清空一個大表
  SQL>truncate table table_name;
  85. 如何查有多少個數據庫實例
  SQL>SELECT * FROM V$INSTANCE;
  86. 如何查詢數據庫有多少表
  SQL>select * from all_tables;
  87. 如何測試SQL語句執行所用的時間
  SQL>set timing on ;
  SQL>select * from tablename;
  大家在應用ORACLE的時候可能會遇到很多看起來不難的問題, 特別對新手來說, 今天我簡單把它總結一下, 發布給大家,
  希望對大家有幫助! 和大家一起探討, 共同進步!
  對ORACLE高手來說是不用看的.
  88. CHR()的反函數是
  ASCII()
  SELECT CHAR(65) FROM DUAL;
  SELECT ASCII('A') FROM DUAL;
  89. 字串的連接
  SELECT CONCAT(COL1,COL2) FROM TABLE ;
  SELECT COL1||COL2 FROM TABLE ;
  90. 怎麽把select出來的結果導到一個文字檔案中?
  SQL>SPOOL C:\ABCD.TXT;
  SQL>select * from table;
  SQL >spool off;
  91. 怎樣估算SQL執行的I/O數
  SQL>SET AUTOTRACE ON ;
  SQL>SELECT * FROM TABLE;
  OR
  SQL>SELECT * FROM v$filestat ;
  可以查看IO數
  92. 如何在sqlplus下改變欄位大小
  alter table table_name modify (field_name varchar2(100));
  改大行,改小不行(除非都是空的)
  93. 如何查詢某天的資料
  select * from table_name where
  trunc(日期欄位)=to_date('2003-05-02','yyyy-mm-dd');
  94. sql 語句如何插入全年日期?
  create table BSYEAR (d date);
  insert into BSYEAR
  select to_date('20030101','yyyymmdd')+rownum-1
  from all_objects
  where rownum <= to_char(to_date('20031231','yyyymmdd'),'ddd');
  95. 如果修改表名
  alter table old_table_name rename to new_table_name;
  96. 如何取得命令的返回狀態值?
  sqlcode=0
  97. 如何知道用戶擁有的許可權
  SELECT * FROM dba_sys_privs ;
  98. 從網上下載的ORACLE9I與市場上賣的標準版有什麽區別?
  從功能上說沒有區別,只不過oracle公司有明文規定;從網站上下載的oracle産品不得用於 商業用途,否則侵權。
  99. 怎樣判斷資料庫是運行在歸檔模式下還是運行在非歸檔模式下?
  進入dbastudio,歷程--〉資料庫---〉歸檔查看。
  100. sql>startup pfile和ifile,spfiled有什麽區別?
  pfile就是Oracle傳統的初始化參數文件,文本格式的。
  ifile類似於c語言裏的include,用於把另一個文件引入
  spfile是9i裏新增的並且是默認的參數文件,二進位格式
  startup後應該只可接pfile
  101. 如何搜索出前N條記錄?
  SELECT * FROM empLOYEE WHERE ROWNUM < n
  ORDER BY empno;
  102. 如何知道機器上的Oracle支援多少並發用戶數
  SQL>conn internal ;
  SQL>show parameter processes ;
  103. db_block_size可以修改嗎
  一般不可以﹐不建議這樣做的。
  104. 如何統計兩個表的記錄總數
  select (select count(id) from aa)+(select count(id) from bb) 總數
  from dual;
  105. 怎樣用Sql語句實現查找一列中第N大值?
  select * from
  (select t.*,dense_rank() over (order by sal) rank from employee)
  where rank = N;
  106. 如何在給現有的日期加上2年?(
  select add_months(sysdate,24) from dual;
  107. USED_UBLK爲負值表示什麽意思
  It is "harmless".
  108. Connect string是指什麽
  應該是tnsnames.ora中的服務名後面的內容
  109. 怎樣擴大REDO LOG的大小?
  建立一個臨時的redolog組,然後切換日誌,刪除以前的日誌,建立新的日誌。
  110. tablespace 是否不能大於4G
  沒有限制.
  111. 返回大於等於N的最小整數值
  SELECT CEIL(N) FROM DUAL;
  112. 返回小於等於N的最小整數值
  SELECT FLOOR(N) FROM DUAL;
  113. 返回當前月的最後一天
  SELECT LAST_DAY(SYSDATE) FROM DUAL;
  114. 如何不同用戶間數據導入
  IMP SYSTEM/MANAGER FILE=AA.DMP FROMUSER=USER_OLD TOUSER=USER_NEW
  ROWS=Y INDEXES=Y ;
  115. 如何找資料庫表的主鍵欄位的名稱
  SQL>SELECT * FROM user_constraints WHERE CONSTRAINT_TYPE='P' and
  table_name='TABLE_NAME';
  116. 兩個結果集互加的函數
  SQL>SELECT * FROM BSEMPMS_OLD INTERSECT SELECT * FROM BSEMPMS_NEW;
  SQL>SELECT * FROM BSEMPMS_OLD UNION SELECT * FROM BSEMPMS_NEW;
  SQL>SELECT * FROM BSEMPMS_OLD UNION ALL SELECT * FROM BSEMPMS_NEW;
  117. 兩個結果集互減的函數
  SQL>SELECT * FROM BSEMPMS_OLD MINUS SELECT * FROM BSEMPMS_NEW;
  118. 如何配置Sequence
  建sequence seq_custid
  create sequence seq_custid start 1 incrememt by 1;
  建表時:
  create table cust
  { cust_id smallint not null,
  ...}
  insert 時:
  insert into table cust
  values( seq_cust.nextval, ...)
  日期的各部分的常用的的寫法
  119>.取時間點的年份的寫法:
  SELECT TO_CHAR(SYSDATE,'YYYY') FROM DUAL;
  120>.取時間點的月份的寫法:
  SELECT TO_CHAR(SYSDATE,'MM') FROM DUAL;
  121>.取時間點的日的寫法:
  SELECT TO_CHAR(SYSDATE,'DD') FROM DUAL;
  122>.取時間點的時的寫法:
  SELECT TO_CHAR(SYSDATE,'HH24') FROM DUAL;
  123>.取時間點的分的寫法:
  SELECT TO_CHAR(SYSDATE,'MI') FROM DUAL;
  124>.取時間點的秒的寫法:
  SELECT TO_CHAR(SYSDATE,'SS') FROM DUAL;
  125>.取時間點的日期的寫法:
  SELECT TRUNC(SYSDATE) FROM DUAL;
  126>.取時間點的時間的寫法:
  SELECT TO_CHAR(SYSDATE,'HH24:MI:SS') FROM DUAL;
  127>.日期,時間形態變為字元形態
  SELECT TO_CHAR(SYSDATE) FROM DUAL;
  128>.將字串轉換成日期或時間形態:
  SELECT TO_DATE('2003/08/01') FROM DUAL;
  129>.返回參數的星期幾的寫法:
  SELECT TO_CHAR(SYSDATE,'D') FROM DUAL;
  130>.返回參數一年中的第幾天的寫法:
  SELECT TO_CHAR(SYSDATE,'DDD') FROM DUAL;
  131>.返回午夜和參數中指定的時間值之間的秒數的寫法:
  SELECT TO_CHAR(SYSDATE,'SSSSS') FROM DUAL;
  132>.返回參數中一年的第幾周的寫法:
  SELECT TO_CHAR(SYSDATE,'WW') FROM DUAL;
  大家在應用ORACLE的時候可能會遇到很多看起來不難的問題, 特別對新手來說, 今天我簡單把它總結一下, 發布給大家,
  希望對大家有幫助! 和大家一起探討, 共同進步!
  對ORACLE高手來說是不用看的.
  虛擬欄位
  133. CURRVAL 和 nextval
  爲表創建序列
  CREATE SEQUENCE EMPSEQ ... ;
  SELECT empseq.currval FROM DUAL ;
  自動插入序列的數值
  INSERT INTO emp
  VALUES (empseq.nextval, 'LEWIS', 'CLERK',
  7902, SYSDATE, 1200, NULL, 20) ;
  134. ROWNUM
  按設定排序的行的序號
  SELECT * FROM emp WHERE ROWNUM < 10 ;
  135. ROWID
  返回行的物理位址
  SELECT ROWID, ename FROM emp WHERE deptno = 20 ;
  136. 將N秒轉換爲時分秒格式?
  set serverout on
  declare
  N number := 1000000;
  ret varchar2(100);
  begin
  ret := trunc(n/3600) || '小時' ||
  to_char(to_date(mod(n,3600),'sssss'),'fmmi"分 "ss"秒"') ;
  dbms_output.put_line(ret);
  end;
  137. 如何查詢做比較大的排序的進程?
  SELECT b.tablespace, b.segfile#, b.segblk#, b.blocks, a.sid,
  a.serial#,
  a.username, a.osuser, a.status
  FROM v$session a,v$sort_usage b
  WHERE a.saddr = b.session_addr
  ORDER BY b.tablespace, b.segfile#, b.segblk#, b.blocks ;
  138. 如何查詢做比較大的排序的進程的SQL語句?
  select /*+ ORDERED */ sql_text from v$sqltext a
  where a.hash_value = (
  select sql_hash_value from v$session b
  where b.sid = &sid and b.serial# = &serial)
  order by piece asc ;
  139. 如何查找重復記錄?
  SELECT * FROM TABLE_NAME
  WHERE ROWID!=(SELECT MAX(ROWID) FROM TABLE_NAME D
  WHERE TABLE_NAME.COL1=D.COL1 AND TABLE_NAME.COL2=D.COL2);
  140. 如何刪除重復記錄?
  DELETE FROM TABLE_NAME
  WHERE ROWID!=(SELECT MAX(ROWID) FROM TABLE_NAME D
  WHERE TABLE_NAME.COL1=D.COL1 AND TABLE_NAME.COL2=D.COL2);
  141. 如何快速編譯所有視圖?
  SQL >SPOOL VIEW1.SQL
  SQL >SELECT 'ALTER VIEW '||TNAME||'
  COMPILE;' FROM TAB;
  SQL >SPOOL OFF
  然後執行VIEW1.SQL即可。
  SQL >@VIEW1.SQL;
  142. ORA-01555 SNAPSHOT TOO OLD的解決辦法
  增加MINEXTENTS的值,增加區的大小,設置一個高的OPTIMAL值。
  143. 事務要求的回滾段空間不夠,表現爲表空間用滿(ORA-01560錯誤),回滾段擴展到達參數
  MAXEXTENTS的值(ORA-01628)的解決辦法.
  向回滾段表空間添加文件或使已有的文件變大;增加MAXEXTENTS的值。
  144. 如何加密ORACLE的存儲過程?
  下列存儲過程內容放在AA.SQL文件中
  create or replace procedure testCCB(i in number) as
  begin
  dbms_output.put_line('輸入參數是'||to_char(i));
  end;
  SQL>wrap iname=a.sql;
  PL/SQL Wrapper: Release 8.1.7.0.0 - Production on Tue Nov 27
  22:26:48 2001
  Copyright (c) Oracle Corporation 1993, 2000. All Rights Reserved.
  Processing AA.sql to AA.plb
  運行AA.plb
  SQL> @AA.plb ;
  145. 如何監控事例的等待?
  select event,sum(decode(wait_Time,0,0,1)) "Prev",
  sum(decode(wait_Time,0,1,0)) "Curr",count(*) "Tot"
  from v$session_Wait
  group by event order by 4;
  146. 如何回滾段的爭用情況?
  select name, waits, gets, waits/gets "Ratio"
  from v$rollstat C, v$rollname D
  where C.usn = D.usn;
  147. 如何監控表空間的 I/O 比例?
  select B.tablespace_name name,B.file_name "file",A.phyrds pyr,
  A.phyblkrd pbr,A.phywrts pyw, A.phyblkwrt pbw
  from v$filestat A, dba_data_files B
  where A.file# = B.file_id
  order by B.tablespace_name;
  148. 如何監控文件系統的 I/O 比例?
  select substr(C.file#,1,2) "#", substr(C.name,1,30) "Name",
  C.status, C.bytes, D.phyrds, D.phywrts
  from v$datafile C, v$filestat D
  where C.file# = D.file#;
  149. 如何在某個用戶下找所有的索引?
  select user_indexes.table_name,
  user_indexes.index_name,uniqueness, column_name
  from user_ind_columns, user_indexes
  where user_ind_columns.index_name = user_indexes.index_name
  and user_ind_columns.table_name = user_indexes.table_name
  order by user_indexes.table_type, user_indexes.table_name,
  user_indexes.index_name, column_position;
  150. 如何監控 SGA 的命中率?
  select a.value + b.value "logical_reads", c.value "phys_reads",
  round(100 * ((a.value+b.value)-c.value) / (a.value+b.value))
  "BUFFER HIT RATIO"
  from v$sysstat a, v$sysstat b, v$sysstat c
  where a.statistic# = 38 and b.statistic# = 39
  and c.statistic# = 40;
 151. 如何監控 SGA 中字典緩衝區的命中率?
  select parameter, gets,Getmisses , getmisses/(gets+getmisses)*100
  "miss ratio",
  (1-(sum(getmisses)/ (sum(gets)+sum(getmisses))))*100 "Hit ratio"
  from v$rowcache
  where gets+getmisses <>0
  group by parameter, gets, getmisses;
  152. 如何監控 SGA 中共用緩存區的命中率,應該小於1% ?
  select sum(pins) "Total Pins", sum(reloads) "Total Reloads",
  sum(reloads)/sum(pins) *100 libcache
  from v$librarycache;
  select sum(pinhits-reloads)/sum(pins) "hit
  radio",sum(reloads)/sum(pins) "reload percent"
  from v$librarycache;
  153. 如何顯示所有資料庫物件的類別和大小?
  select count(name) num_instances ,type ,sum(source_size)
  source_size ,
  sum(parsed_size) parsed_size ,sum(code_size) code_size
  ,sum(error_size) error_size,
  sum(source_size) +sum(parsed_size) +sum(code_size)
  +sum(error_size) size_required
  from dba_object_size
  group by type order by 2;
  154. 監控 SGA 中重做日誌緩存區的命中率,應該小於1%
  SELECT name, gets, misses, immediate_gets, immediate_misses,
  Decode(gets,0,0,misses/gets*100) ratio1,
  Decode(immediate_gets+immediate_misses,0,0,
  immediate_misses/(immediate_gets+immediate_misses)*100) ratio2
  FROM v$latch WHERE name IN ('redo allocation', 'redo copy');
  155. 監控記憶體和硬碟的排序比率,最好使它小於 .10,增加 sort_area_size
  SELECT name, value FROM v$sysstat WHERE name IN ('sorts (memory)',
  'sorts (disk)');
  156. 如何監控當前資料庫誰在運行什麽SQL語句?
  SELECT osuser, username, sql_text from v$session a, v$sqltext b
  where a.sql_address =b.address order by address, piece;
  157. 如何監控字典緩衝區?
  SELECT (SUM(PINS - RELOADS)) / SUM(PINS) "LIB CACHE" FROM
  V$LIBRARYCACHE;
  SELECT (SUM(GETS - GETMISSES - USAGE - FIXED)) / SUM(GETS) "ROW
  CACHE" FROM V$ROWCACHE;
  SELECT SUM(PINS) "EXECUTIONS", SUM(RELOADS) "CACHE MISSES WHILE
  EXECUTING" FROM V$LIBRARYCACHE;
  後者除以前者,此比率小於1%,接近0%爲好。
  SELECT SUM(GETS) "DICTIONARY GETS",SUM(GETMISSES) "DICTIONARY
  CACHE GET MISSES"
  FROM V$ROWCACHE
  158. 監控 MTS
  select busy/(busy+idle) "shared servers busy" from v$dispatcher;
  此值大於0.5時,參數需加大
  select sum(wait)/sum(totalq) "dispatcher waits" from v$queue where
  type='dispatcher';
  select count(*) from v$dispatcher;
  select servers_highwater from v$mts;
  servers_highwater接近mts_max_servers時,參數需加大
  159. 如何知道當前用戶的ID號
  SQL>SHOW USER;
  OR
  SQL>select user from dual;
  160. 如何查看碎片程度高的表
  SELECT segment_name table_name , COUNT(*) extents
  FROM dba_segments WHERE owner NOT IN ('SYS', 'SYSTEM') GROUP BY
  segment_name
  HAVING COUNT(*) = (SELECT MAX( COUNT(*) ) FROM dba_segments GROUP
  BY segment_name);
  162. 如何知道表在表空間中的存儲情況
  select segment_name,sum(bytes),count(*) ext_quan from dba_extents
  where
  tablespace_name='&tablespace_name' and segment_type='TABLE' group
  by tablespace_name,segment_name;
  163. 如何知道索引在表空間中的存儲情況
  select segment_name,count(*) from dba_extents where
  segment_type='INDEX' and owner='&owner'
  group by segment_name;
  164、如何知道使用CPU多的用戶session
  11是cpu used by this session
  select a.sid,spid,status,substr(a.program,1,40)
  prog,a.terminal,osuser,value/60/100 value
  from v$session a,v$process b,v$sesstat c
  where c.statistic#=11 and c.sid=a.sid and a.paddr=b.addr order by
  value desc;
  165. 如何知道監聽器日誌文件
  以8I爲例
  $ORACLE_HOME/NETWORK/LOG/LISTENER.LOG
  166. 如何知道監聽器參數文件
  以8I爲例
  $ORACLE_HOME/NETWORK/ADMIN/LISTENER.ORA
  167. 如何知道TNS 連接文件
  以8I爲例
  $ORACLE_HOME/NETWORK/ADMIN/TNSNAMES.ORA
  168. 如何知道Sql*Net 環境文件
  以8I爲例
  $ORACLE_HOME/NETWORK/ADMIN/SQLNET.ORA
  169. 如何知道警告日誌文件
  以8I爲例
  $ORACLE_HOME/ADMIN/SID/BDUMP/SIDALRT.LOG
  170. 如何知道基本結構
  以8I爲例
  $ORACLE_HOME/RDBMS/ADMIN/STANDARD.SQL
  171. 如何知道建立資料字典視圖
  以8I爲例
  $ORACLE_HOME/RDBMS/ADMIN/CATALOG.SQL
  172. 如何知道建立審計用資料字典視圖
  以8I爲例
  $ORACLE_HOME/RDBMS/ADMIN/CATAUDIT.SQL
  173. 如何知道建立快照用資料字典視圖
  以8I爲例
  $ORACLE_HOME/RDBMS/ADMIN/CATSNAP.SQL
  本講主要講的是SQL語句的優化方法! 主要基於ORACLE9I的.
  174. /*+ALL_ROWS*/
  表明對語句塊選擇基於開銷的優化方法,並獲得最佳吞吐量,使資源消耗最小化.
  例如:
  SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE
  EMP_NO='CCBZZP';
  175. /*+FIRST_ROWS*/
  表明對語句塊選擇基於開銷的優化方法,並獲得最佳回應時間,使資源消耗最小化.
  例如:
  SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE
  EMP_NO='CCBZZP';
  176. /*+CHOOSE*/
  表明如果資料字典中有訪問表的統計資訊,將基於開銷的優化方法,並獲得最佳的吞吐量;
  表明如果資料字典中沒有訪問表的統計資訊,將基於規則開銷的優化方法;
  例如:
  SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE
  EMP_NO='CCBZZP';
  177. /*+RULE*/
  表明對語句塊選擇基於規則的優化方法.
  例如:
  SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE
  EMP_NO='CCBZZP';
  178. /*+FULL(TABLE)*/
  表明對表選擇全局掃描的方法.
  例如:
  SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE
  EMP_NO='CCBZZP';
  179. /*+ROWID(TABLE)*/
  提示明確表明對指定表根據ROWID進行訪問.
  例如:
  SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE
  ROWID>='AAAAAAAAAAAAAA'
  AND EMP_NO='CCBZZP';
  180. /*+CLUSTER(TABLE)*/
  提示明確表明對指定表選擇簇掃描的訪問方法,它只對簇物件有效.
  例如:
  SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS
  WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  181. /*+INDEX(TABLE INDEX_NAME)*/
  表明對表選擇索引的掃描方法.
  例如:
  SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE
  FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';
  182. /*+INDEX_ASC(TABLE INDEX_NAME)*/
  表明對表選擇索引昇冪的掃描方法.
  例如:
  SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE
  DPT_NO='CCBZZP';
  183. /*+INDEX_COMBINE*/
  爲指定表選擇點陣圖訪問路經,如果INDEX_COMBINE中沒有提供作爲參數的索引,將選擇出點陣圖索引的
  布林組合方式.
  例如:
  SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM
  BSEMPMS
  WHERE SAL<5000000 AND HIREDATE<SYSDATE;< SPAN>
  184. /*+INDEX_JOIN(TABLE INDEX_NAME)*/
  提示明確命令優化器使用索引作爲訪問路徑.
  例如:
  SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE
  FROM BSEMPMS WHERE SAL<60000;
  185. /*+INDEX_DESC(TABLE INDEX_NAME)*/
  表明對表選擇索引降冪的掃描方法.
  例如:
  SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE
  DPT_NO='CCBZZP';
  186. /*+INDEX_FFS(TABLE INDEX_NAME)*/
  對指定的表執行快速全索引掃描,而不是全表掃描的辦法.
  例如:
  SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE
  DPT_NO='TEC305';
  187. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/
  提示明確進行執行規劃的選擇,將幾個單列索引的掃描合起來.
  例如:
  SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM
  BSEMPMS WHERE EMP_NO='CCBZZP' AND DPT_NO='TDC306';
  188. /*+USE_CONCAT*/
  對查詢中的WHERE後面的OR條件進行轉換爲UNION ALL的組合查詢.
  例如:
  SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND
  SEX='M';
  189. /*+NO_EXPAND*/
  對於WHERE後面的OR 或者IN-LIST的查詢語句,NO_EXPAND將阻止其基於優化器對其進行擴展.
  例如:
  SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND
  SEX='M';
  190. /*+NOWRITE*/
  禁止對查詢塊的查詢重寫操作.
  191. /*+REWRITE*/
  可以將視圖作爲參數.
  192. /*+MERGE(TABLE)*/
  能夠對視圖的各個查詢進行相應的合併.
  例如:
  SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A
  (SELET DPT_NO
  ,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE
  A.DPT_NO=V.DPT_NO
  AND A.SAL>V.AVG_SAL;
  193. /*+NO_MERGE(TABLE)*/
  對於有可合併的視圖不再合併.
  例如:
  SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS
  A (SELET DPT_NO
  ,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE
  A.DPT_NO=V.DPT_NO
  AND A.SAL>V.AVG_SAL;
  194. /*+ORDERED*/
  根據表出現在FROM中的順序,ORDERED使ORACLE依此順序對其連接.
  例如:
  SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2
  B,TABLE3 C
  WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;
  195. /*+USE_NL(TABLE)*/
  將指定表與嵌套的連接的行源進行連接,並把指定表作爲內部表.
  例如:
  SELECT /*+ORDERED USE_NL(BSEMPMS)*/
  BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS
  WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  196. /*+USE_MERGE(TABLE)*/
  將指定的表與其他行源通過合併排序連接方式連接起來.
  例如:
  SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS
  WHERE
  BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  197. /*+USE_HASH(TABLE)*/
  將指定的表與其他行源通過哈希連接方式連接起來.
  例如:
  SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE
  BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  198. /*+DRIVING_SITE(TABLE)*/
  強制與ORACLE所選擇的位置不同的表進行查詢執行.
  例如:
  SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE
  BSEMPMS.DPT_NO=DEPT.DPT_NO;
  199. /*+LEADING(TABLE)*/
  將指定的表作爲連接次序中的首表.
  200. /*+CACHE(TABLE)*/
  當進行全表掃描時,CACHE提示能夠將表的檢索塊放置在緩衝區緩存中最近最少列表LRU的最近使用端
  例如:
  SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
  201. /*+NOCACHE(TABLE)*/
  當進行全表掃描時,CACHE提示能夠將表的檢索塊放置在緩衝區緩存中最近最少列表LRU的最近使用端
  例如:
  SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
  202. /*+APPEND*/
  直接插入到表的最後,可以提高速度.
  insert /*+append*/ into test1 select * from test4 ;
  203. /*+NOAPPEND*/
  通過在插入語句生存期內停止並行模式來啓動常規插入.
  insert /*+noappend*/ into test1 select * from test4 ;
  ORACLE優化器
  . 選用適合的ORACLE優化器
  ORACLE的優化器共有3種:
  a. RULE (基於規則) b. COST (基於成本) c. CHOOSE (選擇性)
  設置缺省的優化器,可以通過對init.ora文件中OPTIMIZER_MODE參數的各種聲明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS
  . 你當然也在SQL句級或是會話(session)級對其進行覆蓋.
  爲了使用基於成本的優化器(CBO, Cost-Based Optimizer) , 你必須經常運行analyze
  命令,以增加資料庫中的物件統計資訊(object statistics)的準確性.
  如果資料庫的優化器模式設置爲選擇性(CHOOSE),那麽實際的優化器模式將和是否運行過analyze命令有關.
  如果table已經被analyze過, 優化器模式將自動成爲CBO , 反之,資料庫將採用RULE形式的優化器.
  在缺省情況下,ORACLE採用CHOOSE優化器, 爲了避免那些不必要的全表掃描(full table scan) ,
  你必須儘量避免使用CHOOSE優化器,而直接採用基於規則或者基於成本的優化器.
  2. 訪問Table的方式
  ORACLE 採用兩種訪問表中記錄的方式:
  a. 全表掃描
  全表掃描就是順序地訪問表中每條記錄. ORACLE採用一次讀入多個資料塊(database block)的方式優化全表掃描.
  b. 通過ROWID訪問表
  你可以採用基於ROWID的訪問方式情況,提高訪問表的效率, ,
  ROWID包含了表中記錄的物理位置資訊..ORACLE採用索引(INDEX)實現了資料和存放資料的物理位置(ROWID)之間的聯繫.
  通常索引提供了快速訪問ROWID的方法,因此那些基於索引列的查詢就可以得到性能上的提高.
  3. 共用SQL語句
  爲了不重復解析相同的SQL語句,在第一次解析之後, ORACLE將SQL語句存放在記憶體中.這塊位於系統全局區域SGA(system
  global area)的共用池(shared buffer pool)中的記憶體可以被所有的資料庫用戶共用.
  因此,當你執行一個SQL語句(有時被稱爲一個游標)時,如果它
  和之前的執行過的語句完全相同, ORACLE就能很快獲得已經被解析的語句以及最好的
  執行路徑. ORACLE的這個功能大大地提高了SQL的執行性能並節省了記憶體的使用.
  可惜的是ORACLE只對簡單的表提供高速緩衝(cache buffering) ,這個功能並不適用於多表連接查詢.
  資料庫管理員必須在init.ora中爲這個區域設置合適的參數,當這個記憶體區域越大,就可以保留更多的語句,當然被共用的可能性也就越大了.
  當你向ORACLE 提交一個SQL語句,ORACLE會首先在這塊記憶體中查找相同的語句.
  這裏需要注明的是,ORACLE對兩者採取的是一種嚴格匹配,要達成共用,SQL語句必須
  完全相同(包括空格,換行等).
  共用的語句必須滿足三個條件:
  A. 字元級的比較:
  當前被執行的語句和共用池中的語句必須完全相同.
  例如:
  SELECT * FROM EMP;
  和下列每一個都不同
  SELECT * from EMP;
  Select * From Emp;
  SELECT * FROM EMP;
  B. 兩個語句所指的物件必須完全相同:
  例如:
  用戶 物件名 如何訪問
  Jack sal_limit private synonym
  Work_city public synonym
  Plant_detail public synonym
  Jill sal_limit private synonym
  Work_city public synonym
  Plant_detail table owner
  考慮一下下列SQL語句能否在這兩個用戶之間共用.
  SQL
  能否共用
  原因
  select max(sal_cap) from sal_limit;
  不能
  每個用戶都有一個private synonym - sal_limit , 它們是不同的物件
  select count(*0 from work_city where sdesc like 'NEW%';
  能
  兩個用戶訪問相同的物件public synonym - work_city
  select a.sdesc,b.location from work_city a , plant_detail b where
  a.city_id = b.city_id
  不能
  用戶jack 通過private synonym訪問plant_detail 而jill 是表的所有者,物件不同.
  C. 兩個SQL語句中必須使用相同的名字的綁定變數(bind variables)
  例如:
  第一組的兩個SQL語句是相同的(可以共用),而第二組中的兩個語句是不同的(即使在運行時,賦於不同的綁定變數相同的值)
  a.
  select pin , name from people where pin = :blk1.pin;
  select pin , name from people where pin = :blk1.pin;
  b.
  select pin , name from people where pin = :blk1.ot_ind;
  select pin , name from people where pin = :blk1.ov_ind;
  4. 選擇最有效率的表名順序(只在基於規則的優化器中有效)
  ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,因此FROM子句中寫在最後的表(基礎表 driving
  table)將被最先處理. 在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作爲基礎表.當ORACLE處理多個表時,
  會運用排序及合併的方式連接它們.首先,掃描第一個表(FROM子句中最後的那個表)並對記錄進行派序,然後掃描第二個表(FROM子句中最後第二個表),最後將所有從第二個表中檢索出的記錄與第一個表中合適記錄進行合併.
  例如:
  表 TAB1 16,384 條記錄
  表 TAB2 1 條記錄
  選擇TAB2作爲基礎表 (最好的方法)
  select count(*) from tab1,tab2 執行時間0.96秒
  選擇TAB2作爲基礎表 (不佳的方法)
  select count(*) from tab2,tab1 執行時間26.09秒
  如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作爲基礎表,
  交叉表是指那個被其他表所引用的表.
  例如:
  EMP表描述了LOCATION表和CATEGORY表的交集.
  SELECT *
  FROM LOCATION L ,
  CATEGORY C,
  EMP E
  WHERE E.EMP_NO BETWEEN 1000 AND 2000
  AND E.CAT_NO = C.CAT_NO
  AND E.LOCN = L.LOCN
  將比下列SQL更有效率
  SELECT *
  FROM EMP E ,
  LOCATION L ,
  CATEGORY C
  WHERE E.CAT_NO = C.CAT_NO
  AND E.LOCN = L.LOCN
  AND E.EMP_NO BETWEEN 1000 AND 2000
  5. WHERE子句中的連接順序.
  ORACLE採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前,
  那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾.
  例如:
  (低效,執行時間156.3秒)
  SELECT …
  FROM EMP E
  WHERE SAL > 50000
  AND JOB = 'MANAGER'
  AND 25 < (SELECT COUNT(*) FROM EMP
  WHERE MGR=E.EMPNO);
  (高效,執行時間10.6秒)
  SELECT …
  FROM EMP E
  WHERE 25 < (SELECT COUNT(*) FROM EMP
  WHERE MGR=E.EMPNO)
  AND SAL > 50000
  AND JOB = 'MANAGER';
  6. SELECT子句中避免使用 ' * '
  當你想在SELECT子句中列出所有的COLUMN時,使用動態SQL列引用 '*'
  是一個方便的方法.不幸的是,這是一個非常低效的方法. 實際上,ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名,
  這個工作是通過查詢資料字典完成的, 這意味著將耗費更多的時間.
  7. 減少訪問資料庫的次數
  當執行每條SQL語句時, ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變數 , 讀資料塊等等.
  由此可見, 減少訪問資料庫的次數 , 就能實際上減少ORACLE的工作量.
  例如,
  以下有三種方法可以檢索出雇員號等於0342或0291的職員.
  方法1 (最低效)
  SELECT EMP_NAME , SALARY , GRADE
  FROM EMP
  WHERE EMP_NO = 342;
  SELECT EMP_NAME , SALARY , GRADE
  FROM EMP
  WHERE EMP_NO = 291;
  方法2 (次低效)
  DECLARE
  CURSOR C1 (E_NO NUMBER) IS
  SELECT EMP_NAME,SALARY,GRADE
  FROM EMP
  WHERE EMP_NO = E_NO;
  BEGIN
  OPEN C1(342);
  FETCH C1 INTO …,..,.. ;
  …..
  OPEN C1(291);
  FETCH C1 INTO …,..,.. ;
  CLOSE C1;
  END;
  方法3 (高效)
  SELECT A.EMP_NAME , A.SALARY , A.GRADE,
  B.EMP_NAME , B.SALARY , B.GRADE
  FROM EMP A,EMP B
  WHERE A.EMP_NO = 342
  AND B.EMP_NO = 291;
  注意:
  在SQL*Plus , SQL*Forms和Pro*C中重新設置ARRAYSIZE參數, 可以增加每次資料庫訪問的檢索資料量
  ,建議值爲200
  8. 使用DECODE函數來減少處理時間
  使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表.
  例如:
  SELECT COUNT(*),SUM(SAL)
  FROMEMP
  WHERE DEPT_NO = 0020
  AND ENAME LIKE'SMITH%';
  SELECT COUNT(*),SUM(SAL)
  FROMEMP
  WHERE DEPT_NO = 0030
  AND ENAME LIKE'SMITH%';
  你可以用DECODE函數高效地得到相同結果
  SELECT COUNT(DECODE(DEPT_NO,0020,'X',NULL)) D0020_COUNT,
  COUNT(DECODE(DEPT_NO,0030,'X',NULL)) D0030_COUNT,
  SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,
  SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL
  FROM EMP WHERE ENAME LIKE 'SMITH%';
  類似的,DECODE函數也可以運用於GROUP BY 和ORDER BY子句中.
  9. 整合簡單,無關聯的資料庫訪問
  如果你有幾個簡單的資料庫查詢語句,你可以把它們整合到一個查詢中(即使它們之間沒有關係)
  例如:
  SELECT NAME
  FROM EMP
  WHERE EMP_NO = 1234;
  SELECT NAME
  FROM DPT
  WHERE DPT_NO = 10 ;
  SELECT NAME
  FROM CAT
  WHERE CAT_TYPE = 'RD';
  上面的3個查詢可以被合併成一個:
  SELECT E.NAME , D.NAME , C.NAME
  FROM CAT C , DPT D , EMP E,DUAL X
  WHERE NVL('X',X.DUMMY) = NVL('X',E.ROWID(+))
  AND NVL('X',X.DUMMY) = NVL('X',D.ROWID(+))
  AND NVL('X',X.DUMMY) = NVL('X',C.ROWID(+))
  AND E.EMP_NO(+) = 1234
  AND D.DEPT_NO(+) = 10
  AND C.CAT_TYPE(+) = 'RD';
  (譯者按: 雖然採取這種方法,效率得到提高,但是程式的可讀性大大降低,所以讀者 還是要權衡之間的利弊)
  10. 刪除重復記錄
  最高效的刪除重復記錄方法 ( 因爲使用了ROWID)
  DELETE FROM EMP E
  WHERE E.ROWID > (SELECT MIN(X.ROWID)
  FROM EMP X
  WHERE X.EMP_NO = E.EMP_NO);
  11. 用TRUNCATE替代DELETE
  當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復的資訊.
  如果你沒有COMMIT事務,ORACLE會將資料恢復到刪除之前的狀態(準確地說是
  恢復到執行刪除命令之前的狀況)
  而當運用TRUNCATE時,
  回滾段不再存放任何可被恢復的資訊.當命令運行後,資料不能被恢復.因此很少的資源被調用,執行時間也會很短.
  (譯者按: TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML)
  12. 儘量多使用COMMIT
  只要有可能,在程式中儘量多使用COMMIT, 這樣程式的性能得到提高,需求也會因爲COMMIT所釋放的資源而減少:
  COMMIT所釋放的資源:
  a. 回滾段上用於恢復資料的資訊.
  b. 被程式語句獲得的鎖
  c. redo log buffer 中的空間
  d. ORACLE爲管理上述3種資源中的內部花費
  (譯者按: 在使用COMMIT時必須要注意到事務的完整性,現實中效率和事務完整性往往是魚和熊掌不可得兼)
  13. 計算記錄條數
  和一般的觀點相反, count(*) 比count(1)稍快 , 當然如果可以通過索引檢索,對索引列的計數仍舊是最快的. 例如
  COUNT(EMPNO)
  (譯者按: 在CSDN論壇中,曾經對此有過相當熱烈的討論,
  作者的觀點並不十分準確,通過實際的測試,上述三種方法並沒有顯著的性能差別)
  14. 用Where子句替換HAVING子句
  避免使用HAVING子句, HAVING 只會在檢索出所有記錄之後才對結果集進行過濾. 這個處理需要排序,總計等操作.
  如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷.
  例如:
  低效:
  SELECT REGION,AVG(LOG_SIZE)
  FROM LOCATION
  GROUP BY REGION
  HAVING REGION REGION != 'SYDNEY'
  AND REGION != 'PERTH'
  高效
  SELECT REGION,AVG(LOG_SIZE)
  FROM LOCATION
  WHERE REGION REGION != 'SYDNEY'
  AND REGION != 'PERTH'
  GROUP BY REGION
  (譯者按: HAVING 中的條件一般用於對一些集合函數的比較,如COUNT() 等等.
  除此而外,一般的條件應該寫在WHERE子句中)
  15. 減少對表的查詢
  在含有子查詢的SQL語句中,要特別注意減少對表的查詢.
  例如:
  低效
  SELECT TAB_NAME
  FROM TABLES
  WHERE TAB_NAME = ( SELECT TAB_NAME
  FROM TAB_COLUMNS
  WHERE VERSION = 604)
  ANDDB_VER= ( SELECT DB_VER
  FROM TAB_COLUMNS
  WHERE VERSION = 604)
  高效
  SELECT TAB_NAME
  FROM TABLES
  WHERE (TAB_NAME,DB_VER)
  = ( SELECT TAB_NAME,DB_VER)
  FROM TAB_COLUMNS
  WHERE VERSION = 604)
  Update 多個Column 例子:
  低效:
  UPDATE EMP
  SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),
  SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)
  WHERE EMP_DEPT = 0020;
  高效:
  UPDATE EMP
  SET (EMP_CAT, SAL_RANGE)
  = (SELECT MAX(CATEGORY) , MAX(SAL_RANGE)
  FROM EMP_CATEGORIES)
  WHERE EMP_DEPT = 0020;
  16. 通過內部函數提高SQL效率.
  SELECT H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC,COUNT(*)
  FROM HISTORY_TYPE T,EMP E,EMP_HISTORY H
  WHERE H.EMPNO = E.EMPNO
  AND H.HIST_TYPE = T.HIST_TYPE
  GROUP BY H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC;
  通過調用下面的函數可以提高效率.
  FUNCTION LOOKUP_HIST_TYPE(TYP IN NUMBER) RETURN VARCHAR2
  AS
  TDESC VARCHAR2(30);
  CURSOR C1 IS
  SELECT TYPE_DESC
  FROM HISTORY_TYPE
  WHERE HIST_TYPE = TYP;
  BEGIN
  OPEN C1;
  FETCH C1 INTO TDESC;
  CLOSE C1;
  RETURN (NVL(TDESC,' '));
  END;
  FUNCTION LOOKUP_EMP(EMP IN NUMBER) RETURN VARCHAR2
  AS
  ENAME VARCHAR2(30);
  CURSOR C1 IS
  SELECT ENAME
  FROM EMP
  WHERE EMPNO=EMP;
  BEGIN
  OPEN C1;
  FETCH C1 INTO ENAME;
  CLOSE C1;
  RETURN (NVL(ENAME,' '));
  END;
  SELECT H.EMPNO,LOOKUP_EMP(H.EMPNO),
  H.HIST_TYPE,LOOKUP_HIST_TYPE(H.HIST_TYPE),COUNT(*)
  FROM EMP_HISTORY H
  GROUP BY H.EMPNO , H.HIST_TYPE;
  (譯者按: 經常在論壇中看到如 '能不能用一個SQL寫出….' 的貼子, 殊不知複雜的SQL往往犧牲了執行效率.
  能夠掌握上面的運用函數解決問題的方法在實際工作中是非常有意義的)
  17. 使用表的別名(Alias)
  當在SQL語句中連接多個表時,
  請使用表的別名並把別名字首於每個Column上.這樣一來,就可以減少解析的時間並減少那些由Column歧義引起的語法錯誤.
  (譯者注:
  Column歧義指的是由於SQL中不同的表具有相同的Column名,當SQL語句中出現這個Column時,SQL解析器無法判斷這個Column的歸屬)
  18. 用EXISTS替代IN
  在許多基於基礎表的查詢中,爲了滿足一個條件,往往需要對另一個表進行聯接.在這種情況下, 使用EXISTS(或NOT
  EXISTS)通常將提高查詢的效率.
  低效:
  SELECT *
  FROM EMP (基礎表)
  WHERE EMPNO > 0
  AND DEPTNO IN (SELECT DEPTNO
  FROM DEPT
  WHERE LOC = 'MELB')
  高效:
  SELECT *
  FROM EMP (基礎表)
  WHERE EMPNO > 0
  AND EXISTS (SELECT 'X'
  FROM DEPT
  WHERE DEPT.DEPTNO = EMP.DEPTNO
  AND LOC = 'MELB')
  (譯者按: 相對來說,用NOT EXISTS替換NOT IN 將更顯著地提高效率,下一節中將指出)
  19. 用NOT EXISTS替代NOT IN
  在子查詢中,NOT IN子句將執行一個內部的排序和合併. 無論在哪種情況下,NOT IN都是最低效的
  (因爲它對子查詢中的表執行了一個全表遍曆). 爲了避免使用NOT IN ,我們可以把它改寫成外連接(Outer Joins)或NOT
  EXISTS.
  例如:
  SELECT …
  FROM EMP
  WHERE DEPT_NO NOT IN (SELECT DEPT_NO
  FROM DEPT
  WHERE DEPT_CAT='A');
  爲了提高效率.改寫爲:
  (方法一: 高效)
  SELECT ….
  FROM EMP A,DEPT B
  WHERE A.DEPT_NO = B.DEPT(+)
  AND B.DEPT_NO IS NULL
  AND B.DEPT_CAT(+) = 'A'
  (方法二: 最高效)
  SELECT ….
  FROM EMP E
  WHERE NOT EXISTS (SELECT 'X'
  FROM DEPT D
  WHERE D.DEPT_NO = E.DEPT_NO
  AND DEPT_CAT = 'A');
  20. 用表連接替換EXISTS
  通常來說 , 採用表連接的方式比EXISTS更有效率
  SELECT ENAME
  FROM EMP E
  WHERE EXISTS (SELECT 'X'
  FROM DEPT
  WHERE DEPT_NO = E.DEPT_NO
  AND DEPT_CAT = 'A');
  (更高效)
  SELECT ENAME
  FROM DEPT D,EMP E
  WHERE E.DEPT_NO = D.DEPT_NO
  AND DEPT_CAT = 'A' ;
  (譯者按: 在RBO的情況下,前者的執行路徑包括FILTER,後者使用NESTED LOOP)

2009/03/12

快速檢查 DB alert log 的語法

摘自:網路

不知道你有沒有遇過需要去 DB alert log 裡頭
去抓取 ORA- 開頭發生的狀況

如果你用 vi 去搜尋,只能一筆一筆依序判讀,很沒效率

其實可以透過 "sed" 的語法,篩選特定字元,顯示上一行的「時間」

例如:
sed '/ORA-/H;x;/\n/!d' alert_PROD.log

顯示的結果: 這樣可以快速列出 db alert log 發生的問題跟時間
Wed May 21 20:17:35 2008
ORA-1652: unable to extend temp segment by 16 in tablespace TEMP
Wed May 21 20:17:36 2008
ORA-1652: unable to extend temp segment by 16 in tablespace TEMP
Thu May 22 01:14:53 2008
ORA-01555 caused by SQL statement below (Query Duration=39068 sec, SCN: 0x0007.69a1780f):


另外呢,如果我們想要找..上次開關機之間的時間?
這樣就很有效率去顯示從 alert log 記錄的DB開關 時間囉

### 顯示 alter database open 的上一行 系統時間

sed '/ALTER DATABASE OPEN/H;x;/\n/!d' alert_PROD.log

輸出片段:
Thu May 1 09:10:09 2008
ALTER DATABASE OPEN
replication_dependency_tracking turned off (no async multimaster replication found)
Completed: ALTER DATABASE OPEN
Thu May 1 11:44:23 2008
ALTER DATABASE OPEN
replication_dependency_tracking turned off (no async multimaster replication found)
Completed: ALTER DATABASE OPEN
Thu May 15 18:20:29 2008
ALTER DATABASE OPEN
replication_dependency_tracking turned off (no async multimaster replication found)
Completed: ALTER DATABASE OPEN

Oracle Partition Table

摘自:網路

1.1 分区表PARTITION table

ORACLE里如果遇到特别大的表,可以使用分区的表来改变其应用程序的性能。

1.1.1 分区表的建立:

某公司的每年产生巨大的销售记录,DBA向公司建议每季度的数据放在一个分区内,以下示范的是该公司1999年的数据(假设每月产生30M的数据),操作如下:

范围分区表:

CREATE TABLE sales

(invoice_no NUMBER,

...

sale_date DATE NOT NULL )

PARTITION BY RANGE (sale_date)

(PARTITION sales1999_q1

VALUES LESS THAN (TO_DATE(1999-04-01,YYYY-MM-DD)

TABLESPACE ts_sale1999q1,

PARTITION sales1999_q2

VALUES LESS THAN (TO_DATE(1999-07-01,YYYY-MM-DD)

TABLESPACE ts_sale1999q2,

PARTITION sales1999_q3

VALUES LESS THAN (TO_DATE(1999-10-01,YYYY-MM-DD)

TABLESPACE ts_sale1999q3,

PARTITION sales1999_q4

VALUES LESS THAN (TO_DATE(2000-01-01,YYYY-MM-DD)

TABLESPACE ts_sale1999q4 );

--values less than (maxvalue)

列表分区表:

create table emp (

empno number(4),

ename varchar2(30),

location varchar2(30))

partition by list (location)

(partition p1 values ('北京'),

partition p2 values ('上海','天津','重庆'),

partition p3 values ('广东','福建')

partition p0 values (default)

);

哈希分区:

create table emp (

empno number(4),

ename varchar2(30),

sal number)

partition by hash (empno)

partitions 8

store in (emp1,emp2,emp3,emp4,emp5,emp6,emp7,emp8);

组合分区:

范围哈希组合分区:

create table emp (

empno number(4),

ename varchar2(30),

hiredate date)

partition by range (hiredate)

subpartition by hash (empno)

subpartitions 2

(partition e1 values less than (to_date('20020501','YYYYMMDD')),

partition e2 values less than (to_date('20021001','YYYYMMDD')),

partition e3 values less than (maxvalue));

范围列表组合分区:

CREATE TABLE customers_part (

customer_id NUMBER(6),

cust_first_name VARCHAR2(20),

cust_last_name VARCHAR2(20),

nls_territory VARCHAR2(30),

credit_limit NUMBER(9,2))

PARTITION BY RANGE (credit_limit)

SUBPARTITION BY LIST (nls_territory)

SUBPARTITION TEMPLATE

(SUBPARTITION east VALUES ('CHINA', 'JAPAN', 'INDIA', 'THAILAND'),

SUBPARTITION west VALUES ('AMERICA', 'GERMANY', 'ITALY', 'SWITZERLAND'),

SUBPARTITION other VALUES (DEFAULT))

(PARTITION p1 VALUES LESS THAN (1000),

PARTITION p2 VALUES LESS THAN (2500),

PARTITION p3 VALUES LESS THAN (MAXVALUE));

create table t1 (id1 number,id2 number)

partition by range (id1) subpartition by list (id2)

(partition p11 values less than (11)

(subpartition subp1 values (1))

);

索引分区:

CREATE INDEX month_ix ON sales(sales_month)
GLOBAL PARTITION BY RANGE(sales_month)
(PARTITION pm1_ix VALUES LESS THAN (2)
PARTITION pm12_ix VALUES LESS THAN (MAXVALUE));

1.1.2 分区表的维护:

增加分区:

ALTER TABLE sales ADD PARTITION sales2000_q1

VALUES LESS THAN (TO_DATE(2000-04-01,YYYY-MM-DD)

TABLESPACE ts_sale2000q1;

如果已有maxvalue分区,不能增加分区,可以采取分裂分区的办法增加分区!

删除分区:

ALTER TABLE sales DROP PARTION sales1999_q1;

截短分区:

alter table sales truncate partiton sales1999_q2;

合并分区:

alter table sales merge partitons sales1999_q2, sales1999_q3 into sales1999_q23;

alter index ind_t2 rebuild partition p123 parallel 2;

分裂分区:

ALTER TABLE sales

SPLIT PARTITON sales1999_q4

AT TO_DATE (1999-11-01,YYYY-MM-DD)

INTO (partition sales1999_q4_p1, partition sales1999_q4_p2) ;

alter table t2 split partition p123 values (1,2) into (partition p12,partition p3);

交换分区:

alter table x exchange partition p0 with table bsvcbusrundatald ;

访问指定分区:

select * from sales partition(sales1999_q2)

EXPORT指定分区:

exp sales/sales_password tables=sales:sales1999_q1

file=sales1999_q1.dmp

IMPORT指定分区:

imp sales/sales_password FILE =sales1999_q1.dmp

TABLES = (sales:sales1999_q1) IGNORE=y

查看分区信息

user_tab_partitions, user_segments

注:若分区表跨不同表空间,做导出、导入时目标数据库必须预建这些表空间。分表区各区所在表空间在做导入时目标数据库一定要预建这些表空间!这些表空间不一定是用户的默认表空间,只要存在即可。如果有一个不存在,就会报错!

默 认时,对分区表的许多表维护操作会使全局索引不可用,标记成UNUSABLE。 那么就必须重建整个全局索引或其全部分区。如果已被分区,Oracle 允许在用于维护操作的ALTER TABLE 语句中指定UPDATE GLOBAL INDEXES 来重载这个默认特性,指定这个子句也就告诉Oracle 当它执行维护操作的DDL 语句时更新全局索引,这提供了如下好处:
1.在操作基础表的同时更新全局索引这就不需要后来单独地重建全局索引;
2.因为没有被标记成UNUSABLE, 所以全局索引的可用性更高了,甚至正在执行分区的DDL 语句时仍然可用索引来访问表中的其他分区,避免了查询所有失效的全局索引的名字以便重建它们;
另外在指定UPDATE GLOBAL INDEXES 之前还要考虑如下性能因素:
1.因为要更新事先被标记成UNUSABLE 的索引,所以分区的DDL 语句要执行更长时间,当然这要与先不更新索引而执行DDL 然后再重建索引所花的时间做个比较,一个适用的规则是如果分区的大小小于表的大小的5% ,则更新索引更快一点;
2.DROP TRUNCATE 和EXCHANGE 操作也不那么快了,同样这必须与先执行DDL 然后再重建所有全局索引所花的时间做个比较;
3.要登记对索引的更新并产生重做记录和撤消记录,重建整个索引时可选择NOLOGGING;
4.重建整个索引产生一个更有效的索引,因为这更利于使用空间,再者重建索引时允许修改存储选项。
注意分区索引结构表不支持UPDATE GLOBAL INDEXES 子句。

1.1.3 普通表变为分区表

将已存在数据的普通表转变为分区表,没有办法通过修改属性的方式直接转化为分区表,必须通过重建的方式进行转变,一般可以有三种方法,视不同场景使用:

用例:

方法一:利用原表重建分区表。

CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO T
SELECT ROWNUM, SYSDATE - ROWNUM FROM DBA_OBJECTS WHERE ROWNUM <=
5000
;
COMMIT;

CREATE TABLE T_NEW (ID, TIME) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2000-1-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (TO_DATE('2002-1-1', 'YYYY-MM-DD')),
PARTITION P3 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),
PARTITION P4 VALUES LESS THAN (MAXVALUE))
AS SELECT ID, TIME FROM T;

RENAME T TO T_OLD;

RENAME T_NEW TO T;

SELECT COUNT(*) FROM T;

COUNT(*)
----------
5000

SELECT COUNT(*) FROM T PARTITION (P1);

COUNT(*)
----------
2946

SELECT COUNT(*) FROM T PARTITION (P2);

COUNT(*)
----------
731

SELECT COUNT(*) FROM T PARTITION (P3);

COUNT(*)
----------
1096

优点:方法简单易用,由于采用DDL语句,不会产生UNDO,且只产生少量REDO,效率相对较高,而且建表完成后数据已经在分布到各个分区中了。

不足:对于数据的一致性方面还需要额外的考虑。由于几乎没有办法通过手工锁定T表的方式保证一致性,在执行CREATE TABLE语句和RENAME T_NEW TO T语句直接的修改可能会丢失,如果要保证一致性,需要在执行完语句后对数据进行检查,而这个代价是比较大的。另外在执行两个RENAME语句之间执行的对T的访问会失败。

适用于修改不频繁的表,在闲时进行操作,表的数据量不宜太大。

方法二:使用交换分区的方法。

Drop table t;
CREATE
TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO T
SELECT ROWNUM, SYSDATE - ROWNUM FROM DBA_OBJECTS WHERE ROWNUM <=
5000
;
COMMIT;

CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2005-9-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (MAXVALUE));

ALTER TABLE T_NEW EXCHANGE PARTITION P1 WITH TABLE T;

RENAME T TO T_OLD;

RENAME T_NEW TO T;

优点:只是对数据字典中分区和表的定义进行了修改,没有数据的修改或复制,效率最高。如果对数据在分区中的分布没有进一步要求的话,实现比较简单。在执行完RENAME操作后,可以检查T_OLD中是否存在数据,如果存在的话,直接将这些数据插入到T中,可以保证对T插入的操作不会丢失。

不足:仍然存在一致性问题,交换分区之后RENAME T_NEW TO T之前,查询、更新和删除会出现错误或访问不到数据。如果要求数据分布到多个分区中,则需要进行分区的SPLIT操作,会增加操作的复杂度,效率也会降低。

适用于包含大数据量的表转到分区表中的一个分区的操作。应尽量在闲时进行操作。

方法三:Oracle9i以上版本,利用在线重定义功能

Drop table t;
CREATE
TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO T
SELECT ROWNUM, SYSDATE - ROWNUM FROM DBA_OBJECTS WHERE ROWNUM <=
5000
;
COMMIT;

EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(USER, 'T');

PL/SQL 过程已成功完成。

CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2004-7-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),
PARTITION P3 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),
PARTITION P4 VALUES LESS THAN (MAXVALUE));

表已创建。

EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'T', 'T_NEW');

PL/SQL 过程已成功完成。

EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER, 'T', 'T_NEW');

PL/SQL 过程已成功完成。

SELECT COUNT(*) FROM T;

COUNT(*)
----------
5000

SELECT COUNT(*) FROM T PARTITION (P3);

COUNT(*)
----------
1096

优点:保证数据的一致性,在大部分时间内,表T都可以正常进行DML操作。只在切换的瞬间锁表,具有很高的可用性。这种方法具有很强的灵活性,对各种不同的需要都能满足。而且,可以在切换前进行相应的授权并建立各种约束,可以做到切换完成后不再需要任何额外的管理操作。

不足:实现上比上面两种略显复杂。

适用于各种情况。

这里只给出了在线重定义表的一个最简单的例子,详细的描述和例子可以参考下面两篇文章。

Oracle的在线重定义表功能:http://blog.itpub.net/post/468/12855

Oracle的在线重定义表功能(二):http://blog.itpub.net/post/468/12962


XSB:把一个已存在数据的大表改成分区表:

第一种(表不是太大):

1.把原表改名:
rename xsb1 to xsb2;
2.创建分区表:
CREATE TABLE xsb1
PARTITION BY LIST (c_test)
(PARTITION xsb1_p1 VALUES (1),
PARTITION xsb1_p2 VALUES (2),
PARTITION xsb1_p0 VALUES (default))
nologging AS SELECT * FROM xsb2;
3.将原表上的触发器、主键、索引等应用到分区表上;
4.删除原表:
drop table xsb2;

第二种(表很大):

1. 创建分区表:
CREATE TABLE x PARTITION BY LIST (c_test) [range ()]
(PARTITION p0 VALUES [less than ](1) tablespace tbs1,
PARTITION p2 VALUES (2) tablespace tbs1,
PARTITION xsb1_p0 VALUES ([maxvalue]default))
AS SELECT * FROM xsb2 [where 1=2];

2. 交换分区 alter table x exchange partition p0 with table bsvcbusrundatald ;

3. 原表改名alter table bsvcbusrundatald rename to x0;

4. 新表改名alter table x rename to bsvcbusrundatald ;

5. 删除原表drop table x0;

6. 创建新表触发器和索引create index ind_busrundata_lp on bsvcbusrundatald(。。。) local tablespace tbs_brd_ind ;


或者:

1. 规划原大表中数据分区的界限,原则上将原表中近期少量数据复制至另一表;

2. 暂停原大表中的相关触发器;

3. 删除原大表中近期数据;

4. 改名原大表名称;

5. 创建分区表;

6. 交换分区;

7. 重建相关索引及触发器(先删除之再重建).

参考脚本:

select count(*) from t1 where recdate>sysdate-2

create table x2 nologging as select * from t1 where recdate>trunc(sysdate-2)

alter triger trg_t1 disable

delete t1 where recdate>sysdate-2

commit

rename t1 to x1

create table t1 [nologging] partition by range(recdate)

(partition pbefore values less than (trunc(sysdate-2)),

partition pmax values less than (maxvalue))

as select * from x1 where 1=2

alter table t1 exchange partition pbefore with table x1

alter table t1 exchange partition pmax with table x2

drop table x2

[重建触发器]

drop table x1


1.1.4 参考材料:
如果表中预期的数据量较大,通常都需要考虑使用分区表,确定使用分区表后,还要确定什么类型的分区 (range partition、hash partition、list partition等)、分区区间大小等。分区的创建最好与程序有某种默契,偶曾经创建分区表,按自然月份定义分区的,但程序却在查询时默认的开始时间与 结束时间是:当前日期-30至当前日期,比如当天是9.18号,那查询条件被产生为8.18-9.18,结果分区后并不没有大幅提高性能,后来对程序的查 询日期做了调整,按自然月查询,系统的负载小了很多。

从Oracle8.0开始支持表分区(MSSQL2005开始支持表分区)。

Oracle9i 分区能够提高许多应用程序的可管理性、性能与可用性。分区可以将表、索引及索引编排表进一步划分,从而可以更精细地对这些数据库对象进行管理和访问。 Oracle 提供了种类繁多的分区方案以满足所有的业务需要。另外,由于在 SQL 语句中是完全透明的,所以分区可以用于几乎所有的应用程序。

分区表允许将数据分成被称为分区甚至子分区的更小的更好管理的块。索引也可以这么分区。每个分区可以被单独管理,可以不依赖于其他分区而单独发挥作用,因此提供了一个更有利于可用性和性能的结构。

分区可以提高可管理性、性能与可用性,从而给各种各样的应用程序带来极大的好处。通常,分区可以使某些查询以及维护操作的性能大大提高。此外,分区 还能够在很大程度上简化日常管理任务。分区还使数据库设计人员和管理员能够解决尖端应用程序带来的最难的问题。分区是建立上亿万字节数据系统或需要极高可 用性系统的关键工具。

在多CPU配置环境下,如果打算使用并行执行,则分区提供了另一种并行的方法。通过给表或索引的不同分区分配不同的并行执行服务器,就可以并行执行对分区表和分区索引的操作。

表或索引的分区和子分区都共享相同的逻辑属性。例如表的所有分区或子分区共享相同的列和约束定义,一个索引的分区或子分区共享相同的索引选项。然而它们可以具有不同的物理属性如表空间。

尽管不需要将表或索引的每个分区或子分区放在不同的表空间,但这样做更好。将分区存储到不同的表空间能够

l 减少数据在多个分区中冲突的可能性

l 可以单独备份和恢复每个分区

l 控制分区与磁盘驱动器之间的映射对平衡I/O 负载是重要的

l 改善可管理性可用性和性能

分区操作对现存的应用和运行在分区表上的标准DML 语句来说是透明的。但是可以通过在DML 中使用分区扩展表或索引的名字来对应用编程,使其利用分区的优点。

可以使用SQL*Loader、Import 和Export 工具来装载或卸载分区表中的数据。这些工具都是支持分区和子分区的。

分区的方法Oracle9i 提供了如下5种分区方法:

l 范围分区Range

l 散列分区Hash

l 列表分区List

l 组合范围-散列分区Range-Hash

l 组合范围-列表分区Range-List

可对索引和表分区。全局索引只能按范围分区,但可以将其定义在任何类型的分区或非分区表上。通常全局索引比局部索引需要更多的维护。

一般组建局部索引,以便反映其基础表的结构。它与基础表是等同分区的,即它与基础

表在同样的列上分区,创建同样数量的分区或子分区,设置与基础表相对应的同样的分区边界。对局部索引而言,当维护活动影响分区时,会自动维护索引分区。这保证了索引与基础表之间的等同分区。

关于范围分区Range:

要想将行映射到基于列值范围的分区,就使用范围分区方法。当数据可以被划分成逻辑范围时如年度中的月份,这种类型的分区就有用了。当数据在整个范围中能被均等地划分时性能最好。如果靠范围的分区会由于不均等的划分而导致分区在大小上明显不同时,就需要考虑其他的分区方法。

关于散列分区Hash:

如果数据不那么容易进行范围分区,但为了性能和管理的原因又想分区时,就使用散列分区方法。散列分区提供了一种在指定数量的分区中均等地划分数据的 方法。基于分区键的散列值将行映射到分区中。创建和使用散列分区会给你提供了一种很灵活的放置数据的方法,因为你可以通过在I/O 驱动器之间播撒(摘掉)这些均等定量的分区,来影响可用性和性能。

关于列表分区List:

当你需要明确地控制如何将行映射到分区时,就使用列表分区方法。可以在每个分区的描述中为该分区列指定一列离散值,这不同于范围分区,在那里一个范 围与一个分区相关,这也不同于散列分区,在那里用户不能控制如何将行映射到分区。列表分区方法是特意为遵从离散值的模块化数据划分而设计的。范围分区或散 列分区不那么容易做到这一点。进一步说列表分区可以非常自然地将无序的和不相关的数据集进行分组和组织到一起。

与范围分区和散列分区所不同,列表分区不支持多列分区。如果要将表按列分区,那么分区键就只能由表的一个单独的列组成,然而可以用范围分区或散列分区方法进行分区的所有的列,都可以用列表分区方法进行分区。

关于组合范围-散列分区:

范围和散列技术的组合,首先对表进行范围分区,然后用散列技术对每个范围分区再次分区。给定的范围分区的所有子分区加在一起表示数据的逻辑子集。

关于组合范围-列表分区:

范围和列表技术的组合,首先对表进行范围分区,然后用列表技术对每个范围分区再次分区。与组合范围-散列分区不同的是,每个子分区的所有内容表示数据的逻辑子集,由适当的范围和列表分区设置来描述。

创建或更改分区表时可以指定行移动子句,即ENABLE ROW MOVEMENT 或者DISABLE ROW MOVEMENT ,当其键被更改时,该子句启用或停用将行迁移到一个新的分区。默认值为DISABLE ROW MOVEMENT。本产品(项目)使用ENABLE ROW MOVEMENT子句。


分区技术能够提高数据库的可管理性:

使用分区技术,维护操作可集中于表的特定部分。例如,数据库管理员可以只对表的一部分做备份,而不必对整个表做备份。对整个数据库对象的维护操作,可以在每个分区的基础上进行,从而将维护工作分解成更容易管理的小块。

分区技术提高可管理性的一个典型用法是支持数据仓库中的‘滚动视窗’加载进程。假设数据库管理员每周向表中加载新数据。该表可以是范围分区,以便每 个分区包含一周的数据。加载进程只是简单地添加新的分区。添加一个新分区的操作比修改整个表效率高很多,因为数据库管理员不需要修改任何其他分区。从分区 后的表中去除数据也是一样。你只要用一个很简便快捷的数据字典操作删掉一个分区,而不必发出使用大量资源和调动所有要删除的数据的 ‘DELETE’ 命令。

分区技术能够提高数据库的性能:

由于减少了所检查或操作的数据数量,同时允许并行执行,Oracle9i 的分区功能提供了性能上的优势。这些性能包括:

l 分区修整:分区修整是用分区技术提高性能的最简单最有价值的手段。分区修整常常能够将查询性能提高几个数量级。例如,假定应用程序中有包含定单历史记录的 定单表,该表用周进行了分区。查询一周的定单只需访问该定单表的一个分区。如果该定单表包含两年的历史记录,这个查询只需要访问一个而不是一百零四个分 区。该查询的执行速度因为分区修整而有可能快一百倍。分区修整能与所有其他 Oracle 性能特性协作。Oracle 公司将把分区修整技术与索引技术、连结技术和并行访问方法一起联合使用。

l 分区智能联接:分区功能可以通过称为分区智能联接的技术提高多表联接的性能。当两个表要联接在一起,而且每个表都用联接关键字来分区时,就可以使用分区智 能联接。分区智能联接将大型联接分解成较小的发生在各个分区间的联接,从而用较少的时间完成全部联接。这就给串行和并行的执行都能带来显著的性能改善。

l 更新和删除的并行执行:分区功能能够无限地并行执行 UPDATE、DELETE 与 MERGE 语句。当访问分区或未分区的数据库对象时Oracle 将并行处理 SELECT 与 INSERT 语句。当不使用位图索引时,也可以对分区或未分区的数据库对象并行处理 UPDATE、DELETE 和 MERGE 语句。为了对有位图索引的对象并行处理那些操作,目标表必须先分区。这些 SQL 语句的并行执行可以大大提高性能,特别是提高 UPDATE 与 DELETE 或 MERGE 操作涉及大量数据时的性能。

分区技术提高可用性:

分区的数据库对象具有分区独立性。该分区独立性特点可能是高可用性战略的一个重要部分,例如,如果分区表的分区不能用,但该表的所有其他分区仍然保 持在线并可用。那么这个应用程序可以继续针对该分区表执行查询和事务处理,只要不是访问那个不可用的分区,数据库操作仍然能够成功运行。 数据库管理员可以指定各分区存放在不同的表空间里,从而让管理员独立于其它表分区针对每个分区进行备份与恢复操作。 还有,分区功能可以减少计划停机时间。性能由于分区功能得到了改善,使数据库管理员在相对较小的批处理窗口完成大型数据库对象的维护工作。

2009/03/11

Partition table 實作筆記 (INV的 MTL_MATERIAL_TRANSACTIONS)

摘自:網路

在 Oracle ERP 裡頭,我們發現 Inventory 的 table 有幾個很大,
以我們的環境,MTL_MATERIAL_TRANSACTIONS 大約是 14GB

因此,有沒有可能透過 partition 來檢驗這樣可以對 performance 有幫助?
如果有幫助,那這樣可以不用花費多餘的成本就能對 Database performance 作有效的控制獲改善。


在作之前,
先跟 Application Team 同事索取一段測試的 SQL statement
作為 performance 檢驗,
為了避免誤差,
我將這段 SQL 寫成 script ,放在 crontab 連續排程多次測試共 80多次,取得平均值後

整理如下:

1. explain plan 的 cost 有些微改變,但 index 的使用對象(MTL_MATERIAL_TRANSACTIONS_N8)仍不變,
這也顯示不影響原本的執行計畫

2.在 index 跟 table partition size 與分割前有滿大的空間不同
以 index MTL_MATERIAL_TRANSACTIONS_N8為例,
分割前空間為 1593MB,
經過分割跟 compress 後,各 partition 空間總和為原先的一半
1 select owner,segment_name,segment_type,extents ,bytes/1024/1024 "MB"from dba_segments
2* where segment_name like 'MTL_MATERIAL_TRANSACTIONS_N8'
SQL> /
e
OWNER SEGMENT_NAME SEGMENT_TYPE EXTENTS MB
------ -------------------------------------- ------------------ ---------- ----------
INV MTL_MATERIAL_TRANSACTIONS_N8 INDEX 1593 1593
GOBO MTL_MATERIAL_TRANSACTIONS_N8 INDEX PARTITION 33 330
GOBO MTL_MATERIAL_TRANSACTIONS_N8 INDEX PARTITION 18 180
GOBO MTL_MATERIAL_TRANSACTIONS_N8 INDEX PARTITION 21 210
GOBO MTL_MATERIAL_TRANSACTIONS_N8 INDEX PARTITION 8 80
GOBO MTL_MATERIAL_TRANSACTIONS_N8 INDEX PARTITION 1 10



3.經過三天定時排程後,將執行時間統計如下表,經過 partition 後,
執行時間約可增進 15~20%的執行效能

select partition "partition", queryrange1, queryrange2,round(avg(Run)/60,2) "Avg Mins" , count(1) "Testing Counts"
from
(select partition, queryrange1, queryrange2,60*to_number(substr(runtime,4,2)) + to_number(substr(runtime,7,2))+ to_number(substr(runtime,9,3)) Run
from inv_parti_perf_chk ) group by partition, queryrange1, queryrange2

partition QUERYRANGE1 QUERYRANGE2 Avg Mins Testing Counts
---------- -------------- -------------- ---------- --------------
n 200701 200706 8.65 5
n 200704 200705 1.99 1
n 200801 200804 4.74 9
y 200701 200706 8.74 4
y 200801 200804 4.13 7




## 建立 partition 的語法
我是把 partition 建立在另外一個 schema
如果真的要在正式環境的話,
那有個方式可以透過 rename table 的方式,
再重新建立 partition table
CREATE TABLE MY.MTL_MATERIAL_TRANSACTIONS
PARTITION BY RANGE (TRANSACTION_DATE)
(
PARTITION TRANSACTION_2005
VALUES LESS THAN ( TO_DATE('01-jan-2006','dd-mon-yyyy')) TABLESPACE GU_PARTITION_TS,
PARTITION TRANSACTION_2006
VALUES LESS THAN ( TO_DATE('01-jan-2007','dd-mon-yyyy')) TABLESPACE GU_PARTITION_TS,
PARTITION TRANSACTION_2007
VALUES LESS THAN ( TO_DATE('01-jan-2008','dd-mon-yyyy')) TABLESPACE GU_PARTITION_TS,
PARTITION TRANSACTION_2008
VALUES LESS THAN ( TO_DATE('01-jan-2009','dd-mon-yyyy')) TABLESPACE GU_PARTITION_TS,
PARTITION TRANSACTION_new
VALUES LESS THAN (MAXVALUE) TABLESPACE GU_PARTITION_TS )
as select * from inv.MTL_MATERIAL_TRANSACTIONS where 1=2;



## 建立 local index 的一例
在 global index 與 local index的選擇上,
因為 global index 還得另外 create index partition
那 local index 剛好有 key 值可以套用在 table partition
所以,我試著用 local index 並 加上 compress 參數

CREATE INDEX GOBO.MTL_MATERIAL_TRANSACTIONS_N8 ON GOBO.MTL_MATERIAL_TRANSACTIONS
(TRANSACTION_SOURCE_TYPE_ID, ORGANIZATION_ID, TRANSACTION_DATE, TRANSACTION_SOURCE_NAME)
NOLOGGING
NOLOGGING local compress;


## Gather Statistics
建立好了 partition table /index 記得跑一次 gather statistics
exec fnd_stats.gather_table_stats('MY','MTL_MATERIAL_TRANSACTIONS',granularity=>'ALL');

2009/03/06

历史数据归档(转)


在实际业务中,累计5年的历史业务数据可能比较大,比如可能超过1T的数据,这时可能就会影响业务处理
OLTP的运行效率,一般是将5年以上的数据归档的其他地方,同时从当前业务系统中删除。

有各位哥们对这个过程比较熟悉,ORACLE ERP时什么策略呢? 请高手指点。
DBX archiver的功能就是把历史数据放在另一个数据库中,如果在prod中的查询涉及到历史数据,就会到历史库中取数据,实现对客户的透明化,而数据是在两个独立的数据库中存放

类似的ORACLE数据归档的方案应该有不少,但说实话没有一家特别优秀的,因为ORACLE EBS涉及到的业务表太多,数据之间千丝万缕,不是简单的把某些schema的表里的数据移走了事

archive的原理说起来简单,具体实现起来哪些数据走,哪些数据留,那些是事务,哪些不算,没几个人会深入下去搞懂它们。oracle本身提供了 archive的接口,也实现了全部的业务逻辑,但它自己也知道这块做的很烂,所以它从来不愿意公开,更没有全面的推广,只是告诉用户有这么一个接口存在 而已。想自己利用ORACLE的接口,几乎就是一个字:死。。。。

所以才有了大大小小第三方公司的各种解决方案,Outerbay应该算其中不错的一家吧

我曾经为某家大公司,专门负责做个data archive的归档项目,研究它的archive规则,天天和一群印度人做这个,头都太大了。我从进那个项目开始做这个,一直到我走,还没有结束UAT 状态,没办法,数据实在太重要了,有这个需求的肯定都是大公司,数据就是它的命,要它把自己的命都移走,不谨慎那是不可能。。。。

outerbay对EBS的方案也和EMC的类似,把要归档的那些历史数据,整体移到另一个数据库里去,原数据库里数据少了,查询起来当然快

以AP为例,
分别建2类职责:
1个是普通AP查询,专门查近期的数据,比如2000年以后的数据,速度很快
1个是所有AP查询,数据来自一个union的view,速度肯定快不了,这种需求不如1多

发票归档不?没付款的发票归档不?N年前的发票N年后付款归档不?AR的,GL的,PO的,OM的,CE的,,,,,头都大了,最后我把文档,资 料,test case,test document,统统归档后,bye-bye了。。。不是人做的事情,谁做谁要吐。。。。。。。。。
SAP用户R/3文档归档解决方案

业务问题描述:对于使用SAP系统的客户来说,归档SAP系统的数据和对象已经变得越来越重要。 SAP用户通常是在系统越来越不行的时候才想到归档数据和对象的需要,SAP系统通常会变得越来越慢和用户响应时间越来越长,SAP用户也需要能快速访问SAP相关的文档。
客户需求表现:
- 你现在的SAP系统的数据库有多大?
- 每个月数据库的增长有多快?
- 你有发现用户响应时间或SAP系统的性能有下降吗?
- 你希望能通过SAP图形界面来归档和查看打印列表、发票、凭证、图像等吗?
- 你的用户是否希望将一些非SAP的对象,例如Word文档、Excel表格,电子 邮
- 件或视频片断和SAP的交易进行关联,并且能通过SAP系统来进行查看?

解决方案描述: IBM的 Content Manager CommonStore 解决方案已经通过了SAP的Archivelink接口的认证。CommonStore能运行在UNIX, AIX, NT 和 AS/400 平台上,同时也提供了方法来归档不活动的数据库数据,打印列表,发票,影像和另外的和SAP交易相关的文档。SAP用户能直接通过SAP的图形界面来访问 这些文档,并且能查询活动和不活动的数据库数据。客户也能增加另外的IBM Content Manager 应用,例如如果他们需要归档SAP系统以外的内容,可以使用CM或CM Ondemand。
- 带来的好处:
1.开始对SAP系统进行归档,减轻SAP生产系统的压力。
2.通过SAP图形界面归档和提取相关的文档。
3.用户能以浏览器的方式访问SAP系统信息。
- 典型应用:
1.使用SAP R3系统的用户。
- 典型用户:
1.海尔电器
2.长虹电器
案例介绍
CommonStore for SAP R/3在四川长虹的实施案例
系统需求及应用背景
四川长虹电子集团公司是我国大型国有独资公司,始建于1958年,目前拥有多个事业部,包括南通长虹、吉林长虹等多家控股、参股公司,现有员工3万多人, 同时,也拥有覆盖全国各地的一万多个营销服务网点,具有强大的营销实力,产品畅销美洲、澳洲、东南亚、中亚等国家和地区,在海外享有盛誉,为中国家电行业 第一品牌。
长虹公司的SAP R/3系统为4.5b中文版、从2000年9月开始上线,数据库DB2 V5.2.使用了MM、SD、FI、SM四个模块。从系统投入运行以来,在线数据库急剧膨胀,系统数据库是以每周4G的速度增长,数据库2001年5月容 量已经达到110GB,磁盘系统仅有22GB空余空间可以使用。磁盘空间不足的问题非常明显,严重影响了数据库的性能,并增加了R/3用户的等待时间,降 低了R/3系统的效率。同时增加了系统管理的复杂程度,备份时间的大大增加。另外购买高端磁盘系统的需求递增。
解决方案
长虹公司对于上述问题所采取的解决方案为:
- IBM CommonStore for SAP R/3 +TSM+3575磁带库
- 使用IBM CommonStore for SAP R/3 通过TSM将R/3数据库中的数据归档到3575磁带库中的磁带。
这个方案充分利用已有的软件和硬件资源:
- 软件: Tivoli Storage Management。
- 硬件: 3575 磁带库、RS/6000 S7a服务器。
- 新增软件: IBM CommonStore for SAP
实施后的效果
系统实施后的归档数据范围从2001年7月到2001年12月,业务数据量达35G,归档后腾出数据28.7G。总结来说有以下几点:
- 系统实施完成后,数据库的大小明显减少了,高速的数据增长得到有效控制,SAP R/3系统的运行效率提高了。
- 已经购买的备份系统与新系统无缝集成,数据备份与归档更趋完善。
- 已有硬件和软件投资得到保护。

http://www-01.ibm.com/software/cn/data/solution/db2_content_solution02.html

2008/09/10

Note:390864.1:How to check which Techstack patchsets have been applied

Subject: How to check which Techstack patchsets have been applied
Doc ID: Note:390864.1 Type: HOWTO
Last Revision Date: 24-JUN-2008 Status: PUBLISHED

In this Document
Goal
Solution
References

Applies to:
Application Install - Version: 11.5.10
Information in this document applies to any platform.
Goal
How to check which Techstack patchsets have been applied
Solution

For Single Tier Release 11i :



SET head off Lines 120 pages 100
col n_patch format A65
col bug_number format A10
col patch_name format A10
spool atg_pf_ptch_level.txt
select ' atg_pf ' FROM dual;
/

select bug_number, decode(bug_number,
'3438354', '11i.ATG_PF.H'
,'4017300' ,'11i.ATG_PF.H.RUP1'
,'4125550' ,'11i.ATG_PF.H.RUP2'
,'4334965' ,'11i.ATG_PF.H RUP3'
,'4676589' ,'11i.ATG_PF.H RUP4'
,'5382500' ,'11i.ATG_PF.H RUP5 HELP'
,'5473858' ,'11i.ATG_PF.H.5'
,'5674941' ,'11i.ATG_PF.H RUP5 SSO Integrat'
,'5903765' ,'11i.ATG_PF.H RUP6'
,'6117031' ,'11i.ATG_PF.H RUP6 SSO 10g Integration'
,'6330890' ,'11i.ATG_PF.H RUP6 HELP'
) n_patch, last_update_date
FROM ad_bugs
WHERE bug_number
IN ( '3438354', '4017300', '4125550', '4334965', '4676589', '5382500', '5473858', '5674941', '5903765', '6117031', '6330890' );



For Multi Tier Release 11i :


set serveroutput on size 100000
DECLARE
TYPE p_patch_array_type is varray(100) of varchar2(10);
TYPE a_abstract_array_type is varray(100) of varchar2(60);
p_patchlist p_patch_array_type;
a_abstract a_abstract_array_type;
p_appltop_name VARCHAR2(50);
p_patch_status VARCHAR2(15);
p_appl_top_id NUMBER;

CURSOR alist_cursor IS
SELECT appl_top_id, name
FROM ad_appl_tops;

procedure println(msg in varchar2)
IS
BEGIN
dbms_output.put_line(msg);
END;

BEGIN
open alist_cursor;

p_patchlist := p_patch_array_type( '3438354'
,'4017300'
,'4125550'
,'4334965'
,'4676589'
,'5382500'
,'5473858'
,'5674941'
,'5903765'
,'6117031'
,'6330890'
);
a_abstract := a_abstract_array_type( '11i.ATG_PF.H'
,'11i.ATG_PF.H.RUP1'
,'11i.ATG_PF.H.RUP2'
,'11i.ATG_PF.H RUP3'
,'11i.ATG_PF.H RUP4'
,'11i.ATG_PF.H RUP5 HELP'
,'11i.ATG_PF.H.5'
,'11i.ATG_PF.H RUP5 SSO Integrat'
,'11i.ATG_PF.H RUP6'
,'11i.ATG_PF.H RUP6 SSO 10g Integration'
,'11i.ATG_PF.H RUP6 HELP'
);


LOOP
FETCH alist_cursor INTO p_appl_top_id, p_appltop_name;
EXIT WHEN alist_cursor%NOTFOUND;
IF p_appltop_name NOT IN ('GLOBAL','*PRESEEDED*')
THEN
println(p_appltop_name || ':');
for i in 1..p_patchlist.count
LOOP
p_patch_status := ad_patch.is_patch_applied('11i', p_appl_top_id, p_patchlist(i));
println('..Patch ' || a_abstract(i)
||' '||p_patchlist(i)||' was '||
p_patch_status);
END LOOP;
END IF;
println('.');
END LOOP;
close alist_cursor;
END;
/

For Single Tier Release 12 :



SET head off Lines 120 pages 100
col n_patch format A65
col bug_number format A10
col patch_name format A10
spool atg_pf_ptch_level.txt
select ' atg_pf ' FROM dual;
/

select bug_number, decode(bug_number,
'6272680', 'R12.ATG_PF.A.delta.4'
,'6077669', 'R12.ATG_PF.A.delta.3'
,'5917344', 'R12.ATG_PF.A.delta.2'
) n_patch, last_update_date
FROM ad_bugs
WHERE bug_number
IN ('6272680', '6077669', '5917344');


For Multi Tier Release R12 :

set serveroutput on size 100000
DECLARE
TYPE p_patch_array_type is varray(100) of varchar2(10);
TYPE a_abstract_array_type is varray(100) of varchar2(60);
p_patchlist p_patch_array_type;
a_abstract a_abstract_array_type;
p_appltop_name VARCHAR2(50);
p_patch_status VARCHAR2(15);
p_appl_top_id NUMBER;

CURSOR alist_cursor IS
SELECT appl_top_id, name
FROM ad_appl_tops;

procedure println(msg in varchar2)
IS
BEGIN
dbms_output.put_line(msg);
END;

BEGIN
open alist_cursor;

p_patchlist := p_patch_array_type( '6272680'
,'6077669'
,'5917344'
);
a_abstract := a_abstract_array_type( 'R12.ATG_PF.A.delta.4'
,'R12.ATG_PF.A.delta.3'
,'R12.ATG_PF.A.delta.2'
);


LOOP
FETCH alist_cursor INTO p_appl_top_id, p_appltop_name;
EXIT WHEN alist_cursor%NOTFOUND;
IF p_appltop_name NOT IN ('GLOBAL','*PRESEEDED*')
THEN
println(p_appltop_name || ':');
for i in 1..p_patchlist.count
LOOP
p_patch_status := ad_patch.is_patch_applied('11i', p_appl_top_id, p_patchlist(i));
println('..Patch ' || a_abstract(i)
||' '||p_patchlist(i)||' was '||
p_patch_status);
END LOOP;
END IF;
println('.');
END LOOP;
close alist_cursor;
END;
/