DBA Data[Home] [Help]

PACKAGE BODY: APPS.DT_FNDATE

Source


1 package body dt_fndate as
2 /* $Header: dtfndate.pkb 120.1.12010000.3 2009/08/27 06:51:30 avarri ship $ */
3 /*
4  Copyright (c) Oracle Corporation 1991,1992,1993. All rights reserved
5 
6 /*
7 
8  Name         : dt_fndate
9  Author       : P.K.Attwood
10  Date Created : 01-OCT-1993
11  Synopsis     : This package containes procedures for maintaining the
12                 session date held in fnd_sessions.
13  Contents     : change_ses_date
14                 get_dates
15 
16 
17  Change List
18  -----------
19  Date        Name          Vers    Bug No     Description
20  -----------+-------------+-------+----------+-------------------------------+
21  01-OCT-1993 P.K.Attwood   4.0                First Created.
22  03-MAR-1994 P.K.Attwood   4.1                Changed select statement in
23                                               get_dates to query
24                                               trunc(sysdate). Added
25                                               delete_ses_rows procedure.
26  13-MAY-1994 P.K.Attwood   3.0                Transferred out nocopy of version 4 DT
27                                               into version 3, so all server
28                                               side code is in the same place.
29  05-OCT-1994 R.M.Fine      30.1               Renamed package to dt_fndate to
30                                               conform to naming convention that
31                                               all objects begin '<prod>_'.
32  30-MAR-1999 P.K.Attwood   110.1   861272     In get_dates corrected setting
33                            115.1              g_sys_date when globals
34                                               variables have not been set and
35                                               a row already exists in
36                                               fnd_sessions.
37  22-APR-1999 P.K.Attwood   115.2   854170     Rewrote the delete_ses_rows
38                                               procedure to remove the join
39                                               between FND_SESSIONS and a v$
40                                               view.
41  13-AUG-1999 P.K.Attwood   115.3              In change_ses_date when no row
42                                               is found in FND_SESSIONS added
43                                               raise exception.
44  22-JUN-2001 P.K.Attwood   115.4   1841141    To support OPS (Oracle Parallel
45                                               Server) inside the
46                                               delete_ses_rows procedure
47                                               changed references from
48                                               v$session to gv$session.
49  13-SEP-2001 P.K.Attwood   115.5              Added set_effective_date
50                                               procedure.
51  19-DEC-2001 G.Perry       115.6              Added dbdrv
52  31-JAN-2002 G.Sayers      115.7              Added validation to get_dates and
53                                               change_ses_date to ensure
54                                               g_ses_yesterday_date is set to
55                                               null when g_ses_date=01/01/0001
56  01-FEB-2002 G.Sayers      115.8              Removed hr_utility commands.
57  06-Dec-2002 A.Holt        115.9              NOCOPY Performance Changes for 11.5.9
58  09-Feb-2005 K.Tangeeda    115.10             Versions 115.10 and 115.11 contain
59                                               the same code as version 115.9
60  09-Feb-2005 K.Tangeeda    115.11             This version contains the same
61                                               code as the version 115.9
62  07-May-2006 V.Kaduban     120.1              Procedure delete_old_ses_rows has
63                                               been added which is exact copy of
64                                               delete_ses_rows. Existing
65                                               delete_ses_rows has been modified
66                                               so that all it does is to delete the
67                                               row from fnd_sessions for the current
68                                               session. Also the procedure
69                                               clean_fnd_sessions has been added
70                                               which does the same thing as
71                                               delete_old_ses_rows but used by
72                                               a concurrent program to do that
73                                               cleanup periodically.All these
74                                               changes are as a part of long term
75                                               solution to the bug 4163689.
76  14-Aug-2008 avarri     120.2      7260450    Modified delete_old_ses_rows to
77                                               resolve the performance issue.
78  27-Aug-2009 avarri     120.1.12000000.3      Modified delete_old_ses_rows to
79                                               replace fndSessionId.FIRST with 1 and
80                                               fndSessionId.LAST with
81                                               fndSessionId.COUNT to resolve 8839784
82   -----------+-------------+-------+----------+-------------------------------+
83 */
84 --
85 -- Declare globals to this package
86 --
87   g_ses_date           date;
88   g_ses_yesterday_date date;
89   g_start_of_time      date;
90   g_end_of_time        date;
91   g_sys_date           date;
92 --
93   procedure get_dates (p_ses_date           out nocopy date,
94                        p_ses_yesterday_date out nocopy date,
95                        p_start_of_time      out nocopy date,
96                        p_end_of_time        out nocopy date,
97                        p_sys_date           out nocopy date,
98                        p_commit             out nocopy number) is
99     v_commit boolean;
100   begin
101     v_commit := FALSE;
102     if g_ses_date is null then
103       --
104       -- Only select date fields, if globals have not been set
105       --
106       begin
107         select fs.effective_date
108              , fs.effective_date -1
109              , to_date('01/01/0001','DD/MM/YYYY')
110              , to_date('31/12/4712','DD/MM/YYYY')
111              , trunc(sysdate)
112           into g_ses_date
113              , g_ses_yesterday_date
114              , g_start_of_time
115              , g_end_of_time
116              , g_sys_date
117           from fnd_sessions fs
118          where fs.session_id = userenv('sessionid');
119       exception
120         when no_data_found then
121           --
122           -- Set date fields
123           --
124           g_ses_date           := trunc(sysdate);
125           if g_ses_date =  to_date('01/01/0001', 'DD/MM/YYYY') then
126              g_ses_yesterday_date := null;
127           else
128              g_ses_yesterday_date := g_ses_date - 1;
129           end if;
130           g_start_of_time      := to_date('01/01/0001', 'DD/MM/YYYY');
131           g_end_of_time        := to_date('31/12/4712', 'DD/MM/YYYY');
132           g_sys_date           := g_ses_date;
133           --
134           -- Insert row in fnd_sessions as one does not
135           -- already exist.
136           --
137           insert into fnd_sessions (session_id, effective_date)
138             values (userenv('sessionid'), g_ses_date);
139           --
140           v_commit := TRUE;
141       end;
142     end if;
143     --
144     if g_ses_date = to_date('01/01/0001', 'DD/MM/YYYY') then
145        g_ses_yesterday_date := null;
146     else
147        g_ses_yesterday_date := g_ses_date - 1;
148     end if;
149     --
150     p_ses_date           := g_ses_date;
151     p_ses_yesterday_date := g_ses_yesterday_date;
152     p_start_of_time      := g_start_of_time;
153     p_end_of_time        := g_end_of_time;
154     p_sys_date           := g_sys_date;
155     if (v_commit) then
156       p_commit := 1;
157     else
158       p_commit := 0;
159     end if;
160   end get_dates;
161 --
162 --
163 --
164   procedure change_ses_date (p_ses_date in  date,
165                              p_commit   out nocopy number) is
166     v_commit              boolean;
167     no_row_need_to_insert exception;
168   begin
169     begin
170       --
171       -- Update row in fnd_sessions
172       --
173       v_commit := FALSE;
174       --
175       update fnd_sessions
176          set effective_date = trunc(p_ses_date)
177        where session_id = userenv('sessionid');
178       --
179       -- When no row is found in FND_SESSIONS
180       -- raise an exception to insert a row.
181       --
182       if sql%rowcount = 0 then
183         raise no_row_need_to_insert;
184       end if;
185       --
186       v_commit := TRUE;
187    exception
188       when no_row_need_to_insert then
189         g_ses_date           := trunc(p_ses_date);
190         if g_ses_date = to_date('01/01/0001', 'DD/MM/YYYY') then
191            g_ses_yesterday_date := null;
192         else
193            g_ses_yesterday_date := g_ses_date - 1;
194         end if;
195         g_start_of_time      := to_date('01/01/0001', 'DD/MM/YYYY');
196         g_end_of_time        := to_date('31/12/4712', 'DD/MM/YYYY');
197         g_sys_date           := trunc(sysdate);
198         --
199         -- Insert row in fnd_sessions as one does not
200         -- already exist.
201         --
202         insert into fnd_sessions (session_id, effective_date)
203           values (userenv('sessionid'), g_ses_date);
204         --
205         v_commit := TRUE;
206     end;
207     --
208     -- Update package globals
209     --
210     g_ses_date           := trunc(p_ses_date);
211     if g_ses_date= to_date('01/01/0001', 'DD/MM/YYYY') then
212        g_ses_yesterday_date := null;
213     else
214        g_ses_yesterday_date := g_ses_date - 1;
215     end if;
216     --
217     if (v_commit) then
218       p_commit := 1;
219     else
220       p_commit := 0;
221     end if;
222   end change_ses_date;
223 --
224 --
225 --
226   procedure set_effective_date
227   (p_effective_date                in     date     default null
228   ,p_do_commit                     in     boolean  default false
229   ) is
230    v_commit number;
231   begin
232     change_ses_date(p_ses_date => nvl(p_effective_date, sysdate)
233                    ,p_commit   => v_commit);
234     if p_do_commit and v_commit = 1 then
235       commit;
236     end if;
237   end set_effective_date;
238 --
239 --
240 --
241   procedure delete_ses_rows(p_commit out nocopy number) is
242     --
243     -- Declare exceptions to be handled
244     --
245   begin
246           delete from fnd_sessions f
247             where session_id = userenv('sessionid');
248           p_commit := 1;
249           if(SQL%ROWCOUNT = 0) then
250             p_commit := 0 ;
251           end if ;
252           exception
253           when Others then
254             p_commit := 0;
255   end delete_ses_rows;
256 --
257 --
258 --
259   procedure init_dates is
260   begin
261     --
262     -- Initializes globals to NULL to ensure first call to get_dates
263     -- will insert a row into fnd_sessions. (It is not possible to
264     -- commit here, so don't insert the row into fnd_sessions.)
265     --
266     g_ses_date           := NULL;
267     g_ses_yesterday_date := NULL;
268     g_start_of_time      := NULL;
269     g_end_of_time        := NULL;
270     g_sys_date           := NULL;
271   end init_dates;
272 --
273 --
274 --
275   procedure delete_old_ses_rows(p_commit out nocopy number) is
276     --
277     -- Declare cursors
278     --
279     cursor csr_fnd_ses is
280       select session_id
281         from fnd_sessions;
282     --
283     -- To fix Bug 1841141 the v$ view in the
284     -- following cursor was changed to gv$. Inspite of
285     -- comments in the RDBMS manual it should be safe
286     -- to always reference the gv$ view even when a
287     -- non-parallel server is being used. This
288     -- is because the v$ views are based on the gv$
289     -- views with filter INST_ID = userenv('Instance').
290     --
291     cursor csr_gv_ses  is
292       select audsid
293         from gv$session;
294     --
295     -- Declare exceptions to be handled
296     --
297     Resource_Busy  exception;
298     Pragma Exception_Init(Resource_Busy, -54);
299     --
300     -- Local variables
301     --
302     v_exists  varchar2(30);
303     TYPE sessionId IS TABLE OF fnd_sessions.session_id%TYPE INDEX BY BINARY_INTEGER;
304     fndSessionId  sessionId;
305     gvSessionId   sessionId;
306     delSessionId  sessionId;
307     l_session_exists number := 0;
308     k   number := 1;
309     bulkFetchRowLimit number := 10000;
310   begin
311     --
312     -- Bug 854170: Changed original delete statement as joins
313     -- between delete a v$ view and a standard table are not
314     -- supported by the RDBMS.
315     -- Original like code:
316     --   delete from fnd_sessions f
317     --    where not exists (select null
318     --                        from v$session s
319     --                        where s.audsid = f.session_id);
320     --   p_commit := 1;
321     --
322     -- Attempt to obtain an exclusive lock on the DateTrack date
323     -- prompts table. This table lock acts as a gatekeeper to
324     -- the FND_SESSIONS delete logic.
325     --
326     -- When this process obtains the table lock then it should go
327     -- on to remove old session rows from FND_SESSIONS. i.e. Where
328     -- there is no corresponding row in GV$SESSION. When this
329     -- process does not obtain the table lock it indicates that
330     -- another process must be performing the FND_SESSIONS delete
331     -- logic. So this session does not need to do anything extra.
332     --
333     begin
334       lock table dt_date_prompts_tl in exclusive mode nowait;
335       --
336       -- If this point is reached then the table lock
337       -- has been obtained by this process.
338       --
339       -- Get all the rows from gv$session using bulk collect.
340       --
341       open csr_gv_ses;
342       fetch csr_gv_ses BULK COLLECT INTO gvSessionId;
343       close csr_gv_ses;
344       --
345       -- For each row in FND_SESSIONS see if a corresponding
346       -- row exists in GV$SESSION. When there is no matching
347       -- row delete the FND_SESSIONS row.
348       --
349       open csr_fnd_ses;
350       loop
351       fetch csr_fnd_ses BULK COLLECT INTO fndSessionId limit bulkFetchRowLimit;
352         for i in 1..fndSessionId.COUNT loop
353           for j in  1.. gvSessionId.COUNT loop
354             if (fndSessionId(i) =  gvSessionId(j)) then
355                l_session_exists := 1;
356                exit;
357             end if;
358           end loop;
359           --
360           if l_session_exists = 0 then
361             delSessionId(k) := fndSessionId(i);
362             k := k + 1;
363           end if;
364           l_session_exists := 0;
365         end loop;
366       exit when csr_fnd_ses%notfound;
367       end loop;
368       close csr_fnd_ses;
369       --
370       forall l in 1..delSessionId.count
371         delete from fnd_sessions where session_id = delSessionId(l);
372       --
373       p_commit := 1;
374     exception
375       when Resource_Busy then
376         --
377         -- If this point is reached then the table lock
378         -- has not been obtained by this process. This
379         -- means another process must be currently
380         -- performing the FND_SESSIONS delete logic.
381         -- So this process does not need to do anything
382         -- with the FND_SESSIONS table.
383         --
384         p_commit := 0;
385     end;
386   end delete_old_ses_rows;
387 --
388 --
389 --
390   procedure clean_fnd_sessions ( errbuf  out nocopy varchar2,
391                                  retcode out nocopy varchar2 ) is
392     l_commit_flag number;
393   begin
394     delete_old_ses_rows(l_commit_flag);
395     if l_commit_flag = 1 then
396       commit;
397     end if;
398   end clean_fnd_sessions;
399 --
400 end dt_fndate;