Oracle9i与SYBASE ASE12.5相比的几个不足

** Oracle9i ** ** 与 SYBASE ASE12.5 相比的几个不足 **

千千如梦 2004-7-24

Oracle9i 与 ASE12.5 分别是世界主流数据库厂商 ORACLE 、 SYBASE 公司的主打产品,拥有相当大的市场份额。本文抛开两者之间在体系结构、技术路线上的差异,纯粹从使用者的角度出发,整理了 Oracle9i 与 SYBASE Adaptive Server Enterprise 12.5 ( 简称 ASE12.5) 相比的几个不足,至于 ASE12.5 与 Oracle9i 相比的不足则不在本文的讨论范围。

1 不支持正则表达式:熟悉 Unix/Linux 及 ASE12.0/12.5 的人都知道正则表达式的灵活、功能强大。像“查找所有包含数字的表名称”这样的需求,在 ASE12.5 中极其简单:

select name from sysobjects where type=”U” and name like “%[0-9]%” ( 这里 sysobjects 相当于 Oracle9i 中的 all_objects) ,而 Oracle9i 的实现要颇费一番周折了,一般情况下很多人都是写一个函数实现,以下就是刚学 Oracle 的时候写的一个实现该功能的函数:

CREATE OR REPLACE function is_number(p_str in varchar2)

return number

as

w_char char(1);

i number :=1;

begin

while i <= length(p_str) loop

w_char := substr(p_str,i,1);

if w_char >='0' and w_char <='9' then

return 1;

end if;

i:=i+1;

end loop;

return 0;

end;

/

在 Oracle9i 调用一个自定义的 PL/SQL 函数开销会很大;远不及 ASE12.5 的内部实现。

2 UPDATE 语句的“蹩脚” , 在数据库的应用中,两个表关联 update 是很常见的,如有如下两个表: t_a(id,name,point,…),t_b(id,point,…) id 均为主键或 unique index, 现要实现根据 id 的对应关系将 t_b 表上 point 加至 t_a 表 point 。我们来看 Oracle9i 与 ASE12.5 的实现 :

/** For Oracle9i **/

Update t_a a

Set a.point=a.point+(select b.point from t_b b where b.id=a.id)

Where exists (select 1 from from t_ b where b.id=a.id)

/

/** For ASE12.0/12.5 **/

Update t_a

Set point=a.point+b.point

From t_a a,t_b b

Where a.id=b.id

Go

Oracle9i 的语句似乎不顾清晰、容易误解,而且查看执行计划发现 t_b 表或索引扫描了 2 遍! ASE12.5 只扫描了 1 遍。虽然第 2 遍是逻辑读,但总觉得不甘心;

有时如果 t_b 表较小,且 id 上无索引,我宁愿采用 cursor 方式,多次试验表明

比 Create INDEX+ 关联 UPDATE 要快得多。还有就是采用 Oracle9i 的 OLAP 特性,用 merge 语句来完成。

3 临时表技术的比较:

ITEM

|

存储位置

|

DDL

|

数据生命周期

---|---|---|---

ORACLE9i

|

任何表空间

|

用户自己维护 , 表名是全局(数据库用户)唯一

|

Session / Transaction

ASE12.5

|

Tempdb 库

|

用户 create; 用户 drop 或系统 drop ,表名 Session 级唯一

|

Session

|

|

|

虽然两者各有所长,但我觉得 ASE12.5 的实现似乎更得 ” 临时 ” 的精髓 — 在每个会话期间,“召之即来 ”, 不用担心与别人重名, #11 #22 #aa #bb 随个人喜好创建, ” 挥之即去 ”, 会话结束亦不必显式删除,由系统代劳,不必担心垃圾表存在。

4 Count 的问题还是 Distinct 的问题 ? 在 select 语句使用 distinct 关键字修饰以返回唯一的行集,这在统计分析、剔除重复数据尤为重要,但是有时仅想统计一个总数呢?我第一次是这样写的 :

Select count(distinct a,b,c) from my_table 结果语法不对,只好修改为:

Select count(*) from ( select distinct a,b,c from my_table ) 方得以通过,心想这一定是 distinct 惹的祸,但随后发现 distinct 被冤枉了,因为即使是:

Select count(a,b,c) from my_table 也是不行的。只能写成:

Select count(*) from ( select a,b,c from my_table )

但在 ASE12.5 上无论是 Select count(distinct a,b,c) from my_table 还是 Select count(a,b,c) from my_table 均能得出正确结果。

5 数据导入导出工具的比较: Exp/Imp 在备份和恢复方面用的比较多,且受版本 ( 高低版本、 32bit/64bit) 、语言影响较大,且 sqlldr 只能算作导入工具,严格来说 Oracle9i 没有表数据的文本级的导出工具!相反, ASE12.5 的 bcp 的在表数据导入导出方面的很灵活,格式也很简单,很容易做应用程序的输入。还有视图、存储过程、触发器的导出工具 defncopy 也很好用;至于 Oracle9i ,我 N+1 次遇到以下情况:

问:我怎么得到某个存储过程的代码啊?

答:有没有装 client 阿?

问:装了!

答:打开 Enterprise Manager Console ,登录后在方案下面找吧

……

问:怎么麻烦阿?

答:那你有没有装 Toad 或者 PL/Develop 阿 , 这些工具好用点

问:没有啊!

答: L

或者

问:我怎么得到某个存储过程的代码啊?

答:有没有装 client 阿?

问:装了,可我在主机上啊!

答:那你用 sqlplus 看罢,

set long 300

select text from all_source where name=’YourName’

go

问:哇,怎么麻烦阿

答: L

要是在 ASE12.0

问:我怎么得到某个存储过程的代码啊?

答:用 defncopy 吧

问:怎么用啊

答:我靠,这么简单!你还用问阿! J

6 联机备份:虽然 Oracle9i 提供了冷、热备份技术 , 但是与 ASE12.5 基于 Open Server 技术的联机实时备份 Backup Server 相比似乎逊色不少,将备份的介质直接拿到另外一台 ASE12.5 进行 Load ,很快很简单就能获得一个时效性极强的 ” 镜像 ” 数据库环境。而我觉得 Exp/Imp 比较琐碎,且限制也较多。

Oracle9i 附带的命令行工具如 sqlplus exp/imp sqlldr 等,执行时无一例外都将输出时间、版本、版权信息,给像我这样喜欢用 shell 处理结果的人来说徒增不少麻烦,相比 ASE12.5 的 isql bcp defncopy 的干净利落,是 Oracle9i 的无聊和 ” 自恋 ” ,还是埃里克森的霸气呢 ?

Published At
Categories with 数据库类
comments powered by Disqus