近日在做項目的過程中對plsql的使用非常多,主要是編寫存儲過程實現業務邏輯。但是在coding的過程中遇到非常奇怪的問題。
問題是:在package包頭中定義了一個變量,current_time := sysdate,然后在procedure使用這個定義的變量,直接insert到表里。一個很簡單的實現吧。
但是奇怪的是,每次insert到表里的這個時間莫名其妙的會變化,有時候是正確的,有時候就是一個不確定的時間,有時候每次都和上次的時間一樣,真是令人頭疼不已。
下面先看一下代碼片段吧。
package包頭:
?
- create?or?replace?package?PKG_LIFE_AML_DATA?is??
- ??
- ??CURRENT_TIME?date?:=?sysdate;??
- ??
- ??procedure?T_NORMAL(i_start_date?in?varchar2,??
- ?????????????????????i_end_date?in?varchar2,??
- ?????????????????????i_organ_id?in?t_company_organ.organ_id%TYPE);??
package包體(僅僅取最關鍵部分的代碼):
?
- procedure?T_NORMAL(i_start_date?in?varchar2,??
- ?????????????????????i_end_date?in?varchar2,??
- ?????????????????????i_organ_id?in?t_company_organ.organ_id%TYPE)?is??
- ??
- ????insert?into?t_su_data??
- ????????(insert_time)??
- ??????values??
- ?????????(CURRENT_TIME);??
- ?end;??
通過上述代碼不難看出,這其實是一個非常簡單的conding。。。但是確實是有問題的。問題就是處在這個CURRENT_TIME的定義的位置,它其實是全局變量。
?
PLSQL中的全局變量在該包初始化的時候就被賦予了值,在同一個session中不會在變化,所以這就導致了為什么每次insert的時間都不對,但是不太清楚oracle如何判斷一個session的開始和結束,因為通過測試來看,其時間有時候是正確的。
所以,正確的做法是在insert數據的時候,直接使用該sysdate,而不在包頭的地方將sysdate賦值給CURRENT_TIME,因此不管是在java中還是在plsql中全局變量能不用就不用的,那么什么時候可以使用呢?
1.最簡單的,它是個常量,它永遠不會變,那么定義成全局變量會非常好用。
2.package_B想使用package_A中的一個值或者變量,那么這時候就可以再package_A中定義個全局變量 CURRENT_TIME(不賦值,僅定義),在存儲過程中對其賦值;這時候切換到package_B,那么在package_B中只需要調用package_A.CURRENT_TIME即可,就能獲得package_A中的變量值,然后在package_B中根據此值做一些操作。這樣非常好用。
? ? ? 總結一下,變量不要定義成全局變量!太危險啦~