分享
 
 
 

关于约束、CASE语句和游标的一些介绍

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

关于约束、CASE语句和游标

我们的技术专家谈完整性、时间和归属问题。

我仔细阅读了《Oracle9i 数据库概念手册(Oracle9i Database Concepts Manual)》和你们的站点,但对下述概念仍不明白:

"定义为可延迟(deferrable)的约束可以指定为:

1. initially immediate(初始化立即执行)或

2. initially deferred(初始化延迟执行)。"

我知道什么是延迟约束,但不明白什么叫"初始化立即执行的可延迟约束"和"初始化延迟执行的可延迟约束"。请解释二者的区别。还有,这些约束有什么用途?这是通常容易混淆的问题。我希望下面的例子能解释清楚。初始化立即执行/延迟执行规定了在默认情况下应该如何执行约束:

初始化立即执行--在每条语句执行结束时检验约束

初始化延迟执行--一直等到事务完成后(或者调用set constraint immediate语句时)才检验约束

来看下面的代码:

SQL create table t

2

( x int constraint

check_x check ( x 0 )

deferrable

initially immediate,

3

y int constraint

check_y check ( y 0 )

deferrable

initially deferred

4

)

5

/

Table created.

SQL insert into t values ( 1,1 );

1 row created.

SQL commit;

Commit complete.

所以,当两个约束同时满足时才能正确无误地插入行。但是,如果我试图插入违反CHECK_X约束(初始化立即执行的约束)的行,则系统会立即检验约束,并得到下面的结果:

SQL insert into t values ( -1,1);

insert into t values ( -1,1)

*

ERROR at line 1:

ORA-02290: check constraint

(OPS$TKYTE.CHECK_X) violated

由于CHECK_X是可延迟但初始化为立即执行的约束,所以这一行立刻被拒绝了。而CHECK_Y则不同,它不仅是可延迟的,而且初始化为延迟执行,这就意味着直到我用COMMIT命令提交事务或将约束状态设置为立即执行时才检验约束。

SQL insert into t values ( 1,-1);

1 row created.

现在它是成功的(总之到目前为止是成功的)。我将约束检验延迟到了执行COMMIT的时候:

SQL commit;

commit

*

ERROR at line 1:

ORA-02091: transaction rolled back

ORA-02290: check constraint

(OPS$TKYTE.CHECK_Y) violated

此时数据库将事务回滚,因为违反约束导致了COMMIT语句的失败。这些语句说明了初始化立即执行与初始化延迟执行约束之间的区别。initially(初始化)部分指定Oracle什么时候会进行默认的约束检验--是在语句结束时[immediate(立即执行)],还是在事务结束时[deferred(延迟执行)]。我还要说明deferred(可延迟)子句有什么用。我可以发出命令,让所有可延迟的约束变为延迟执行的。注意,你也可以对一个约束使用该命令;你不必让所有可延迟的约束都变为延迟执行的:

SQL set constraints all deferred;

Constraint set.

SQL insert into t values ( -1,1);

1 row created.

由于将初始化立即执行的约束设置为延迟执行的模式,这个语句似乎执行成功;但是,当我用COMMIT语句提交事务时,看一下会发生什么:

SQL commit;

commit

*

ERROR at line 1:

ORA-02091: transaction rolled back

ORA-02290: check constraint

(OPS$TKYTE.CHECK_X) violated

事务提交失败并回滚,因为在COMMIT语句之后对约束进行了检验。相反,我可以将初始化为延迟执行的约束变为"立即"执行的约束:

SQL set constraints all immediate;

Constraint set.

SQL insert into t values ( 1,-1);

insert into t values ( 1,-1)

*

ERROR at line 1:

ORA-02290: check constraint

(OPS$TKYTE.CHECK_Y) violated

前面在我提交前能执行的语句现在立即出了问题。因为我手动修改了默认的约

束模式。

延迟约束有哪些实际用处呢? 有很多。它主要用于物化视图(快照)。这些视图会使用延迟约束来进行视图刷新。在刷新物化视图的过程中,可能会破坏完整性,而且将不能逐句检验约束。但到执行COMMIT时,数据完整性就没问题了,而且能满足约束。没有延迟约束,物化视图的约束可能会使刷新过程不能成功进行。

使用延迟约束的另一个普遍原因是,当预测是否需要更新父/子关系中的主键时,它有助于级联更新。如果你将外键设为可延迟、但初始化为立即执行,那么你就可以

将所有约束设置为可延迟。

将父键更新为一个新值--至此子关系的完整性约束不会被验证。

将子外键更新为这个新值。

COMMIT--只要所有受更新影响的子记录都指向现有的父记录,这条命令就能成功执行。

如果没有延迟约束,这一更新过程将极为艰难。参见asktom.oracle.com/~tkyte/update_cascade/index.html中给出的没有这一特性时进行级联更新所必需的示例代码!

此外,你可以在各种多语句事务中使用延迟约束,这些事务在处理的过程中需要暂时破坏完整性,但最后它们都会物归原样。

如何计算时间

你是如何计算asktom.oracle.com第一页中AGE列显示的时间的?我之所以问这个问题是因为我看到它有多种格式,如9个月3小时;2.3年;19个小时;等等。我是Oracle新手,想知道你们在使用哪种日期计算法。

我就是使用Oracle8i第2版(8.1.6版)中介绍的使用已久但很好用的CASE语句:

Select

case

when sysdate-timestamp

then round(24*60*(sysdate-timestamp))

|| ' minutes old '

when sysdate-timestamp

then round(24*(sysdate-timestamp))

|| ' hours old '

when sysdate-timestamp

then trunc(sysdate-timestamp)

|| ' days old '

when sysdate-timestamp

then trunc((sysdate-timestamp)/7)

|| ' weeks old '

when sysdate-timestamp

then round(months_between

(sysdate,timestamp))

|| ' months old '

else round(months_between

(sysdate,timestamp)/12,1)

|| ' years old '

end age, ...

如果你想在Oracle8i的PL/SQL中使用CASE语句,则会出现一个错误消息,因为PL/SQL语法分析程序不识别CASE语句。(请注意,在Oracle9i不存在这样的问题。)为了避开Oracle8i的限制,你可以

将CASE语句隐藏在视图当中,并用PL/SQL来查询视图。

使用嵌套的DECODE语句来代替CASE语句。

我本人愿意使用视图,但读者Martin Burbridge在asktom.oracle.com 网站上公布了下面这段DECODE代码:

decode(sign(sysdate-timestamp-1/24),-1,

round(24*60*(sysdate-timestamp))

|| ' minutes old ',

decode(sign(sysdate-timestamp - 1), -1,

round(24*(sysdate-timestamp))

|| ' hours old ',

decode(sign(sysdate-timestamp-14),-1,

trunc(sysdate-timestamp)

|| ' days old ',

decode(sign(sysdate-timestamp-60),-1,

trunc((sysdate-timestamp)/7)

|| ' weeks old ',

decode(sign(sysdate-timestamp-365),-1,

round(months_between

(sysdate,timestamp))

|| ' months old ',

round(months_between

(sysdate,timestamp)/12,

1)

|| ' years old '

))))) age

它与CASE语句的功能完全相同--只是不太明显。

文件放在哪?

我正在考虑为一个应用程序设计些选项,利用它用户可以上传和存储可供他人下载的文档。文档可以是平均大小为150K的Microsoft Word文档。最初需要(从CD)移植18000到20000个文档,当使用该应用程序时存储数量会增加到大约25000个文档。浏览器前端是用于上传和下载的PL/SQL插件(PL/SQL cartridge)页面。一开始,会有400到500人几乎同时访问该应用程序,两周内每天将有300人访问(分散访问)。 文档本身在数据库中作为BLOB存储。

从使用方面考虑,你觉得这样的选项好吗?它会过多占用系统全局区(SGA)吗?考虑到应用程序的需求以及前端(基于浏览器),除了保存为BLOB,还有没有其他选择,如文件系统?

我什么都存在数据库里。就是这样。如果数据就是你的一切,无论它们有什么样的值,事实上都要放到数据库中,在那里数据可以得到专业化的管理、备份,恢复而且安全。除了这些实实在在的好处,你还可以索引及搜索文档。(诚然,用文件系统也可以做这些,但在索引和文档之间不存在完整性。)在数据库中,你可以转换文档格式(例如,上传一个DOC文件,而显示为HTML格式)。你的数据是完全集成的、安全的、有备份的而且随时供你使用。

在Oracle公司内部,我们将一个几千吉字节的数据库作为整个公司的一个单一的文件服务器。公司所有文档都存在那里,存在这样一个单一的地方,可以对这些文档进行备份、搜索、建立索引和访问。在常规的文件系统中管理成千上万的文档是不可能的

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有