關於約束CASE語句和游標 我們的技術專家談完整性
時間和歸屬問題
我仔細閱讀了《Oracle
i 數據庫概念手冊(Oracle
i Database Concepts Manual)》和你們的站點
但對下述概念仍不明白
定義為可延遲(deferrable)的約束可以指定為
initially immediate(初始化立即執行)或
initially deferred(初始化延遲執行)
我知道什麼是延遲約束
但不明白什麼叫
初始化立即執行的可延遲約束
和
初始化延遲執行的可延遲約束
請解釋二者的區別
還有
這些約束有什麼用途?這是通常容易混淆的問題
我希望下面的例子能解釋清楚
初始化立即執行/延遲執行規定了在默認情況下應該如何執行約束
初始化立即執行
在每條語句執行結束時檢驗約束
初始化延遲執行
一直等到事務完成後(或者調用set constraint immediate語句時)才檢驗約束
來看下面的代碼 SQL> create table t
( x int constraint
check_x check ( x >
)
deferrable
initially immediate
y int constraint
check_y check ( y >
)
deferrable
initially deferred
)
/
Table created
SQL> insert into t values (
);
row created
SQL> commit;
Commit complete
所以
當兩個約束同時滿足時才能正確無誤地插入行
但是
如果我試圖插入違反CHECK_X約束(初始化立即執行的約束)的行
則系統會立即檢驗約束
並得到下面的結果
SQL> insert into t values (
);
insert into t values (
)
*
ERROR at line
:
ORA
: check constraint
(OPS$TKYTE
CHECK_X) violated
由於CHECK_X是可延遲但初始化為立即執行的約束
所以這一行立刻被拒絕了
而CHECK_Y則不同
它不僅是可延遲的
而且初始化為延遲執行
這就意味著直到我用COMMIT命令提交事務或將約束狀態設置為立即執行時才檢驗約束
SQL> insert into t values (
);
row created
現在它是成功的(總之到目前為止是成功的)
我將約束檢驗延遲到了執行COMMIT的時候
SQL> commit;
commit
*
ERROR at line
:
ORA
: transaction rolled back
ORA
: 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 (
);
row created
由於將初始化立即執行的約束設置為延遲執行的模式
這個語句似乎執行成功
但是
當我用COMMIT語句提交事務時
看一下會發生什麼
SQL> commit;
commit
*
ERROR at line
:
ORA
: transaction rolled back
ORA
: check constraint
(OPS$TKYTE
CHECK_X) violated
事務提交失敗並回滾
因為在COMMIT語句之後對約束進行了檢驗
相反
我可以將初始化為延遲執行的約束變為
立即
執行的約束
SQL> set constraints all immediate;
Constraint set
SQL> insert into t values (
);
insert into t values (
)
*
ERROR at line
:
ORA
: check constraint
(OPS$TKYTE
CHECK_Y) violated
前面在我提交前能執行的語句現在立即出了問題
因為我手動修改了默認的約
束模式
延遲約束有哪些實際用處呢? 有很多
它主要用於物化視圖(快照)
這些視圖會使用延遲約束來進行視圖刷新
在刷新物化視圖的過程中
可能會破壞完整性
而且將不能逐句檢驗約束
但到執行COMMIT時
數據完整性就沒問題了
而且能滿足約束
沒有延遲約束
物化視圖的約束可能會使刷新過程不能成功進行
使用延遲約束的另一個普遍原因是
當預測是否需要更新父/子關系中的主鍵時
它有助於級聯更新
如果你將外鍵設為可延遲
但初始化為立即執行
那麼你就可以
將所有約束設置為可延遲
將父鍵更新為一個新值
至此子關系的完整性約束不會被驗證
將子外鍵更新為這個新值
COMMIT
只要所有受更新影響的子記錄都指向現有的父記錄
這條命令就能成功執行
如果沒有延遲約束
這一更新過程將極為艱難
參見/~tkyte/update_cascade/l中給出的沒有這一特性時進行級聯更新所必需的示例代碼!
此外
你可以在各種多語句事務中使用延遲約束
這些事務在處理的過程中需要暫時破壞完整性
但最後它們都會物歸原樣
如何計算時間 你是如何計算第一頁中AGE列顯示的時間的?我之所以問這個問題是因為我看到它有多種格式
如
個月
小時
年
個小時
等等
我是Oracle新手
想知道你們在使用哪種日期計算法
我就是使用Oracle
i第
版(
版)中介紹的使用已久但很好用的CASE語句
Select
case
when sysdate
timestamp <
/
then round(
*
*(sysdate
timestamp))
||
minutes old
when sysdate
timestamp <
then round(
*(sysdate
timestamp))
||
hours old
when sysdate
timestamp <
then trunc(sysdate
timestamp)
||
days old
when sysdate
timestamp <
then trunc((sysdate
timestamp)/
)
||
weeks old
when sysdate
timestamp <
then round(months_between
(sysdate
timestamp))
||
months old
else round(months_between
(sysdate
timestamp)/
)
||
years old
end age
如果你想在Oracle
i的PL/SQL中使用CASE語句
則會出現一個錯誤消息
因為PL/SQL語法分析程序不識別CASE語句
(請注意
在Oracle
i不存在這樣的問題
)為了避開Oracle
i的限制
你可以
將CASE語句隱藏在視圖當中
並用PL/SQL來查詢視圖
使用嵌套的DECODE語句來代替CASE語句
我本人願意使用視圖
但讀者Martin Burbridge在 網站上公布了下面這段DECODE代碼
decode(sign(sysdate
timestamp
/
)
round(
*
*(sysdate
timestamp))
||
minutes old
decode(sign(sysdate
timestamp
)
round(
*(sysdate
timestamp))
||
hours old
decode(sign(sysdate
timestamp
)
trunc(sysdate
timestamp)
||
days old
decode(sign(sysdate
timestamp
)
trunc((sysdate
timestamp)/
)
||
weeks old
decode(sign(sysdate
timestamp
)
round(months_between
(sysdate
timestamp))
||
months old
round(months_between
(sysdate
timestamp)/
)
||
years old
))))) age
它與CASE語句的功能完全相同
只是不太明顯
文件放在哪? 我正在考慮為一個應用程序設計些選項
利用它用戶可以上傳和存儲可供他人下載的文檔
文檔可以是平均大小為
K的Microsoft Word文檔
最初需要(從CD)移植
到
個文檔
當使用該應用程序時存儲數量會增加到大約
個文檔
浏覽器前端是用於上傳和下載的PL/SQL插件(PL/SQL cartridge)頁面
一開始
會有
到
人幾乎同時訪問該應用程序
兩周內每天將有
人訪問(分散訪問)
文檔本身在數據庫中作為BLOB存儲
從使用方面考慮
你覺得這樣的選項好嗎?它會過多占用系統全局區(SGA)嗎?考慮到應用程序的需求以及前端(基於浏覽器)
除了保存為BLOB
還有沒有其他選擇
如文件系統?
我什麼都存在數據庫裡
就是這樣
如果數據就是你的一切
無論它們有什麼樣的值
事實上都要放到數據庫中
在那裡數據可以得到專業化的管理
備份
恢復而且安全
除了這些實實在在的好處
你還可以索引及搜索文檔
(誠然
用文件系統也可以做這些
但在索引和文檔之間不存在完整性
)在數據庫中
你可以轉換文檔格式(例如
上傳一個DOC文件
而顯示為HTML格式)
你的數據是完全集成的
安全的
有備份的而且隨時供你使用
在Oracle公司內部
我們將一個幾千吉字節的數據庫作為整個公司的一個單一的文件服務器
公司所有文檔都存在那裡
存在這樣一個單一的地方
可以對這些文檔進行備份
搜索
建立索引和訪問
在常規的文件系統中管理成千上萬的文檔是不可能的
From:http://tw.wingwit.com/Article/program/Oracle/201311/18071.html