程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> Oracle到DB2移植解決方案

Oracle到DB2移植解決方案

編輯:DB2教程

1、Oracle中的decode

DB2解決方案:用case條件表達式完成。

case兩種語法模式:

(1)CASE

WHEN 條件 THEN 結果1

ELSE 結果2

END

(2)CASE 表達式1

WHEN 表達式2 THEN 結果1

ELSE 結果2

END

上面的WHEN可以重復多次,就像C中的SWITCH ..CASE的表達.

例如:

  SELECT ORDNO,CUSNO,
  CASE MONTH(SHIPDATE)
  WHEN ''01'' THEN ''Jan''
  WHEN ''02'' THEN ''Feb''
  WHEN ''03'' THEN ''Mar''
  WHEN ''04'' THEN ''Apr''
  WHEN ''05'' THEN ''May''
  WHEN ''06'' THEN ''Jun''
  WHEN ''07'' THEN ''Jul''
  WHEN ''08'' THEN ''Aug''
  WHEN ''09'' THEN ''Sep''
  WHEN ''10'' THEN ''Oct''
  WHEN ''11'' THEN ''Nov''
  WHEN ''12'' THEN ''Dec''
  END
  FROM FILE

應用實例:

  Oracle SQL:
  -------------------------
  select decode(t.organtypecode, ''D'', t.parent, ''S'', t.parent, t.id)
  from A_ORGAN t
  where t.parent = 35
  DB2 SQL:
  -------------------------
  select case x.organtypecode
  when ''D'' then
  x.parent
  when ''S'' then
  x.parent
  else
  x.id
  end
  from a_Organ x
  where x.parent = 35;


2、Oracle中的Start with...Connect By遞歸查詢

DB2解決方案:用with公共遞歸表達式來解決。

DB2解決方案:用case條件表達式完成。

Oracle SQL:  

selectt.id
  froma_organt
  startwitht.idin(selectdecode(t.organtypecode,
  ''D'',
  t.parent,
  ''S'',
  t.parent,
  t.id)
  fromA_ORGAN
  wheret.id=35)
  connectbyt.parent=priort.id

DB2SQL:  

WITHFKK(id)as
  (selecto.idfroma_organo
  whereo.id=35
  UNIONALL
  selectcasex.organtypecode
  when''D''thenx.parent
  when''S''thenx.parent
  elsex.id
  end
  fromFKKfk,a_organx
  wherefk.id=x.parent)
  selectdistinctidfromFKK;

3、Oracle中的dual表對應DB2中的SYSIBM.SYSDUMMY1表

DB2解決方案:對應於DB2中的 SYSIBM.SYSDUMMY1表

Oracle SQL:

-------------------------

select 15 as ttt from dual

結果:

ttt

-------

15

DB2 SQL:

-------------------------

select 15 as ttt from SYSIBM.SYSDUMMY1

結果:

ttt

-------

15

4、日期轉換問題

DB2解決方案:有相應的函數

Oracle SQL:  

selectm.*
  fromdj_mcdjm
  wherem.mcqc||''''like''%$P%''
  andm.xzqhdm||''''like''%$P%''
  andm.hylbdm||''''like''%$P%''
  andm.blqsrq>=to_date(''$P'',''yyyy-mm-dd'')
  andm.blqsrq<to_date(''$P'',''yyyy-mm-dd'')+1


DB2 SQL:

--------------------

-名稱:名稱庫查詢

--作者:雷智民

--日期:2006-10-27

--FOR :DB2  

selectm.*
  fromdj_mcdjm
  wherem.mcqc||''''like''%%''
  andm.xzqhdm||''''like''%%%''
  andm.hylbdm||''''like''%%%''
  anddate(m.blqsrq)>=date(''1900-01-01'')
  anddate(m.blqsrq)<date(''2050-01-01'')+1day

5、nvl 問題

DB2解決方案:利用coalesce(,) 或 value(,)方法。

oracle中的nvl對應db2中的value ,只是Oracle中的語法更有寬松一些,在db2中,value要求兩個參數必須是同一種類型的,nvl要求則不是很嚴格,nvl(A,‘’),如果A是數字類型或者日期類型的這個表達式也沒有 問題,但是在db2中,若是也這麼寫的話, value(A,''),那肯定就有問題了,總的來說,基本上是一致的。

6、左右外連接問題

db2的左右外連接的語法和標准sql語法一樣,只是沒有Oracle中的(+)這個簡單符號來標記左右外連接,left (right) outer join on

1).內連接INNER JOIN的Oracle和DB2的寫法

Oracle可以這樣實現? Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no; DB2 可以這樣實現? Select * from db2admin.bsempms inner join db2admin.bsdptms on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;

2).外連接的Oracle和DB2的寫法(右外連接,左外連接,完全外連接,組合外連接)

Oracle可以這樣實現?


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;

DB2 可以這樣實現?

Select * from db2admin.bsempms right outer join db2admin.bsdptms

on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;

Select * from db2admin.bsempms left outer join db2admin.bsdptms

on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;

Select * from db2admin.bsempms full outer join db2admin.bsdptms

on db2admin.bsempms.dpt_no=db2admin.bsdptms.dpt_no;

7、LIKE問題

db2中謂詞LIKE後邊的表達式不支持字段。只支持一下類型:

A constant

A special register

A host variable

A scalar function whose Operands are any of the above

An expression concatenating any of the above

在db2 9 中我做了以下的試驗,  

CreatetableRRTest(pkIDVARCHAR(20)NOTNULL,unID1varchar(20)NotNULL,UnID2varchar(20),"CUSTOMER_ID"VARCHAR(6),
  "ORDER_TYPE"DECIMAL(2,0),
  "EXECUTION_TYPE"DECIMAL(2,0),
  "ORDER_DATE"VARCHAR(8),
  "ORDER_TIME"VARCHAR(6),
  "ORDER_DATETIME"TIMESTAMP,
  "SIDE"DECIMAL(1,0),
  "TRADE_TYPE"DECIMAL(1,0),
  "ORDER_AMOUNT"DECIMAL(15,2),
  "ORDER_PRICE"DECIMAL(8,4),
  TSIDvarchar(20))
  insertintoRRTest
  SELECTOrder_ID,Order_ID,Order_ID,CUSTOMER_ID,ORDER_TYPE,EXECUTION_TYPE,ORDER_DATE,ORDER_TIME,ORDER_DATETIME,SIDE,TRADE_TYPE,ORDER_AMOUNT,ORDER_PRICE,ORDER_ID
  FROMDB2INST1.Fx_OrderwhereORDER_DATE>'20070401'
  GO
  selectcount(*)FromRRTEST
  72239
  ALTERTABLE"DB2INST1".RRTest
  ADDPRIMARYKEY
  (pkID);
  CREATEUNIQUEINDEXUNIQINDXONRRTest(unID1)
  CREATEINDEXINDX002ONRRTest(unID2)
  db2"RUNSTATSONTABLEDB2INST1.RRTestONALLCOLUMNSANDINDEXESALLALLOWWRITEAccess"
  db2connecttodb2TT
  db2+c
  select*FromRRTESTwhereTSID='20070223ORD01267732'forupdatewithRR
  select*FromRRTESTwhereTSID='20070222ORD01266302'forupdatewithRR
  select*FromRRTESTwhereTSID='20070223ORD01267732'forupdatewithRS
  select*FromRRTESTwhereTSID='20070222ORD01266302'forupdatewithRS
  select*FromRRTESTwhereunID1='20070223ORD01267732'forupdatewithRR
  select*FromRRTESTwhereunID1='20070222ORD01266302'forupdatewithRR
  select*FromRRTESTwhereunID1='20070223ORD01267732'forupdatewithRS
  select*FromRRTESTwhereunID1='20070222ORD01266302'forupdatewithRS
  select*FromRRTESTwhereunID2='20070223ORD01267732'forupdatewithRR
  select*FromRRTESTwhereunID2='20070222ORD01266302'forupdatewithRR
  select*FromRRTESTwhereunID2='20070223ORD01267732'forupdatewithRS
  select*FromRRTESTwhereunID2='20070222ORD01266302'forupdatewithRS
  select*FromRRTESTwherepkID='20070223ORD01267732'forupdatewithRR
  select*FromRRTESTwherepkID='20070222ORD01266302'forupdatewithRR
  select*FromRRTESTwherepkID='20070223ORD01267732'forupdatewithRS
  select*FromRRTESTwherepkID='20070222ORD01266302'forupdatewithRS


按照以上字段 pkID 是主鍵,unID1 是唯一健索引,unID2 是普通健索引,TSID 是普通字段,沒有在上建立索引。

試驗結論:

PK_INDEX UNIQ_INDEX NormalINDEX NO_INDEX

WITH RR 鎖行,不鎖表 鎖行,不鎖表 不鎖行,不鎖表(1) 鎖行,鎖表

WITH RS 鎖行,不鎖表 鎖行,不鎖表 鎖行,不鎖表 鎖行,鎖表(2)

鎖行是指在一個事務中用某種方式讀取並更改了改行數據並顯示得指明要修改後,這個事務將鎖住改行,直到它提交或者回滾了事務後,才釋放該鎖。

鎖表是指在用以上各種SQL在讀取並更改一行的同時鎖住了整個表。

對以上紅字部分(1)可能有不能理解的是:為什麼對普通索引和主鍵或者唯一健索引的不同結論?

對 PK和UNIQ的解釋是因為RR 是可重復的讀的級別,對這次檢索掃描到的有可能成為自己的潛在檢索對象的內容都會鎖住,而因為是主鍵或者唯一健,別的行不可能成為這次這個檢索的潛在讀的范圍,就是對別的數據此事務根本就沒有必要鎖,任何情況的更改都不可能出現幻讀的情況(此表上的約束限制),所以只鎖這一行。這麼理解對PK,UNIQ沒有問題。

但是NormalINDEX 我認為應該是鎖住這個表而不是不鎖。這點一直沒想明白。留待以後再加強理解。

對 RS隔離級別是“鎖定檢索到的數據行”,是通過SQL檢索到的結果進行鎖定, PK,UNIQ,INDEX的結論完全都可以理解。 對 tableScan的檢索而出現的鎖表有些象RR隔離級別的所為。

嗯,想了一圈沒想明白,故把詳細過程貼出來給自己留個紀念,以供以後遇到此類並發控制程序中注意一下,select * From TTT where ****= ? for update with RR(RS),這裡的 *** 可不是隨便定義的。

隔離級別分為RR/RS/CS/UR這四個級別。 下面讓我們來逐一論述:

1. RR隔離級別: 在此隔離級別下, DB2會鎖住所有相關的紀錄。 在一個SQL語句執行期間, 所有執行此語句掃描過的紀錄都會被加上相應的鎖。 具體的鎖的類型還是由操作的類型來決定, 如果是讀取,則加共享鎖; 如果是更新, 則加獨占鎖。 由於會鎖定所有為獲得SQL語句的結果而掃描的紀錄, 所以鎖的數量可能會很龐大, 這個時候, 索引的增加可能會對SQL語句的執行有很大的影響,因為索引會影響SQL語句掃描的紀錄數量。

2. RS隔離級別: 此隔離級別的要求比RR隔離級別稍弱,此隔離級別下會鎖定所有符合條件的紀錄。 不論是讀取, 還是更新, 如果SQL語句中包含查詢條件, 則會對所有符合條件的紀錄加相應的鎖。 如果沒有條件語句, 也就是對表中的所有記錄進行處理,則會對所有的紀錄加鎖。

3. CS隔離級別: 此隔離級別僅鎖住當前處理的紀錄。

4. UR隔離級別:此隔離級別下,如果是讀取操作,不會出現任何的行級鎖。對於非只讀的操作,它的鎖處理和CS相同。

DB2默認的隔離級別是CS。即 游標穩定性。

DB2分頁查詢

SELECT * FROM (Select 字段1,字段2,字段3,rownumber() over(ORDER BY 排序用的列名 ASC) AS rn from 表名) AS a1 WHERE a1.rn BETWEEN 10 AND 20

SELECT * FROM (Select T.*,rownumber() over(ORDER BY T.ID ASC) AS rn from ADMINISTRATOR.TEST_BY_HUFENG T) AS a1 WHERE a1.rn BETWEEN 1 AND 3


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved