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;