2008年6月30日 星期一

Data movement on Materialized Query Table using DB2 UDB8.2

/* 建立測試資料 */

CREATE TABLE DATAMOVE_TEST
(
  X INTEGER,
  Y INTEGER,
  XY INTEGER
) IN USERSPACE1;

/* 新增測試資料一萬筆 */

INSERT INTO DATAMOVE_TEST
WITH N(X) AS (
SELECT 1 X
FROM  SYSIBM.SYSDUMMY1
UNION  ALL
SELECT N.X + 1
FROM  N
WHERE N.X + 1 <= 100
)
SELECT N.X , N1.X , N.X * N1.X
FROM  N,N N1;

/* 建立MQT放X>50的資料 */

CREATE TABLE MQT_GREATERTHAN5000 AS
(
  SELECT X,Y,XY
  FROM DATAMOVE_TEST
  WHERE X > 50
) DATA INITIALLY DEFERRED REFRESH DEFERRED IN USERSPACE1;

/* 將資料轉入MQT */

REFRESH TABLE MQT_GREATERTHAN5000;

/* 建立MQT放X<=50的資料 */

CREATE TABLE MQT_NOGREATERTHAN5000 AS
(
  SELECT X,Y,XY
  FROM DATAMOVE_TEST
  WHERE X <= 50
) DATA INITIALLY DEFERRED REFRESH DEFERRED IN USERSPACE1;

/* 將資料轉入MQT */

REFRESH TABLE MQT_NOGREATERTHAN5000;

/* 建一個MQT: MQT_TOTAL */

CREATE TABLE MQT_TOTAL AS
(
  SELECT 0 X,0 Y,0 XY FROM SYSIBM.SYSDUMMY1
) DATA INITIALLY DEFERRED REFRESH DEFERRED IN USERSPACE1;

※若於此時對MQT_TOTAL做REFRESH,則LOAD完,SET INTEGRITY後,SELECT MQT_TOTAL會有10001筆資料

/* 於CLP下對MQT_GREATERTHAN5000及MQT_NOGREATERTHAN5000做EXPORT */

C:\>db2 export to 1.del of del select * from mqt_greaterthan5000
C:\>db2 export to 2.del of del select * from mqt_nogreaterthan5000

/* 將.del資料load進MQT_TOTAL */

C:\>db2 load from 1.del of del insert into mqt_total
C:\>db2 load from 2.del of del insert into mqt_total

/* SELECT MQT_TOTAL */

C:\>db2 select * from mqt_total
X  Y  XY
---- ---- ----
SQL0668 由於原因碼"1",不容許表格"ORION.MQT_TOTAL"上的作業。
SQLSTATE=57016

/* SET INTEGRITY */

C:\>db2 set integrity for mqt_total all immediate unchecked
DB20000I SQL 命令已順利完成。

C:\>db2 select count(*) from mqt_total

---------
10000

Materialized Query Table in DB2 UDB8.2

/* 建立測試table */

CREATE TABLE TEST
(
  PRDID CHAR(1),
  TRADEDT CHAR(8),
  PRICE DECIMAL(19,2)
) IN USERSPACE1;

CREATE TABLE TEST1
(
PRDID CHAR(1) NOT NULL PRIMARY KEY,
PRDNAME VARCHAR(32)
) IN USERSPACE1;

CREATE TABLE TEST3
(
TRADEMON CHAR(6),
TOTAL DECIMAL(19,2)
) IN USERSPACE1;

/* 新增測試資料 */

INSERT INTO TEST VALUES ('1','20080301',33.62);
INSERT INTO TEST VALUES ('1','20080403',100.05);
INSERT INTO TEST VALUES ('2','20080205',50.93);
INSERT INTO TEST VALUES ('1','20080409',120.73);
INSERT INTO TEST VALUES ('2','20080301',99.12);
INSERT INTO TEST VALUES ('1','20080501',162.53);
INSERT INTO TEST VALUES ('1','20080530',195.99);
INSERT INTO TEST VALUES ('2','20080502',88.76);
INSERT INTO TEST VALUES ('2','20080530',90.23);

INSERT INTO TEST1 VALUES ('1','PRODUCT A');
INSERT INTO TEST1 VALUES ('2','PRODUCT B');

/* 建立Materialized Query Table(MQT) */

CREATE TABLE MQT_TEST AS
(
 SELECT TEST.PRDID,PRDNAME,AVG(PRICE) AVG_PRICE
 FROM TEST
 LEFT JOIN TEST1 ON TEST1.PRDID = TEST.PRDID
 GROUP BY TEST.PRDID,PRDNAME
) DATA INITIALLY DEFERRED REFRESH DEFERRED IN USERSPACE1;

/* 將資料轉入MQT */

REFRESH TABLE MQT_TEST;

/* View可建立在MQT之上做查詢,反之則不然 */

CREATE VIEW V_MQT_TEST
AS
SELECT * FROM MQT_TEST;

※這樣做並沒有什麼好處,因MQT重建時,View會被標記為無效(SQL0575N)。View 必須被重建

/* 再測試Stored procedure包含MQT的狀況 */
/* 建立一個MQT:MQT_TEST2 */

CREATE TABLE MQT_TEST2 AS (
SELECT TEST.PRDID,PRDNAME,TRADEDT,SUM(PRICE) TOTAL
FROM TEST
LEFT JOIN TEST1 ON TEST1.PRDID = TEST.PRDID
GROUP BY TEST.PRDID,PRDNAME,TRADEDT
) DATA INITIALLY DEFERRED REFRESH DEFERRED IN USERSPACE1;

REFRESH TABLE MQT_TEST2;

/* ex: 建立procedure: sp_test 內容如下 */

DROP PROCEDURE SP_TEST
GO
CREATE PROCEDURE SP_TEST
SPECIFIC SP_TEST
LANGUAGE SQL
BEGIN

    DECLARE SQLCODE INTEGER DEFAULT 0;
    DECLARE retcode INTEGER DEFAULT 0;
    declare szsql VARCHAR(1024);
    DECLARE nCOL1 INTEGER;

    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION,
                     SQLWARNING,
                     NOT FOUND
    SET RETCODE = SQLCODE;

    SET szsql = 'ALTER TABLE TEST3 ACTIVATE NOT LOGGED INITIALLY WITH EMPTY TABLE';
    EXECUTE IMMEDIATE szsql;

    INSERT INTO TEST3
    SELECT SUBSTR(TRADEDT,1,6),SUM(TOTAL)
    FROM  MQT_TEST2
    GROUP  BY SUBSTR(TRADEDT,1,6);

    RETURN RETCODE;
END

/* MQT_TEST2正常有資料下Call procedure */

C:\>db2 call sp_test
傳回狀態 = 0

C:\>db2 select * from TEST3

/* 結果如下 */

200802 50.93
200803 132.74
200804 220.78
200805 537.51

/* DROP MQT_TEST2 then Call procedure */

C:\>db2 call sp_test
傳回狀態 = -727

/* CREATE MQT_TEST2 未 refresh then Call procedure */

C:\>db2 call sp_test
傳回狀態 = -668

※ MQT正確被Refresh後,procedure 可正常被執行,不須重建

2008年6月27日 星期五

SQL30081 Error when connect using DB2 UDB8.2

/* Connect DB時傳回以下錯誤 */

C:\>connect to ORIONDB user db2admin using db2admin

SQL30081N 偵測到通信錯誤。 已使用的通訊協定: "TCP/IP"。 已使用的通信 API:
"SOCKETS"。 偵測到錯誤的位置: "10.7.72.62"。
偵測錯誤的通信功能:"connect"。 通訊協定特定的錯誤碼: "10060"、"*"、"*"。
SQLSTATE=08001

/* 解決方法 */
/* 1) Check database server 的環境變數 DB2COMM是否設為TCPIP */

C:\>db2set -all
[e] DB2PATH=C:\Program Files\IBM\SQLLIB
[i] DB2ACCOUNTNAME=IBM-63AB93AA2BF\orion
[i] DB2INSTOWNER=IBM-63AB93AA2BF
[i] DB2PORTRANGE=60000:60003
[i] DB2INSTPROF=C:\PROGRAM FILES\IBM\SQLLIB
[i] DB2COMM=TCPIP
[g] DB2_EXTSECURITY=YES
[g] DB2SYSTEM=IBM-63AB93AA2BF
[g] DB2PATH=C:\Program Files\IBM\SQLLIB
[g] DB2INSTDEF=DB2
[g] DB2ADMINSERVER=DB2DAS00

/* 使用db2set設定 */

C:\>db2set DB2COMM = TCPIP

/* 2) 檢查 database server的service name */

C:\>DB2 GET DBM CFG

資料庫管理程式配置

   節點類型 = 具有本地及遠端用戶端的 Enterprise Server Edition

 資料庫管理程式配置版次               = 0x0a00

 開啟檔案的最大總數         (MAXTOTFILOP) = 16000
 CPU 速度 (千分之一秒/命令)       (CPUSPEED) = 4.000000e-005
 通信頻寬 (MB/秒)       (COMM_BANDWIDTH) = 1.250000e+000
                             .
                             .
                             .
                             .
 「TCP/IP服務程式」名稱        (SVCENAME) = db2c_DB2


/* 
  找(SVCENAME)設定值是否正確,不正確則重新設定
  若service name應該為orion_DB2,則使用update dbm cfg 修改
*/


C:\>update dbm cfg using svcename orion_DB2


/* 3) 檢查 etc\services的port number */

開啟C:\WINDOWS\system32\drivers\etc\services
確定以service name使用的port number存在且正確

orion_DB2 50000/tcp


/* 4) 檢查 firewall 設定*/

2008年6月26日 星期四

Index analyze and rebuild using Oracle10g

/* 建立測試table */

SQL>CREATE TABLE TBLBASE
  (
    X INTEGER,
    Y INTEGER,
    XY INTEGER
  );

/* 新增測試資料 */

SQL>insert into tblbase
  select x,y,x*y
  from (select level x from dual connect by level = 100),
  (select level y from dual connect by level <= 100);

/* 建index */

SQL>create index TBLBASE_IDX on TBLBASE(X,Y) tablespace idx;

/* 由系統tables檢示一下所建立的index */

SQL>select index_name,index_type,status from all_indexes
  where table_name = 'TBLBASE';

INDEX_NAME   INDEX_TYPE   STATUS
------------- -------------- --------------------------
TBLBASE_IDX   NORMAL     VALID

/* 由系統tables檢示一下所建立的index包含欄位 */

SQL>select INDEX_OWNER,COLUMN_NAME,COLUMN_POSITION
  from  ALL_IND_COLUMNS where INDEX_NAME = 'TBLBASE_IDX';

INDEX_OWNER  COLUMN_NAME  COLUMN_POSITION
------------- -------------- ---------------------------------
ORION     X        1
ORION     Y        2

/* 分析一下INDEX的結構 */


SQL>analyze index TBLBASE_IDX VALIDATE STRUCTURE;

已分析索引.

SQL>select height,blocks,lf_rows,lf_blks,br_rows,
   br_blks,btree_space,used_space
   from index_stats where name = 'TBLBASE_IDX';

HEIGHT BLOCKS LF_ROWS LF_BLKS BR_ROWS BR_BLKS BTREE_SPACE USED_SPACE
------ ------ -------- ------- ------- ------- ----------- -----------------
2    80   27821  68    67    1     552032     483450


/* 對TBLBASE進行DML後再分析 */

SQL> analyze index TBLBASE_IDX VALIDATE STRUCTURE;

已分析索引.

SQL>select height,blocks,lf_rows,lf_blks,br_rows,
   br_blks,btree_space,used_space
   from index_stats where name = 'TBLBASE_IDX';

HEIGHT BLOCKS LF_ROWS LF_BLKS BR_ROWS BR_BLKS BTREE_SPACE USED_SPACE
------ ------ ------- ------- ------- ------- ----------- ----------
2    80   27889  69    68    1     560032    484649

/* 對INDEX做REBUILD */

SQL> ALTER INDEX TBLBASE_IDX REBUILD;

已更改索引.

/* 對TBLBASE進行分析 */

SQL> analyze index TBLBASE_IDX VALIDATE STRUCTURE;

已分析索引.

SQL>select height,blocks,lf_rows,lf_blks,br_rows,
   br_blks,btree_space,used_space
   from index_stats where name = 'TBLBASE_IDX';

HEIGHT BLOCKS LF_ROWS LF_BLKS BR_ROWS BR_BLKS BTREE_SPACE USED_SPACE
------ ------ ------- ------- ------- ------- ----------- -------------
2    72   25106  61    60    1     496032    437230

2008年6月25日 星期三

Unable to update Load History File Entry problem using DB2 UDB8.2

/* db2diag.log裡出現下列錯誤訊息 */


2008-06-26-02.30.26.503000+480 I651705345H542  LEVEL: Error
PID : 2588             TID : 852      PROC : db2syscs.exe
INSTANCE: DB2          NODE : 000     DB : ORIONDB
APPHDL : 0-224          APPID: *LOCAL.DB2.080625183005
FUNCTION: DB2 UDB, database utilities, sqluCommitLoadEntryInHistoryFile, probe:20
MESSAGE : LOADID: 852.2008-06-26-02.30.06.051000.0 (2;804) Unable to update Load History File Entry rc =
DATA #1 : Hexdump, 4 bytes
0x490B48F0 : 8FF7 FFFF ....

2008-06-26-02.30.26.503000+480  I651705889H458  LEVEL: Error
PID : 2588               TID : 852      PROC : db2syscs.exe
INSTANCE: DB2            NODE : 000     DB : ORIONDB
APPHDL : 0-224            APPID: *LOCAL.DB2.080625183005
FUNCTION: DB2 UDB, database utilities, sqluCommitLoadEntryInHistoryFile, probe:21
MESSAGE : LOADID: 852.2008-06-26-02.30.06.051000.0 (2;804) Load History File Entry left in non-committed state.

/*在CLP下 LIST HISTORY 檢示過去LOAD歷程, 並出現下列錯誤訊息 */

C:\>db2 list history load since 20080625 for ORIONDB
sql2161n 無法修正損壞的回復歷程檔,指定動作失敗

/*處理方式 */

0) db2stop
1) 從DB存放的實體路徑下,找DB2RHIST.ASC
  ex:
    C:\DB2\NODE0000\SQL00002\
2) 將DB2RHIST.ASC及DB2RHIST.BAK全部rename
3) db2start

2008年6月23日 星期一

SQL Explain Tool on general table with index using DB2 UDB8.2

/*建立table並給定key值*/

CREATE TABLE TABPLUS2
(
  X INTEGER NOT NULL,
  Y INTEGER NOT NULL,
  XY INTEGER,
  DES VARCHAR(32),
  PRIMARY KEY (X,Y)
) IN USERSPACE1

INSERT INTO TABPLUS2
WITH N(X) AS (
SELECT 1 X
FROM  SYSIBM.SYSDUMMY1
UNION  ALL
SELECT N.X + 1
FROM  N
WHERE N.X + 1 <= 100
)
SELECT N.X , N1.X , N.X * N1.X,
    RTRIM(CHAR(N.X)) || ' x ' ||
    RTRIM(CHAR(N1.X)) || ' = ' ||
    RTRIM(CHAR(N.X * N1.X))
FROM N,N N1;

/*檢示index*/


/*對table做reorgchk*/
DB2 REORGCHK UPDATE STATISTICS ON TABLE ORION.TABPLUS2
/*結果如下圖*/


db2expln -database CDIDB2 -g -statement "select x,sum(xy) from tabplus2 where x=20 and y=40 group by x" -o c:\plus2.log

/*結果如下*/

DB2 Universal Database Version 8.1, 5622-044 (c) Copyright IBM Corp. 1991, 2002
Licensed Material - Program Property of IBM
IBM DB2 Universal Database SQL Explain Tool
******************** DYNAMIC ***************************************
==================== STATEMENT ==========================================

Isolation Level      = Cursor Stability
Blocking          = Block Unambiguous Cursors
Query Optimization Class = 5

Partition Parallel     = No
Intra-Partition Parallel = No

SQL Path          = "SYSIBM", "SYSFUN", "SYSPROC", "ORION"

SQL Statement:

 select x, sum(xy)
 from tabplus2
 where x=20 and y=40
 group by x

Section Code Page = 1208

Estimated Cost = 28.780834
Estimated Cardinality = 1.000000

Access Table Name = ORION.TABPLUS2 ID = 2,187
| Index Scan: Name = SYSIBM.SQL080624120815130 ID = 1
| | Regular Index (Not Clustered)
| | Index Columns:
| | | 1: X (Ascending)
| | | 2: Y (Ascending)
| #Columns = 1
| Single Record
| Fully Qualified Unique Key
| #Key Columns = 2
| | Start Key: Inclusive Value
| | | | 1: 20
| | | | 2: 40
| | Stop Key: Inclusive Value
| | | | 1: 20
| | | | 2: 40
| Data Prefetch: None
| Index Prefetch: None
| Lock Intents
| | Table: Intent Share
| | Row : Next Key Share
Aggregation
| Group By
| Column Function(s)
Return Data to Application
| #Columns = 2
End of section

Optimizer Plan:

         RETURN
         (  1)
           |
         GRPBY
         (  2)
           |
         FETCH
         (  3)
         /   \
      IXSCAN   Table:
      (  3)   ORION
        |    TABPLUS2
      Index:
      SYSIBM
      SQL080624120815130

SQL Explain Tool on general table with no index using DB2 UDB8.2

/*建立一般的table,並且未建index*/

CREATE TABLE TABPLUS1
(
  X INTEGER NOT NULL,
  Y INTEGER NOT NULL,
  XY INTEGER,
  DES VARCHAR(32)
) IN USERSPACE1;

/*新增測試資料*/

INSERT INTO TABPLUS1
WITH N(X) AS (
SELECT 1 X
FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT N.X + 1
FROM N
WHERE N.X + 1 <= 100
)
SELECT N.X , N1.X , N.X * N1.X,
RTRIM(CHAR(N.X)) || ' x ' ||
RTRIM(CHAR(N1.X)) || ' = ' ||
RTRIM(CHAR(N.X * N1.X))
FROM N,N N1;

DB2 REORGCHK UPDATE STATISTICS ON TABLE ORION.TABPLUS1

/*結果如下圖*/


/*SQL Explain Tool*/

db2expln -database CDIDB2 -g -statement "select x,sum(xy) from tabplus1 where x=20 and y=40 group by x" -o c:\plus1.log

/*結果如下*/

DB2 Universal Database Version 8.1, 5622-044 (c) Copyright IBM Corp. 1991, 2002
Licensed Material - Program Property of IBM
IBM DB2 Universal Database SQL Explain Tool
******************** DYNAMIC ***************************************
==================== STATEMENT ==========================================

Isolation Level      = Cursor Stability
Blocking          = Block Unambiguous Cursors
Query Optimization Class = 5

Partition Parallel    = No
Intra-Partition Parallel = No

SQL Path          = "SYSIBM", "SYSFUN", "SYSPROC", "ORION"

SQL Statement:

 select x, sum(xy)
 from tabplus1
 where x=20 and y=40
 group by x

Section Code Page = 1208

Estimated Cost = 1213.568237
Estimated Cardinality = 1.000000

Access Table Name = ORION.TABPLUS1 ID = 2,191
| #Columns = 1
| Relation Scan
| | Prefetch: Eligible
| Lock Intents
| | Table: Intent Share
| | Row : Next Key Share
| Sargable Predicate(s)
| | #Predicates = 2
| | Predicate Aggregation
| | | Group By
| | | Column Function(s)
Aggregation Completion
| Group By
| Column Function(s)
Return Data to Application
| #Columns = 2
End of section

Optimizer Plan:
 RETURN
 (  1)
   |
 GRPBY
 (  2)
   |
 TBSCAN
 (  3)
   |
 Table:
 ORION
 TABPLUS1

SQL Explain Tool on MDC Table using DB2 UDB8.2

/*建立Multi-Dimensional Cluster table*/

CREATE TABLE TABPLUS
(
  X INTEGER NOT NULL,
  Y INTEGER NOT NULL,
  XY INTEGER,
  DES VARCHAR(32)
) ORGANIZE BY DIMENSIONS (X, Y)
NOT LOGGED INITIALLY IN USERSPACE1;

/*新增測試資料*/

INSERT INTO TABPLUS
WITH N(X) AS (
SELECT 1 X
FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT N.X + 1
FROM N
WHERE N.X + 1 <= 100
)
SELECT N.X , N1.X , N.X * N1.X,
RTRIM(CHAR(N.X)) || ' x ' ||
RTRIM(CHAR(N1.X)) || ' = ' ||
RTRIM(CHAR(N.X * N1.X))
FROM N,N N1;

/*REORGCHK TABPLUS*/

DB2 REORGCHK UPDATE STATISTICS ON TABLE ORION.TABPLUS


/*結果如下圖*/

/*REORGCHK TABPLUS*/




SELECT A.TABNAME,A.CARD * (SUM(B.AVGCOLLEN)+10)
FROM SYSCAT.TABLES A, SYSCAT.COLUMNS B
WHERE A.TABNAME = B.TABNAME
AND B.TABNAME ='TABPLUS'
GROUP BY A.TABNAME,A.CARD

/*執行結果*/

TABPLUS 410000


db2expln -database CDIDB2 -g -statement "select x,sum(xy) from tabplus where x=20 and y=40 group by x" -o c:\plus.log

/*結果如下:*/

DB2 Universal Database Version 8.1, 5622-044 (c) Copyright IBM Corp. 1991, 2002
Licensed Material - Program Property of IBM
IBM DB2 Universal Database SQL Explain Tool
******************** DYNAMIC ***************************************
==================== STATEMENT ==========================================
Isolation Level      = Cursor Stability
Blocking          = Block Unambiguous Cursors
Query Optimization Class = 5

Partition Parallel    = No
Intra-Partition Parallel = No

SQL Path          = "SYSIBM", "SYSFUN", "SYSPROC", "ORION"

SQL Statement:

 select x, sum(xy)
 from tabplus
 where x=20 and y=40
 group by x

Section Code Page = 1208

Estimated Cost = 77.462067
Estimated Cardinality = 1.000000

Access Table Name = ORION.TABPLUS ID = 2,190
| Index Scan: Name = SYSIBM.SQL080624120914310 ID = 1
| | Composite Block Index
| | Index Columns:
| | | 1: X (Ascending)
| | | 2: Y (Ascending)
| #Columns = 1
| Clustered by Dimension for Block Index Access
| #Key Columns = 2
| | Start Key: Inclusive Value
| | | | 1: 20
| | | | 2: 40
| | Stop Key: Inclusive Value
| | | | 1: 20
| | | | 2: 40
| Data Prefetch: None
| Index Prefetch: None
| Lock Intents
| | Table: Intent Share
| | Block: Intent Share
| | Row : Next Key Share
| Sargable Predicate(s)
| | Predicate Aggregation
| | | Group By
| | | Column Function(s)
Aggregation Completion
| Group By
| Column Function(s)
Return Data to Application
| #Columns = 2
End of section

Optimizer Plan:
         RETURN
         (  1)
           |
         GRPBY
         (  2)
           |
         FETCH
         ( 3)
        /    \
     IXSCAN    Table:
     (  3)    ORION
       |     TABPLUS
     Index:
     SYSIBM
     SQL080624120914310

※ drop MDC TABLE TABPLUS 前,只剩下12.8G. DROP 後剩下14.0G
結論是我覺得MDC Table佔空間,performance也沒有好到哪裡去. 用MQT是上選.

2008年6月20日 星期五

check uncommitted sessions using Oracle10g

建測試table

create table testlk
(
  col1 integer
);

新增測試資料

insert into testlb select level from dual connect by level <= 500;

Session 1)以user:Orion登入刪資料

SQL>connect orion/orion
SQL>delete from testlk where col1 = 8;
已刪除1個資料列.


Session 2)以user:pisces登入

SQL>connect pisces/pisces

Session 2)刪同一筆資料結果被block住

SQL>delete from testlk where col1 = 8;

Session 3)以user:taurus登入

SQL>connect taurus/taurus

Session 3)刪另一筆資料

SQL>delete from testlk where col1 = 9;
已刪除1個資料列.
SQL>commit;


Session 4)以sysdba登入檢查是否有session被block住

將以下程式存成.sql檔,ex:c:\uncommit.sql
(reference=> http://www.praetoriate.com/oracle_tips_find_locks.htm):


set pagesize 200
set linesize 200
column owner format a10
column object_name format a10
column username format a10
column object_type format a10
column osuser format a30
column machine format a30

spool c:\1.log

select c.owner,c.object_name,c.object_type,
b.sid,b.serial#,b.username,b.blocking_session,b.status,b.osuser,
b.machine
from v$locked_object a ,v$session b,
dba_objects c
where b.sid = a.session_id
and a.object_id = c.object_id
/
spool off

執行uncommit.sql

SQL>@c:\uncommit.sql

開啟 1.log內容如下

OWNER OBJECT_NAM OBJECT_TYP SID SERIAL# USERNAME BLOCKING_SESSION STATUS OSUSER MACHINE
----- ---------- ---------- ---------- ---------- ---------- ---------------- ---------------- ------------------------------ --------
ORION TESTLK    TABLE    156  256   PISCES   143     ACTIVE  IBM-63AB93AA2BF\orion  WORKGROUP\IBM-63AB93AA2BF
ORION TESTLK    TABLE    143  71    ORION        INACTIVE IBM-63AB93AA2BF\orion  WORKGROUP\IBM-63AB93AA2BF

另外,也可以使用DBA_BLOCKERS來查看誰block住別人
以pisces登入刪資料

SQL>delete from testlk where col1 = 95;
已刪除 1 個資料列.

再以taurus登入刪同一筆資料

SQL>delete from testlk where col1 = 95;

以sys登入查誰block住別人

SQL>select * from dba_blockers;
HOLDING_SESSION
---------------
150

SQL>select username,program from v$session where sid = 150;
USERNAME   PROGRAM
----------- -----------------
PISCES    sqlplus.exe

如DBA_BLOCKERS不存在,則需先執行%ORACLE_HOME%\rdbms\admin\Catblock.sql產生之

2008年6月18日 星期三

use index or not II using Oracle10g

/* 將先前的TESTIDX_IDX DROP */

SQL>DROP INDEX TESTIDX_IDX;

/* 以總合建一個INDEX */

SQL>CREATE INDEX TESTIDX_I ON TESTIDX(CATEGORY+X+Y);

/* 使用SQLPLUS並開啟TRACE */

SQL> set autotrace traceonly explain

/* 看總和為條件的查詢結果 */

SQL> select * from testidx where category+x+y=9;

執行計畫
----------------------------------------------------------
Plan hash value: 3683099191

----------------------------------------------------------------------------
| Id | Operation         | Name |Rows| Bytes |Cost(%CPU)|Time |
----------------------------------------------------------------------------
| 0 |SELECT STATEMENT      |     | 4 | 208  | 7 0)|00:00:01 |
| 1 |TABLE ACCESS BY INDEX ROWID|TESTIDX | 4 | 208 | 7 (0)|00:00:01 |
|* 2 |INDEX RANGE SCAN      |TESTIDX_I| 40|    | 1 (0)|00:00:01|
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
  2 - access("CATEGORY"+"X"+"Y"=9)
Note
-----
  - dynamic sampling used for this statement


/* 再看看各別為條件的查詢結果 */

SQL> select * from testidx where category=99 and x=99 and y=99;

執行計畫
----------------------------------------------------------
Plan hash value: 3565063929

----------------------------------------------------------------------
| Id |Operation     | Name  |Rows|Bytes|Cost(%CPU)| Time  |
----------------------------------------------------------------------
| 0 |SELECT STATEMENT  |     | 1 | 52 |  8 (0) | 00:00:01 |
|* 1 |TABLE ACCESS FULL | TESTIDX | 1 | 52 |  8 (0) | 00:00:01 |
----------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
 1 - filter("CATEGORY"=99 AND "X"=99 AND "Y"=99)
Note
-----
 - dynamic sampling used for this statement

SQL> set autotrace off

use index or not using Oracle10g

/*建立測試table*/

CREATE TABLE TESTIDX
(
CATEGORY INTEGER,
X INTEGER,
Y INTEGER,
TOTAL INTEGER
);

/*新增測試資料*/

INSERT INTO TESTIDX
SELECT X,X,Y,X*Y
FROM
(SELECT level x FROM DUAL CONNECT BY LEVEL <= 100),
(SELECT level y FROM DUAL CONNECT BY LEVEL <= 100);

/*建立index*/

SQL>CREATE INDEX TESTIDX_IDX ON TESTIDX(CATEGORY,X,Y);

/*使用Sql Explain Tool*/

SQL> set autotrace traceonly explain

/*按所鍵index來查詢*/

SQL> select * from testidx where category=99 and x=99 and y=99;

執行計畫
----------------------------------------------------------
Plan hash value: 3158742342

------------------------------------------------------------------------------
| Id | Operation        | Name    |Rows|Bytes|Cost(%CPU)|Time  |
------------------------------------------------------------------------------
| 0 |SELECT STATEMENT      |       | 1 | 52  |2 (0) | 00:00:01 |
| 1 |TABLE ACCESS BY INDEX ROWID|TESTIDX   | 1 | 52  |2 (0) | 00:00:01 |
|*2  |INDEX RANGE SCAN      |TESTIDX_IDX | 1 |   |1 (0) | 00:00:01 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
 2 - access("CATEGORY"=99 AND "X"=99 AND "Y"=99)

Note
-----
 - dynamic sampling used for this statement


/*測試使用部份index來查詢是否有用到index*/

SQL> select * from testidx where category = 10;

執行計畫
----------------------------------------------------------
Plan hash value: 3158742342

----------------------------------------------------------------------------------
| Id |Operation          | Name    |Rows|Bytes|Cost(%CPU)| Time |
----------------------------------------------------------------------------------
| 0|SELECT STATEMENT        |       |100| 5200 | 3 (0) | 00:00:01 |
| 1|TABLE ACCESS BY INDEX ROWID  |TESTIDX   |100| 5200 | 3 (0) | 00:00:01 |
|* 2|INDEX RANGE SCAN        |TESTIDX_IDX |100|   | 2 (0) | 00:00:01 |
---------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
 2 - access("CATEGORY"=10)
Note
-----
 - dynamic sampling used for this statement


/*測試使用部份index來查詢是否有用到index*/

SQL> select * from testidx where category = 10 and y = 5;

執行計畫
----------------------------------------------------------
Plan hash value: 3158742342

-----------------------------------------------------------------------------------
| Id |Operation           |Name     |Rows|Bytes|Cost(%CPU)|Time |
-----------------------------------------------------------------------------------
| 0 |SELECT STATEMENT       |        | 1 | 52  | 3 (0)  |00:00:01 |
| 1 |TABLE ACCESS BY INDEX ROWID |TESTIDX    | 1 | 52  | 3 (0)  |00:00:01 |
|* 2 |INDEX RANGE SCAN       | TESTIDX_IDX  | 1 |   | 2 (0)  |00:00:01 |
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
 2 - access("CATEGORY"=10 AND "Y"=5)
   filter("Y"=5)
Note
-----
 - dynamic sampling used for this statement


/*測試使用總合來查詢是否有用到index*/

SQL> select * from testidx where category+x+y=9;

執行計畫
----------------------------------------------------------
Plan hash value: 3565063929

------------------------------------------------------------------------------
| Id |Operation     | Name  | Rows | Bytes |Cost(%CPU)|Time    |
------------------------------------------------------------------------------
| 0 |SELECT STATEMENT  |     |  4  | 208  | 9 (12) | 00:00:01 |
|* 1 |TABLE ACCESS FULL | TESTIDX |  4  | 208  | 9 (12) | 00:00:01 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("CATEGORY"+"X"+"Y"=9)

Note
-----
- dynamic sampling used for this statement

SQL> set autotrace off

2008年6月16日 星期一

Find the gap using DB2 UDB8.2

/* FIND THE GAP BETWEEN ALL THESE RECORD */
~ 參考ORACLE OLAP FUNCTION lag(dt) over (order by dt) 的做法. FROM AskTom ~

建立測試table並新增測試資料

create table t ( a int, b date, c date );
insert into t values(1, DATE('2007-01-01'), date('2007-01-15'));
insert into t values(2, DATE('2007-01-03'), DATE('2007-01-10'));
insert into t values(3, DATE('2007-01-12'), DATE('2007-01-25'));
insert into t values(4, DATE('2007-01-20'), DATE('2007-02-01'));
insert into t values(5, DATE('2007-02-05'), DATE('2007-02-10'));
insert into t values(6, DATE('2007-02-05'), DATE('2007-02-28'));
insert into t values(7, DATE('2007-02-10'), DATE('2007-02-15'));
insert into t values(8, DATE('2007-02-18'), DATE('2007-02-23'));
insert into t values(9, DATE('2007-02-22'), DATE('2007-03-16'));

運用Olap Function及遞迴Sql Query

WITH   N(COL,L) AS (
SELECT  ROW_NUMBER() OVER() COL,L
FROM   (SELECT B + L DAY L FROM T,(SELECT ROW_NUMBER() OVER() - 1 L
      FROM SYSIBM.SYSCOLUMNS) K
      WHERE B+L DAY <= C
      GROUP BY B+L DAY
      ) TMP
)
SELECT PREV.L + 1 DAY,N.L - 1 DAY FROM N
LEFT JOIN N PREV ON PREV.COL = N.COL - 1
WHERE DAYS(N.L) - DAYS(PREV.L) > 1

FIND GAP

2007/2/2 2007/2/4

2008年6月13日 星期五

Change data type decimal to char in DB2 UDB8.2

-- 由數值轉字串CHAR時,DB2會字動在左方補0

SELECT CHAR(CAST(1.25 AS DECIMAL(5,2)))
FROM  SYSIBM.SYSDUMMY1;

-- 結果為:

001.25

-- 以小數點分前後處理

SELECT RTRIM(CHAR(INT(NUM)))||SUBSTR(CHAR(NUM),LOCATE('.',CHAR(NUM)))
FROM
(
SELECT CAST(1.25 AS DECIMAL(5,2)) NUM
FROM SYSIBM.SYSDUMMY1
) T;

-- 結果為:

1.25

create User Define Function INSTR using DB2 UDB8.2


/*
 Create function INSTR
  iFind => Character you want to find
  iStr => String
  iOrder => if there are more than one character in string,
        which you want to find
  return location of that certain character
*/


DROP FUNCTION INSTR
GO
CREATE FUNCTION INSTR(iFind CHAR(1),iStr VARCHAR(1024),iOrder INTEGER)
RETURNS INTEGER
RETURN WITH N(COL,TXT,TXT1) AS (
    SELECT 1 COL,TXT,SUBSTR(TXT,1,1)
    FROM (SELECT iStr TXT
         FROM SYSIBM.SYSDUMMY1) T
    WHERE TXT > ''
    UNION ALL
    SELECT N.COL + 1,TXT,SUBSTR(TXT,N.COL+1,1)
    FROM N
    WHERE N.COL + 1 <= LENGTH(RTRIM(TXT))
    )
    SELECT COALESCE(COL,0) FROM
    (
     SELECT COL,TXT1,ROW_NUMBER() OVER() OD FROM N
     WHERE TXT1 = iFind
    ) T
    WHERE OD = iOrder;

-- test

SELECT INSTR(',','abcd,efghijkl,m',1) FROM SYSIBM.SYSDUMMY1;

==> Result

5


SELECT INSTR(',','abcd,efghijkl,m',2) FROM SYSIBM.SYSDUMMY1;

==> Result

14

2008年6月11日 星期三

Recursive SQL II using DB2 UDB 8.2


/* 運用Recursive SQL將以逗號組出之字串拆解成多筆資料
  ex: 將a,bb,ccc,d,e,f拆解開來
*/


WITH N(COL,TXT,TXT1) AS (
SELECT 1 COL,TXT,TXT
FROM  (SELECT ','||'a,bb,ccc,d,e,f' || ',' TXT
     FROM  SYSIBM.SYSDUMMY1) T
UNION  ALL
SELECT N.COL + 1,TXT,SUBSTR(TXT1,LOCATE(',',TXT1,2))
FROM  N
WHERE  N.COL + 1 <= LENGTH(N.TXT) - LENGTH(REPLACE(N.TXT,',','')) -1
)
SELECT SUBSTR(TXT1,2,LOCATE(',',TXT1,2) -2)
FROM N;

得到以下結果

a
bb
ccc
d
e
f

Generate 9x9 using DB2UDB 8.2 SQL Statement


WITH N(X) AS (
SELECT 1 X
FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT N.X + 1
FROM N
WHERE N.X + 1 <= 9
)
SELECT N.X , N1.X , N.X * N1.X FROM N,N N1;

2008年6月10日 星期二

Recursive SQL Statement to pipe string using DB2UDB 8.2

/*以Recursive SQL語法將以下結果將COST以「,」pipe起來

NAME  COST
----  -----
ABC   101
HJK   130
HJK   206
KLM
OPU   105
OPU   109
OPU   113
OPU   117
OPU   118
OPU   199
OPU   287
OPU   288
XYZ   100
XYZ   101
XYZ   102
XYZ   203
XYZ   204


WITH   N(COL,CNT,NAME,COST) AS (
SELECT  0 COL,COUNT(*) CNT,NAME,CAST('' AS VARCHAR(1000))
FROM   ORION2
WHERE  COST > ''
GROUP  BY NAME
UNION  ALL
SELECT  N.COL + 1,N.CNT,PLUS.NAME,PLUS.COST || ',' || N.COST
FROM   (SELECT ROW_NUMBER() OVER(PARTITION BY NAME) COL,
          NAME,COST
      FROM  ORION2
      WHERE  COST > ''
      ORDER BY NAME,COST DESC) PLUS,N
WHERE  PLUS.NAME = N.NAME
AND   N.COL + 1 = PLUS.COL
AND   N.COL + 1 <= N.CNT)
SELECT NAME,SUBSTR(RTRIM(COST),1,LENGTH(RTRIM(COST))-1)
FROM   N
WHERE  COL = CNT
UNION
SELECT NAME,COST FROM ORION2 WHERE COST = ''
ORDER BY NAME;

/*結果如下:

NAME  COST
----  -------------------------------
ABC   101
HJK   130,206
KLM
OPU   105,109,113,117,118,199,287,288
XYZ   100,101,102,203,204

Recursive SQL using DB2 UDB 8.2

建立測試table

CREATE TABLE ORION
(
NAME VARCHAR(100) ,
COST VARCHAR(1000)
) IN USERSPACE1;

新增測試資料

Insert into ORION (NAME, COST) Values ('ABC', '101');
Insert into ORION (NAME, COST) Values ('XYZ', '100,101,102,204,203');
Insert into ORION (NAME, COST) Values ('HJK', '130,206');
Insert into ORION (NAME, COST) Values ('KLM', '');
Insert into ORION (NAME, COST) Values ('OPU', '105,109,113,118,117,199,288,287');

運用Recursive SQL將COST欄位裡用逗號區分的資料拆解成多筆資料

WITH N(COL,NAME,COST,COST1) AS (
SELECT 1 COL,NAME,','||COST||',',','||COST||','
FROM  ORION
WHERE  COST > ''
UNION  ALL
SELECT N.COL + 1,N.NAME,N.COST,
     SUBSTR(N.COST1,LOCATE(',',N.COST1,2))
FROM  N
WHERE  N.COL + 1 <= LENGTH(N.COST) -
            LENGTH(REPLACE(N.COST,',','')) - 1
)
SELECT NAME,SUBSTR(COST1,2,LOCATE(',',COST1,2) - 2)
FROM   N
UNION
SELECT NAME,COST
FROM  ORION WHERE COST = ''
ORDER  BY NAME;

得到以下結果

NAME   COST
------- -------
ABC    101
HJK    130
HJK    206
KLM
OPU    105
OPU    109
OPU    113
OPU    117
OPU    118
OPU    199
OPU    287
OPU    288
XYZ    100
XYZ    101
XYZ    102
XYZ    203
XYZ    204

Generate 9x9 using Oracle10g SQL Statement


SELECT X,Y,X*Y
FROM
(SELECT level x FROM DUAL CONNECT BY LEVEL <= 9),
(SELECT level y FROM DUAL CONNECT BY LEVEL <= 9)