近日在做项目的过程中对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中根据此值做一些操作。这样非常好用。