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

Oracle到DB2的SQL移植解決方案

編輯:DB2教程

   將Oracle(大型網站數據庫平台)遷移到DB2上,SQL會有些變化,下面讓我們來具體看一下:

1、Oracel中的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:

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

select t.id

from a_organ t

start with t.id in (select decode(t.organtypecode,

''D'',

t.parent,

''S'',

t.parent,

t.id)

from A_ORGAN

where t.id = 35)

connect by t.parent = prior t.id

DB2 SQL:

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

WITH FKK(id) as

(select o.id from a_organ o

where o.id=35

UNION ALL

select case x.organtypecode

when ''D'' then x.parent

when ''S'' then x.parent

else x.id

end

from FKK fk, a_organ x

where fk.id=x.parent)

select distinct id from FKK;

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:

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

select m.*

from dj_mcdj m

where m.mcqc || '' '' like ''%$P%''

and m.xzqhdm || '' '' like ''%$P%''

and m.hylbdm || '' '' like ''%$P%''

and m.blqsrq >= to_date(''$P'', ''yyyy-mm-dd'')

and m.blqsrq < to_date(''$P'', ''yyyy-mm-dd'')+1

DB2 SQL:

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

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

--名稱:名稱庫查詢

--作者:雷智民

--日期:2006-10-27

--FOR :DB2

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

select m.*

from dj_mcdj m

where m.mcqc || '' '' like ''%%''

and m.xzqhdm || '' '' like ''%%%''

and m.hylbdm || '' '' like ''%%%''

and date(m.blqsrq) >= date(''1900-01-01'')

and date(m.blqsrq) < date(''2050-01-01'')+1 day

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文檔:
使用格式: match-expression LIKE pattern-expression
match-expression
An expression that specifIEs the string that is to be examined to see if it conforms to a certain pattern of characters.
The expression can be specifIEd by:

A constant
A special register
A host variable (including a locator variable or a file reference variable)
A scalar function
A large object locator
A column name
An expression concatenating any of the above

pattern-expression
An expression that specifIEs the string that is to be matched.
The expression can be specifIEd by:

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
with the following restrictions:

No element in the expression can be of type LONG VARCHAR, CLOB, LONG VARGRAPHIC, or DBCLOB. In addition it cannot be a BLOB file reference variable.
The actual length of pattern-expression cannot be more than 32 672 bytes.


DB2中幾個隔離級別select..for update with ** 的行鎖

看了很多介紹DB2中隔離級別和鎖的各種用法和機制,動手做了一個比較詳盡的試驗,
對於有些結果我還真沒想明白。。

在 db2 9 中我做了以下的試驗,
Create table RRTest (pkID VARCHAR(20) NOT NULL ,unID1 varchar(20) Not NULL,UnID2 varchar(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),
TSID varchar(20) )

insert into RRTest
SELECT Order_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
FROM DB2INST1.Fx_Order where ORDER_DATE >'20070401'
GO
select count(*) From RRTEST
72239

ALTER TABLE "DB2INST1".RRTest
ADD Prima(最完善的虛擬主機管理系統)RY KEY
(pkID);

CREATE UNIQUE INDEX UNIQINDX ON RRTest(unID1)
CREATE INDEX INDX002 ON RRTest(unID2)
db2 "RUNSTATS ON TABLE DB2INST1.RRTest ON ALL COLUMNS AND INDEXES ALL ALLOW WRITE Access"

db2 connect to db2TT
db2 +c

select * From RRTEST where TSID='20070223ORD01267732' for update with RR
select * From RRTEST where TSID='20070222ORD01266302' for update with RR

select * From RRTEST where TSID='20070223ORD01267732' for update with RS
select * From RRTEST where TSID='20070222ORD01266302' for update with RS

select * From RRTEST where unID1='20070223ORD01267732' for update with RR
select * From RRTEST where unID1='20070222ORD01266302' for update with RR
select * From RRTEST where unID1='20070223ORD01267732' for update with RS
select * From RRTEST where unID1='20070222ORD01266302' for update with RS

select * From RRTEST where unID2='20070223ORD01267732' for update with RR
select * From RRTEST where unID2='20070222ORD01266302' for update with RR
select * From RRTEST where unID2='20070223ORD01267732' for update with RS
select * From RRTEST where unID2='20070222ORD01266302' for update with RS

select * From RRTEST where pkID='20070223ORD01267732' for update with RR
select * From RRTEST where pkID='20070222ORD01266302' for update with RR
select * From RRTEST where pkID='20070223ORD01267732' for update with RS
select * From RRTEST where pkID='20070222ORD01266302' for update with RS

按照以上字段 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