SQL Server、Access、Oracle都是數據庫平臺,都支持SQL,但有差異。通常是語義相近而形式不同,但也有形似而含義不同的。有的差異是細節的,有的差異還不小。如果不注意這些差異就可能會被困擾,於是把最近遇到的有關差異整理了一下,將來還會擴充。
一、多表連接更新的差異
Access形式最簡潔,SQL Server略麻煩(加個from跟多個表名,保證update和set之間只有一個表名),Oracle有點怪,用嵌套實現。
SQL Server:
update qsdc
set sjyt=地類代號,mc2=地類名稱
from 國有集體,qsdc
where 國有集體.區號=qsdc.qh
and 國有集體.街道號=qsdc.jdh
and 國有集體.街坊號=qsdc.jfh
and 國有集體.宗地號=qsdc.zdh
and sjyt<>地類代號
Access:
update ma_ZD_QLR,MA_ZD
set ma_ZD_QLR.BSM=MA_ZD.BSM,
ma_ZD_QLR.pcode=MA_ZD.pcode
where MA_ZD.djh=ma_ZD_QLR.djh
and ma_ZD_QLR.BSM=0
Oracle:
Create Table TabA(
ID int,
name varchar2(20)
);
Create Table TabB(
ID int,
name varchar2(20)
);
insert into TabA values(1,'ABC');
insert into TabA values(2,'DEF');
insert into TabA values(3,'GHI');
insert into TabB values(1,'');
insert into TabB values(2,'');
update TabB
set TabB.NAME=(selectTabA.NAME fromTabA where TabB.ID=TabA.ID)
where TabB.ID IN (select ID from TabA);
說明:
如果直接執行select TabA.NAME fromTabA where TabB.ID=TabA.ID是不行的,而要用selectTabA.NAME fromTabA,TabB where TabB.ID=TabA.ID才能被正確執行,但是在這裏被嵌套的這裏TabB反倒是不能寫的。通常被嵌套的select語句是能夠獨立執行的,這就是稱之爲“怪”的原因。
二、外連接的差異
以左外連接爲例,SQL Server用LEFT OUTER JOIN,Access和Oracle用LEFT JOIN。
SQL Server:
select * from ShengChan as S
LEFT OUTER JOIN
ZhiLiang as Z
on (Z.合同號=S.合同號),
XiaDaRen as X,
SheJi as J
where X.合同號=S.合同號and j.合同號=S.合同號;
這是三個表等值連接再對ZhiLiang表作左外連接。
Access:
Select * from (ma_zd LEFT JOIN ma_fw ON ma_zd.djh=ma_fw.lszd )
Oracle:
select * from PersonMain主表
left join PersonJingPin精品庫表
on 主表.個人標識=精品庫表.個人標識
left join PersonCongYe職業表
on 主表.個人標識=職業表.個人標識
left join PersonCongYi從醫表
on 主表.個人標識=從醫表.個人標識
where 精品庫代碼 like '%,13,%';
這是一個主表對三個從表作左外連接。
三、NULL值處理差異
外聯接就會有NULL,在數值計算時,常常要用0、’空’、’無’等代替。
SQL Server:
select isnull(zdmj,0) from qsdc;
Access:
select NZ(ma_fw.SHAPE_Area,0) from ma_fw;
Oracle:
selectnvl(name,'無') from TabA;
四、嵌套查詢差異
SQL Server與Access基本一致,在查詢結果前後加一對圓括號,並以As別名緊跟;Oracle不要As,把查詢結果括起來後直接跟別名。經過如此別名命名之後,被嵌套的中間查詢結果就可以當作關係表一樣來引用,這個功能極大地擴充了單條SQL語句的威力,尤其對沒有提供類似T-SQL、PL/SQL等過程化語言擴展的Access這樣的平臺,顯得尤爲重要。
SQL Server:
select * from
(
select * from國有集體 ,qsdc
where國有集體.區號=qsdc.qh
and國有集體.街道號=qsdc.jdh
and國有集體.街坊號=qsdc.jfh
and國有集體.宗地號=qsdc.zdh
) as aa
,tdsq
where aa.qh=tdsq.qh
and aa.jdh=tdsq.jdh
and aa.jfh=tdsq.jfh
and aa.zdh=tdsq.zdh
Access:
select left(d.LSZD,9) as行政區劃代碼,sum(Area_jzmj) as建築面積 from
(
select LSZD,sum(SHAPE_Area*FWCS) as Area_jzmj from ma_fw
group by LSZD
) as d
group by left(d.LSZD,9)
Oracle:
寫法相近,但不要as關鍵字:
select ID_A from
(
select A.ID ID_A, A.NAME,B.ID ID_B
from taba A, tabb B
where A.ID=B.ID
) T;
五、Select Into差異
SQL Server和Access中都用於將查詢結果的記錄集輸出到新表中(新表不需要事先存在),Oracle的Select Into是PL/SQL中使用的,有點像SQL ServerT-SQL中的Fetch Into。
SQL Server:
select * into newTAB
from 國有集體
Access:
select B.OBJECTID, B.xh-A.zd_xh+1 as FWBH_
into myFWBH_ from
(
select min(xh) as zd_xh,LSZD as zd from myFWBH
group by LSZD
) as A,
myFWBH as B
where A.zd=B.LSZD
order by B.xh
(這實際上還是個自連接。)
Oracle:
寫法上差異似乎不那麼大,但概念不一樣了,是PL/SQL中用於將單行記錄的字段值賦給PL/SQL變量,Into後面不是表名而是PL/SQL變量,比如:
Select SUM(SALARY),SUM(SALARY*0.1)
Into TOTAL_SALARY,TATAL_COMMISSION
From EMPLOYEE
Where DEPT=10;
而如果要實現類似SQL Server、Access中Select Into語句的效果,可以使用Oracle的Create Table As語句,如下:
create table TabE as
select * from TabA
where id<3;