Oracle專家進階編程學習筆記
一.準備工作
1.建立基本調試環境
Create demo schema(建立示範模式)
sqlplus>start $ORACLE_HOME/sqlplus/demo/demobld.sql
2.建立login.sql
---------------------------------
define_editor=vi
set serveroutput on size 1000000
set trimspool on
set long 500
set linesize 100
set pagesize 9999
column plan_plus_exp format a80
column global_name new_value gname
select lower(user)||'@'||decode(global_name,'WEBDB.FANYAMIN.NET','webdb',global_name) global_name from global_name;
set sqlprompt '&gname>'
set termout on
-------------------------------------------------
3.在sqlplus中配置AutoTrace
1)cd $ORACLE_HOME/rdbms/admin
log into sqlplus as system(connect system/manager@webdb)
run @utlxplan
run create public synonym plan_table for plan_table;
run grant all on plan_table to public;
2)
cd $ORACLE_HOME/sqlplus/admin
log into sqlplus as sys(connect sys/change_on_install@webdb)
run @plustrce
run grant plustrace to public;
二.內容
1.開發成功的Oracle應用程式
一條簡單秘訣
if(possible) 就用單條SQL陳述式完成
else if(possible) 用plsql程式
else if(possible) 用java預存程序
else if(possible) 用C外部過程
else 考慮是否真有必要這樣做
兩個指導方針
1)不要在MTS下運行長事務<45s
2)使用綁定變數
system@webdb>alter system flush shared_pool;
system@webdb>set timing on
執行這兩個sql檔案,一比較,發現使用綁定變數後,速度快多了
--bindtest1.sql, did not use bind variable
-----------------------------------------------------------------------------
declare
type rc is ref cursor;
l_rc rc;
l_dummy all_objects.object_name%type;
l_start number default dbms_utility.get_time;
begin
for i in 1..1000
loop
open l_rc for
'select object_name from all_objects where object_id='||i;
fetch l_rc into l_dummy;
close l_rc;
end loop;
dbms_output.put_line(round((dbms_utility.get_time-l_start)/100,2)||'seconds...');
end;
/
--bindtest2.sql, use bind variable
-----------------------------------------------------------
declare
type rc is ref cursor;
l_rc rc;
l_dummy all_objects.object_name%type;
l_start number default dbms_utility.get_time;
begin
for i in 1..1000
loop
open l_rc for
'select object_name from all_objects where object_id=:x'
using i;
fetch l_rc into l_dummy;
close l_rc;
end loop;
dbms_output.put_line(round((dbms_utility.get_time-l_start)/100,2)||'seconds...');
end;
/
Oracle封鎖策略
1)只有當修改時,oracle在行級上鎖定資料,不要把鎖定上升到塊級或表級
2)Oracle決不會為讀取而鎖定資料,簡單讀取不能在資料行上設定鎖定
3)資料的寫入器不會阻塞資料讀取器.
4)只有當另一個資料寫入器已經鎖定了某行資料後,才阻塞其他人對該行資料的寫入.資料讀取器決不會阻塞資料的寫入器
Oracle的這種"不阻塞"方法用一個副作用,如果想要一次只有一個使用者訪問某行資料,在多使用者環境中,必須經常使用在多線程程式設計用到的相似技巧,
select * from resources where resource-name=:room_name FOR UPDATE
Oracle的並行控制機制(多版本一致讀)
一致性查詢:在某一時刻查詢產生一致結果
非阻塞查詢:資料寫入器從來不阻塞查詢