DBA Data[Home] [Help]

PACKAGE BODY: APPS.AD_MV

Source


1 package body ad_mv as
2 /* $Header: admvb.pls 120.4 2006/06/01 19:18:16 vlim noship $*/
3 
4    gs_package_name_c               CONSTANT VARCHAR2(30) := 'ad_mv';
5 
6    gn_timeout_c                    CONSTANT INTEGER := dbms_lock.maxwait;
7    gs_lockhandle_name_c            CONSTANT VARCHAR2(12) := 'AD_MV_CREATE';
8 
9    ga_stmt                         dbms_sql.varchar2s;
10 
11    check_tspace_exist              varchar2(100);
12 
13    mv_exists                       EXCEPTION;
14    PRAGMA EXCEPTION_INIT(mv_exists, -12006);
15 
16    -- Bug 3562360: sallamse
17    -- Removed the set_sess_parm_if_required procedure
18    -- global constants for package body
19    -- everything between 8.1.7 and 9.0.0
20    gn_limit_min_c                 CONSTANT PLS_INTEGER := 817;
21    gn_limit_max_c                 CONSTANT PLS_INTEGER := 900;
22 
23    ls_version                     VARCHAR2(20);
24    ls_compatibility               VARCHAR2(20);
25 
26    --
27    -- This procedure should not be called directly from an
28    -- external program when the statement is really long
29    -- and dbms_sql.parse() is expected to be used, i.e.
30    -- ab_long_stmt_i=TRUE. In these cases, the call should
31    -- be made to do_mv_ddl().
32    --
33    PROCEDURE create_mv (
34      as_mview_name_i               VARCHAR2
35    , as_stmt_i                     VARCHAR2
36    , ab_long_stmt_i                BOOLEAN DEFAULT FALSE
37    )
38    IS
39      ls_name_c                     CONSTANT VARCHAR2(30) := gs_package_name_c || '.' || 'create_mv';
40      ls_dummy                      VARCHAR2(1);
41      ln_resource_status            INTEGER;
42      ls_lockhandle                 VARCHAR2(128);
43      l_db_version                  VARCHAR2(30);
44      l_statement                   VARCHAR2(500);
45      ln_cursor                     INTEGER;
46      ln_dummy                      INTEGER;
47    BEGIN
48      dbms_lock.allocate_unique (
49        lockname    => gs_lockhandle_name_c
50      , lockhandle  => ls_lockhandle
51      );
52 
53      -- requesting lock
54      ln_resource_status := dbms_lock.request (
55                              lockhandle        => ls_lockhandle
56                            , lockmode          => dbms_lock.x_mode
57                            , timeout           => gn_timeout_c
58                            , release_on_commit => FALSE
59      );
60      -- 0 - success
61      -- 1 - timeout
62      -- 2 - deadlock
63      -- 3 - parameter error
64      -- 4 - already own lock specified by 'id' or 'lockhandle'
65      -- 5 - illegal lockhandle
66      -- Everything except 'success' is bad
67      IF (ln_resource_status <> 0)
68      THEN
69        RAISE_APPLICATION_ERROR(-20001, ls_name_c || ': could not get the lock: ' || ln_resource_status);
70      END IF;
71 
72      -- Is the mview 'partially' created? If so, it has to be dropped
73      -- IF (as_mview_name_i IS NOT NULL)
74      -- THEN
75      BEGIN
76        SELECT 'x'
77          INTO ls_dummy
78          FROM user_tables
79             , user_mviews
80         WHERE table_name = mview_name
81           AND mview_name = create_mv.as_mview_name_i
82           AND NOT EXISTS (
83                 SELECT null
84                   FROM user_objects
85                  WHERE object_type = 'MATERIALIZED VIEW'
86                    AND object_name = table_name
87                    AND object_name = create_mv.as_mview_name_i
88               )
89        ;
90        EXECUTE IMMEDIATE 'DROP MATERIALIZED VIEW ' || as_mview_name_i;
91      EXCEPTION
92        WHEN NO_DATA_FOUND
93        THEN null;
94      END;
95      -- END IF;
96 
97      BEGIN
98 
99        BEGIN
100          l_statement := 'select version from v$instance';
101          execute immediate l_statement into l_db_version;
102        EXCEPTION
103          when others then
104   	     raise_application_error(-20000,
105 	      'Unable to get the DB Version.');
106        END;
107 
108        -- Bug 3562360: sallamse
109        -- Moved  setting "_mv_refresh_selections" session parameter
110        -- to init section of the package body
111 
112        IF (ab_long_stmt_i)
113        THEN
114          ln_cursor := dbms_sql.open_cursor;
115          dbms_sql.parse(c => ln_cursor, statement => ga_stmt
116                        , lb => 1, ub => ga_stmt.COUNT
117                        , lfflg => FALSE, language_flag => dbms_sql.native
118          );
119          ln_dummy := dbms_sql.execute(ln_cursor);
120          dbms_sql.close_cursor(ln_cursor);
121          ga_stmt.DELETE;
122        ELSE
123          EXECUTE IMMEDIATE as_stmt_i;
124        END IF;
125      EXCEPTION
126        WHEN mv_exists
127        THEN null;
128        WHEN OTHERS
129        THEN ln_resource_status := dbms_lock.release(lockhandle => ls_lockhandle);
130             ga_stmt.DELETE;
131             RAISE;
132      END;
133 
134      ln_resource_status := dbms_lock.release(lockhandle => ls_lockhandle);
135      IF (ln_resource_status <> 0)
136      THEN
137        RAISE_APPLICATION_ERROR(-20002, ls_name_c || ': could not release the lock: ' || ln_resource_status);
138      END IF;
139    END create_mv;
140 
141    -- Bug 3562360: sallamse
142    -- Created wraper procedure as Java JDBC driver does not support
143    -- passing boolean parameters in PL/SQL Stored Procedures.
144    --
145    -- This procedure should not be called directly from an
146    -- external program when the statement is really long
147    -- and dbms_sql.parse() is expected to be used, i.e.
148    -- ab_long_stmt_i=1.  In these cases, the call should
149    -- be made to do_mv_ddl2().
150    --
151    PROCEDURE create_mv2 (
152      as_mview_name_i               VARCHAR2
153    , as_stmt_i                     VARCHAR2
154    , ab_long_stmt_i                INTEGER DEFAULT 0
155    )
156    IS
157    BEGIN
158      IF (ab_long_stmt_i=1) THEN
159        create_mv(as_mview_name_i, as_stmt_i, TRUE);
160      ELSE
161        create_mv(as_mview_name_i, as_stmt_i, FALSE);
162      END IF;
163    END create_mv2;
164 
165    --
166    -- This procedure should not be called directly from an
167    -- external program when the statement is really long
168    -- and dbms_sql.parse() is expected to be used, i.e.
169    -- ab_long_stmt_i=TRUE. In these cases, the call should
170    -- be made to do_mv_ddl().
171    --
172    PROCEDURE mv_ddl (
173      as_mview_name_i               VARCHAR2
174    , as_stmt_i                     VARCHAR2
175    , ab_long_stmt_i                BOOLEAN DEFAULT FALSE
176    )
177    IS
178      ls_name_c                     CONSTANT VARCHAR2(30) := gs_package_name_c || '.' || 'mv_ddl';
179      ls_dummy                      VARCHAR2(1);
180      ln_resource_status            INTEGER;
181      ls_lockhandle                 VARCHAR2(128);
182      ln_cursor                     INTEGER;
183      ln_dummy                      INTEGER;
184    BEGIN
185      dbms_lock.allocate_unique (
186        lockname    => gs_lockhandle_name_c
187      , lockhandle  => ls_lockhandle
188      );
189 
190      -- requesting lock
191      ln_resource_status := dbms_lock.request (
192                              lockhandle        => ls_lockhandle
193                            , lockmode          => dbms_lock.x_mode
194                            , timeout           => gn_timeout_c
195                            , release_on_commit => FALSE
196      );
197      IF (ln_resource_status <> 0)
198      THEN
199        RAISE_APPLICATION_ERROR(-20001, ls_name_c || ': could not get the lock: ' || ln_resource_status);
200      END IF;
201 
202      BEGIN
203        IF (ab_long_stmt_i)
204        THEN
205          ln_cursor := dbms_sql.open_cursor;
206          dbms_sql.parse(c => ln_cursor, statement => ga_stmt
207                        , lb => 1, ub => ga_stmt.COUNT
208                        , lfflg => FALSE, language_flag => dbms_sql.native
209          );
210          ln_dummy := dbms_sql.execute(ln_cursor);
211          dbms_sql.close_cursor(ln_cursor);
212          ga_stmt.DELETE;
213        ELSE
214          EXECUTE IMMEDIATE as_stmt_i;
215        END IF;
216      EXCEPTION
217        WHEN OTHERS
218        THEN
219             ln_resource_status := dbms_lock.release(lockhandle => ls_lockhandle);
220             ga_stmt.DELETE;
221             RAISE;
222      END;
223 
224      ln_resource_status := dbms_lock.release(lockhandle => ls_lockhandle);
225      IF (ln_resource_status <> 0)
226      THEN
227        RAISE_APPLICATION_ERROR(-20002, ls_name_c || ': could not release the lock: ' || ln_resource_status);
228      END IF;
229    END mv_ddl;
230 
231    PROCEDURE alter_mv (
232      as_mview_name_i               VARCHAR2
233    , as_stmt_i                     VARCHAR2
234    )
235    IS
236    BEGIN
237      mv_ddl(as_mview_name_i, as_stmt_i);
238    END alter_mv;
239 
240    PROCEDURE drop_mv (
241      as_mview_name_i               VARCHAR2
242    , as_stmt_i                     VARCHAR2
243    )
244    IS
245    BEGIN
246      mv_ddl(as_mview_name_i, as_stmt_i);
247    END drop_mv;
248 
249    --
250    -- This procedure allows really long statements to be
251    -- executed by preparing ga_stmt before dbms_sql.parse()
252    -- is called in other procedures.
253    --
254    -- If the calling program needs to call this procedure
255    -- several times to pass a single statement, make sure
256    -- that ab_execute_i is set to FALSE for all calls except
257    -- for the last one where it should be set to TRUE.
258    --
259    PROCEDURE do_mv_ddl (
260      an_operation_i                PLS_INTEGER
261    , as_mview_name_i               VARCHAR2
262    , as_stmt_i                     VARCHAR2
263    , ab_execute_i                  BOOLEAN DEFAULT NULL
264    )
265    IS
266      l_chunk                       VARCHAR2(256);
267      l_index                       INTEGER := 1;
268      l_pointer                     INTEGER;
269    BEGIN
270      IF (an_operation_i NOT IN (ad_mv.mv_create, ad_mv.mv_alter, ad_mv.mv_drop))
271      THEN
272        RAISE_APPLICATION_ERROR(-20003, 'do_mv_ddl: unsupported operation');
273      END IF;
274      IF (ab_execute_i IS NOT NULL)
275      THEN
276        l_pointer := NVL(ga_stmt.COUNT + 1, 1);
277        LOOP
278          l_chunk := SUBSTR(as_stmt_i, l_index, 256);
279          EXIT WHEN l_chunk IS NULL;
280          ga_stmt(l_pointer) := l_chunk;
281          l_pointer := l_pointer + 1;
282          l_index := l_index + 256;
283        END LOOP;
284      END IF;
285      IF (ab_execute_i IS NULL OR ab_execute_i)
286      THEN
287        IF (an_operation_i = ad_mv.mv_create)
288        THEN
289          create_mv(as_mview_name_i, as_stmt_i, ab_execute_i);
290        ELSIF (an_operation_i IN (ad_mv.mv_alter, ad_mv.mv_drop))
291        THEN
292          mv_ddl(as_mview_name_i, as_stmt_i, ab_execute_i);
293        END IF;
294      END IF;
295    END do_mv_ddl;
296 
297    -- Bug 3562360: sallamse
298    -- Created wraper procedure as Java JDBC driver does not support
299    -- passing boolean parameters in PL/SQL Stored Procedures.
300    --
301    -- If the calling program needs to call this procedure
302    -- several times to pass a single statement, make sure
303    -- that ab_execute_i is set to 0 for all calls except
304    -- for the last one where it should be set to 1.
305    --
306    PROCEDURE do_mv_ddl2 (
307      an_operation_i                PLS_INTEGER
308    , as_mview_name_i               VARCHAR2
309    , as_stmt_i                     VARCHAR2
310    , ab_execute_i                  INTEGER DEFAULT NULL
311    )
312    IS
313    BEGIN
314      IF (ab_execute_i IS NULL)
315      THEN
316        do_mv_ddl(an_operation_i, as_mview_name_i, as_stmt_i);
317      ELSIF (ab_execute_i=1) THEN
318        do_mv_ddl(an_operation_i, as_mview_name_i, as_stmt_i, TRUE);
319      ELSE
320        do_mv_ddl(an_operation_i, as_mview_name_i, as_stmt_i, FALSE);
321      END IF;
322    END do_mv_ddl2;
323 
324 BEGIN
325   dbms_utility.db_version(ls_version, ls_compatibility);
326   IF (TO_NUMBER(TRANSLATE(SUBSTR(ls_version, 1, 5), '@.', '@')) BETWEEN
327     gn_limit_min_c AND gn_limit_max_c)
328   THEN
329     EXECUTE IMMEDIATE 'ALTER SESSION SET "_mv_refresh_selections"=TRUE';
330   END IF;
331   ad_tspace_util.get_tablespace_name('BIS','SUMMARY','Y',check_tspace_exist,g_mv_data_tablespace);
332   g_mv_index_tablespace := g_mv_data_tablespace;
333 END ad_mv;