DBA Data[Home] [Help]

PACKAGE BODY: APPS.AMS_DISCOVERER_PVT

Source


1 Package Body AMS_DISCOVERER_PVT AS
2 /* $Header: amsvdisb.pls 120.1 2005/12/15 17:48:58 musman noship $ */
3 
4 /*==========================================================================+
5  | PROCEDURES.                                                              |
6  |    Create_Discoverer_Url.                                                |
7  |    get_source_type_code                                                  |
8  |    EUL_TRIGGER$POST_SAVE_DOCUMENT                                        |
9  |    Search_SQL_string                                                     |
10  +==========================================================================*/
11 
12  g_pkg_name      CONSTANT VARCHAR2(30):='AMS_DISCOVERER_PVT';
13  g_file_name     CONSTANT VARCHAR2(12):='amsvdisb.pls';
14 
15 
16 --
17 -- Foreward Procedure Declarations
18 --
19 AMS_DEBUG_HIGH_ON CONSTANT BOOLEAN := FND_MSG_PUB.CHECK_MSG_LEVEL(FND_MSG_PUB.G_MSG_LVL_DEBUG_HIGH);
20 AMS_DEBUG_LOW_ON CONSTANT BOOLEAN := FND_MSG_PUB.CHECK_MSG_LEVEL(FND_MSG_PUB.G_MSG_LVL_DEBUG_LOW);
21 AMS_DEBUG_MEDIUM_ON CONSTANT BOOLEAN := FND_MSG_PUB.CHECK_MSG_LEVEL(FND_MSG_PUB.G_MSG_LVL_DEBUG_MEDIUM);
22 
23 PROCEDURE get_source_type_code (
24    p_workbook_name   IN VARCHAR2,
25    p_worksheet_name  IN VARCHAR2,
26    x_source_type_code   OUT NOCOPY VARCHAR2
27 );
28 
29 
30 --
31 -- Procedure Bodies
32 --
33 
34 -----------------------------------------------------------------------------
35 -- Procedure
36 --   Create_Discoverer_Url
37 
38 -- PURPOSE
39 --   Creates a URL which will launch Web Discoverer.
40 --
41 -- PARAMETERS
42 
43 -- NOTES
44 -- created yxliu 14-Mar-2001
45 -----------------------------------------------------------------------------
46 PROCEDURE Create_Discoverer_Url(p_text              IN VARCHAR2,
47                                 p_application_id    IN NUMBER,
48                                 p_responsibility_id IN NUMBER,
49                                 p_function_id       IN NUMBER,
50                                 p_target            IN VARCHAR2,
51                                 p_session_id        IN NUMBER,
52                                 x_discoverer_url    OUT NOCOPY VARCHAR2
53                                )
54 IS
55    l_api_name    CONSTANT VARCHAR2(30) := 'Create_Discoverer_Url';
56    l_full_name   CONSTANT VARCHAR2(60) := g_pkg_name ||'.'|| l_api_name;
57 
58 
59 BEGIN
60 
61    IF (AMS_DEBUG_HIGH_ON) THEN
62 
63 
64 
65    AMS_Utility_PVT.debug_message(l_full_name||': start');
66 
67    END IF;
68 
69 /*
70 vbhandar commented to fix  bug 2665683
71    x_discoverer_url := ORACLEAPPS.CREATERFLINK(
72                  p_text              => p_text
73                 ,p_application_id    => p_application_id
74                 ,p_responsibility_id => p_responsibility_id
75                 ,p_security_group_id => 0
76                 ,p_function_id       => p_function_id
77                 ,p_target            => p_target
78                 ,p_session_id        => p_session_id);
79 */
80    x_discoverer_url := ICX_SEC.CREATERFURL (
81                            p_function_name      => null,
82                            p_function_id        => p_function_id,
83                            p_application_id     => p_application_id,
84                            p_responsibility_id  => p_responsibility_id,
85                            p_security_group_id  => 0,
86                            p_session_id         => p_session_id
87                        );
88 
89 
90    IF (AMS_DEBUG_HIGH_ON) THEN
91 
92 
93 
94 
95 
96    AMS_Utility_PVT.debug_message(l_full_name||': end');
97 
98 
99    END IF;
100 
101 END;
102 
103 -----------------------------------------------------------------------------
104 -- Function
105 --  EUL_TRIGGER$POST_SAVE_DOCUMENT
106 
107 -- PURPOSE
108 --   1. This Function is used by Oracle Discoverer to save a WorkSheets SQL
109 --      to The AMS_DISCOVERER_SQL table.
110 
111 --   2. This Function must be Registered as a valid Function using Oracle
112 --      Discoverer's Administration Edition before any WorkBook SQL will be
113 --      saved.
114 
115 -- NOTES
116 --    choang - 24-jun-2002 - new logic for post save document
117 --       - get source_type_code for workbook/worksheet
118 --       - if source_type_code exists, use source_type_code for current record
119 --       - else merge sql for workbook/worksheet
120 --       - search for source_type_code in merged sql
121 --       - if source_type_code exists, update all records for workbook/worksheet
122 --       - else continue
123 --
124 -- HISTORY
125 -- 13-Apr-2001 yxliu    copied from AMS_DiscovererSQL_PVT
126 -- 24-Jun-2002 choang   added logic to populate source_type_code
127 --
128 -- End of Comments
129 -----------------------------------------------------------------------------
130 FUNCTION  EUL_TRIGGER$POST_SAVE_DOCUMENT (
131    p_workbookowner IN VARCHAR2,
132    p_workbookname  IN VARCHAR2,
133    p_worksheetname IN VARCHAR2,
134    p_sequence      IN NUMBER,
135    p_sqlsegment    IN VARCHAR2
136 )
137 RETURN NUMBER
138 IS
139 
140    l_max_sequence_number number;
141 
142     -- Declare program variables
143     l_sqlerrm varchar2(600);
144     l_sqlcode varchar2(100);
145 
146    CURSOR c_get_seq IS
147       SELECT ams_discoverer_sql_s.NEXTVAL
148       FROM DUAL;
149 
150    l_discoverer_sql_id     NUMBER;
151 
152    -- choang - 24-jun-2002
153    -- get the start id for this workbook+worksheet
154    -- get the largest sequence_order and source_type_code
155    -- to determine if the requested worksheet is a replacement
156    -- or a continuation, and if source type code is defined
157    CURSOR c_disco (p_workbook_name IN VARCHAR2, p_worksheet_name IN VARCHAR2) IS
158       SELECT MIN (discoverer_sql_id), MAX (sequence_order), MAX (source_type_code)
159       FROM   ams_discoverer_sql
160       WHERE  workbook_name = p_workbook_name
161       AND    worksheet_name = p_worksheet_name
162       ;
163 
164    l_source_type_code      ams_discoverer_sql.source_type_code%TYPE;
165 BEGIN
166    OPEN c_disco (p_workbookname, p_worksheetname);
167    FETCH c_disco INTO l_discoverer_sql_id, l_max_sequence_number, l_source_type_code;
168    CLOSE c_disco;
169 
170 /* choang - 24-jun-2002 - replaced with new logic
171      --checking for an existing set of entries for this workbook and worksheet combination.
172      select max(sequence_order)
173      into   l_max_sequence_number
174      from   ams_discoverer_sql
175      where  workbook_name  = P_WorkBookName
176      and    WORKSHEET_NAME = P_WorkSheetName;
177 */
178 
179 /* choang - 24-jun-2002 - replaced to use one cursor for performance
180      -- checking the start discoverer_sql_id for this workbook and worksheet
181      -- combination
182      select min(discoverer_sql_id)
183      into l_start_id
184      from ams_discoverer_sql
185      where workbook_name = P_WorkBookName
186        and worksheet_name = P_WorkSheetName;
187 */
188 
189    --if the workbook and worksheet combination exists in the AMS_DISCOVERER_SQL table
190    --then delete all entries , then we can insert the new records for the newest version
191    --of this workbook - worksheet.
192    IF ((l_max_sequence_number >= p_sequence) OR (l_max_sequence_number = 0)) THEN
193       DELETE FROM ams_discoverer_sql
194       WHERE  workbook_name  = p_workbookname
195       AND    WORKSHEET_NAME = p_worksheetname;
196    END IF;
197 
198    -- start new logic to update source type code
199 
200    -- if updating the same workbook + worksheet, we
201    -- need to preserve the disco sql id which is
202    -- associated to marketing objects.  the logic:
203    --    - new worksheet = p_sequence in 0,1 and disco sql id is null
204    --    - updated worksheet = p_sequence in 0,1 and disco sql id not null
205    --    - wrapped long sql = p_sequence > 1
206    IF p_sequence IN (0, 1) THEN
207       IF l_discoverer_sql_id IS NULL THEN
208          OPEN c_get_seq;
209          FETCH c_get_seq INTO l_discoverer_sql_id;
210          CLOSE c_get_seq;
211       END IF;
212    ELSE
213       OPEN c_get_seq;
214       FETCH c_get_seq INTO l_discoverer_sql_id;
215       CLOSE c_get_seq;
216    END IF;
217 
218    INSERT INTO ams_discoverer_sql (
219       discoverer_sql_id,
220       workbook_owner_name,
221       workbook_name,
222       worksheet_name,
223       sequence_order,
224       last_update_date,
225       last_updated_by,
226       creation_date,
227       created_by,
228       sql_string,
229       source_type_code
230    )
231    VALUES (
232       l_discoverer_sql_id,
233       p_workbookowner,
234       p_workbookname,
235       p_worksheetname,
236       p_sequence,
237       SYSDATE,
238       FND_GLOBAL.user_id,
239       SYSDATE,
240       FND_GLOBAL.user_id,
241       p_sqlsegment,
242       l_source_type_code
243   );
244 
245    -- update needed when SQL spans multiple
246    -- segments.
247    get_source_type_code (
248       p_workbook_name   => p_workbookname,
249       p_worksheet_name  => p_worksheetname,
250       x_source_type_code   => l_source_type_code
251    );
252 
253    IF l_source_type_code IS NOT NULL THEN
254       UPDATE ams_discoverer_sql
255       SET source_type_code = l_source_type_code
256       WHERE workbook_name = p_workbookname
257       AND   worksheet_name = p_worksheetname
258       AND   (source_type_code <> l_source_type_code OR source_type_code IS NULL)
259       ;
260    END IF;
261 
262    RETURN (0);
263 
264 EXCEPTION
265    WHEN OTHERS THEN
266      l_sqlerrm := SQLERRM;
267      l_sqlcode := SQLCODE;
268      RETURN (1);
269 END EUL_TRIGGER$POST_SAVE_DOCUMENT;
270 
271 -----------------------------------------------------------------------------
272 -- Procedure
273 -- Search_SQL_string
274 
275 -- PURPOSE
276 --    1. Will search for the p_search_string variable in the set of strings
277 --       which compose a workbook SQL statement and are stored in the
278 --       AMS_DISCOVERER_SQL table.
279 
280 --    2. p_found will return FND_API.G_TRUE if the string has been found.
281 
282 --    3. p_found_in_str returns the number of the sql string in which the search
283 --       string was found. each SQL string is 2000 characters in length.
284 
285 --    4. p_position returns the position in the string where the first character
286 --       in the search string was found.
287 
288 --    5. p_overflow wil return the number of characters which contain part of
289 --       the search string in the overflow string if the searched for string
290 --       spans two SQL strings.
291 
292 --    6. p_max_search_len restricts the number of characters to search on from
293 --       the set of sql strings.
294 
295 -- NOTES
296 
297 -- HISTORY
298 --   04/13/2001        yxliu            copied from AMS_DiscovererSQL_PVT
299 -- End of Comments
300 -----------------------------------------------------------------------------
301 Procedure Search_SQL_string(p_search_string  in  varchar2,
302                             p_workbook_name  in  varchar2,
303                             p_worksheet_name in  varchar2,
304                             p_max_search_len in  number default NULL,
305                             x_found          out nocopy varchar2 ,
306                             x_found_in_str   out nocopy number,
307                             x_position       out nocopy number,
308                             x_overflow       out nocopy number)
309 IS
310 
311   l_sql_table t_SQLtable;
312 
313   --the total number of strings for a sql statement.
314   l_str_count      number      := 0;
315 
316   --the current search position in the string.
317   l_str_pos        number      := 0;
318 
319   --the length of the current sql string.
320   l_str_len        number      := 0;
321 
322   --the total number of characters read from the set of sql strings so far.
323   l_total_str_len  number      := 0;
324 
325   --this flag indicates that no more fetched of sql strings are to be made
326   --because the max. number of characters have been read.
327   l_last_fetch     varchar2(1);
328 
329   --this flag is set to 'Y' when processing on the last sql string has started.
330   l_last_str       varchar2(1) := 'N';
331 
332   --temporary substring holder used if a p_max_search_len has been reached.
333   l_tmp_str        varchar2(2000);
334 
335   --if a sub string has to be constructed because of overflow into a second
336   --string then it is stored in this variable.
337   l_substr         varchar2(1000);
338 
339   --the length of the sub string.
340   l_substr_len     number       := 0;
341 
342   --set to FND_API.G_TRUE when the first character of the searched for string
343   --has been found.
344   l_first_char_found     varchar2(1);
345 
346 
347   --the first character being searched for.
348   l_first_char     varchar2(1);
349 
350   --the position that the first character was found in the current sql string.
351   l_first_char_pos number       := 0;
352 
353   --the length of the string being searched for.
354   l_search_str_len number       := 0;
355 
356   --the search string without its first character.
357   l_search_sub_str varchar2(2000);
358 
359 
360 
361   l_sqlerrm varchar2(600);
362   l_sqlcode varchar2(100);
363 
364   Cursor C_SQL_string IS
365   Select  Sql_String
366     From  Ams_Discoverer_SQL
367    Where  Workbook_name       = p_workbook_name
368      And  Worksheet_name      = p_worksheet_name
369    Order by Sequence_Order;
370 
371 Begin
372 
373    l_first_char     := substr(p_search_string,1,1);
374    l_search_str_len := length(p_search_string);
375    l_search_sub_str := substr(p_search_string,2,l_search_str_len);
376 
377 
378    x_found := FND_API.G_FALSE;
379 
380    --getting the total number of strings that compose the sql statement.
381    Select   Count(*)
382    into     l_str_count
383    From     ams_discoverer_sql
384    Where    Workbook_name       = p_workbook_name
385    And      Worksheet_name      = p_worksheet_name;
386 
387    if (l_str_count = 0) then
388        x_found := FND_API.G_FALSE;
389        --dbms_output.put_line('search sql str : could not find workbook SQL  = '||to_char(l_str_count));
390        RETURN;
391    end if;
392 
393 
394    --Getting the SQL strings.
395    Open C_SQL_string;
399 
396 
397    --starting from Zero because the sequence in which the strings are stored
398    --start from Zero.
400 
401    <<l_fetch_string>>
402    For l_iterator in 0 .. (l_str_count - 1) Loop
403 
404       --dbms_output.put_line('search sql str : fetch string iteration '||to_char(l_iterator + 1));
405 
406       --Fetching the next string for the discoverer workbook.
407       Fetch C_SQL_string into l_sql_table(l_iterator + 1);
408 
409       --initializing the current search position for the string.
410       l_str_pos := 0;
411 
412       --checking for the last string.
413       if ( l_iterator = (l_str_count -1) )then
414          --dbms_output.put_line('search sql str :  last string detected ');
415          l_last_str := 'Y';
416       end if;
417 
418       --getting the length of the current sql string.
419       l_str_len :=  Length(l_sql_table(l_iterator + 1));
420       --dbms_output.put_line('search sql str : length of current sql string = '||to_char(l_str_len));
421 
422       --updating the total number of characters read from the set of sql strings.
423       l_total_str_len := l_total_str_len + l_str_len;
424 
425       --dbms_output.put_line('search sql str : total number of chars read = '||to_char(l_total_str_len));
426 
427       --if the max. number of characters have been read then set this flag to
428       --break out of the fetch string loop.
429       if (l_total_str_len >= p_max_search_len) then
430 
431          --dbms_output.put_line('search sql str : max num of characters have been read');
432 
433          l_last_fetch := FND_API.G_TRUE;
434           l_tmp_str    := substr(l_sql_table(l_iterator + 1),1,p_max_search_len - 1);
435 
436          --dbms_output.put_line('search sql str : l_tmp_str ='||l_tmp_str);
437 
438          l_sql_table(l_iterator + 1) := NULL;
439          l_sql_table(l_iterator + 1) := l_tmp_str;
440 
441       end if;
442 
443       --If First character of search string has been found in the previous string
444       --but the remainder of previous string is too short to contain the rest of
445       --the search string.
446       if (l_first_char_found  = FND_API.G_TRUE) then
447          --getting the substring length.
448          l_substr_len :=  length(l_substr);
449          --dbms_output.put_line('search sql str : overflow detected, length of sub string = '||to_char(l_substr_len));
450 
451          --concatenating the substring and the necessary number of characters in
452          --the current string to search for search string minus the first
453          --character of it.
454 
455          --dbms_output.put_line('search sql str : overflow match string  ='||l_substr||substr(x_sql_table(l_iterator + 1),1,(l_search_str_len-1)-l_substr_len));
456 
457          if ( l_substr||substr(l_sql_table(l_iterator + 1),1,((l_search_str_len-1)-nvl(l_substr_len,0)) ) = l_search_sub_str) then
458             --dbms_output.put_line('search sql str : sucessful match after overflow');
459 
460             x_found         := FND_API.G_TRUE;
461             x_overflow      := (l_search_str_len-1)- l_substr_len;
462 
463             --dbms_output.put_line('search sql str : overflow length = '||to_char(x_overflow));
464 
465             exit l_fetch_string;
466          else
467 
468             x_found         := FND_API.G_FALSE;
469             --calculating the new search position.
470             l_str_pos :=  l_str_pos + 1;
471 
472             --dbms_output.put_line('search sql str : unsucessful match after overflow, new string position ='||to_char(l_str_pos ));
473 
474          end if;
475       end if;
476 
477 
478       --Loop through the current sql string searching for  l_first_char,
479       --If this is  found then check that the next length(l_search_sub_str - 1)
480       --characters are part of the search string.
481 
482       --If when l_first_char is found there are not enough characters to perform
483       --a match, copy the remaining characters into l_sub_str, read the next
484       --string(this is done before this loop,
485       --after the string is fetched) and then perform a check for a match.
486 
487       --If l_first_char is not found then read in the next string and continue
488       --searching.
489 
490       <<l_search_string>>
491       Loop
492 
493          --dbms_output.put_line('search sql str : looping through current sql string searching for first char');
494 
495          --getting the position of l_first_char in the current string.
496          l_first_char_pos := Instr(l_sql_table(l_iterator + 1),l_first_char,l_str_pos+1);
497 
498          --the first character of the search string has been found.
499          if ( l_first_char_pos <> 0 ) then
500 
501             --dbms_output.put_line('search sql str :  getting the position of l_first_char in the current string, found position ='||to_char(l_first_char_pos ));
502             --setting current position in sql string.
503             l_str_pos := l_first_char_pos;
504 
505             --indicating that the first character of the searched for string has been found.
506             l_first_char_found := FND_API.G_TRUE;
507 
508 
509             if (l_str_count = 1) then
510                x_found_in_str := l_iterator;
511             else
512                x_found_in_str := l_iterator + 1;
513             end if;
514 
518 
515             --dbms_output.put_line('search sql str : first char found in sql string number '||to_char(x_found_in_str));
516 
517             x_position     := l_first_char_pos;
519             if (l_search_str_len = 1 ) then
520                --dbms_output.put_line('search sql str : Match has been found');
521                x_found := FND_API.G_TRUE;
522                exit       l_search_string;
523             --there are enough characters left in the current string to find a match.
524             elsif ( (l_str_len - (l_str_pos + 1)) >= (l_search_str_len - 1) )then
525 
526                --dbms_output.put_line('search sql str : enough remaining chars in current string to perform match');
527 
528                l_substr := substr(l_sql_table(l_iterator + 1),l_str_pos + 1,l_search_str_len - 1);
529                --dbms_output.put_line('search sql str : Sub string = '||l_substr);
530 
531 
532                --match has been found.
533                if ( l_substr = l_search_sub_str ) then
534 
535                   --dbms_output.put_line('search sql str : Match has been found');
536                   x_found := FND_API.G_TRUE;
537              exit       l_search_string;
538 
539                --no match found, update string search position.
540                else
541                   --dbms_output.put_line('search sql str : Match has not been found');
542                   x_found := FND_API.G_FALSE;
543                   l_str_pos    := l_str_pos + 1;
544                end if;
545 
546                --not enough characters remaining in current sql string to perform a match.
547                --creating a sub string of the remaining characters, which are used with
548                --the next string fetched to perform a check.
549             elsif ((l_str_len - l_str_pos) < (l_search_str_len-1)) then
550                --dbms_output.put_line('search sql str : Not enough chars remaining to perform check');
551                l_substr := substr(l_sql_table(l_iterator + 1),l_str_pos + 1,l_str_len) ;
552 
553                --dbms_output.put_line('search sql str : sub string created = '||l_substr);
554                --exit the search string loop and fetch another sql string.
555                exit       l_search_string;
556             end if;
557 
558          else
559             --dbms_output.put_line('search sql str : first char not found in current sql string');
560             --l_first_char has not been been found in the current string.
561 
562 
563             --indicating that the first character of the searched for string has not been found.
564             l_first_char_found := FND_API.G_FALSE;
565 
566             --indicating that the search string has not been found;
567             x_found := FND_API.G_FALSE;
568 
569             --exit the search string loop and fetch another sql string.
570             exit l_search_string;
571          end if;
572 
573 
574       End Loop l_search_string;--Searching the current strings.
575       --dbms_output.put_line('search sql str : exiting search string loop');
576 
577       --the string has been found , no need to fetch any more sql strings.
578       --OR the max. number of characters have been read.
579       If (x_found = FND_API.G_TRUE or l_last_fetch = FND_API.G_TRUE ) then
580          exit l_fetch_string;
581       end If;
582 
583    End Loop l_fetch_string;--Fetching the SQL strings.
584    --dbms_output.put_line('search sql str : exiting fetch string loop');
585    Close C_SQL_string;
586 
587 EXCEPTION
588 WHEN OTHERS THEN
589 
590    if (c_sql_string%ISOPEN) then
591       Close C_SQL_string;
592    end if;
593 
594    l_sqlerrm := SQLERRM;
595    l_sqlcode := SQLCODE;
596    --dbms_output.put_line('Search SQL string:'||l_sqlerrm||l_sqlcode);
597 
598 End Search_SQL_string;
599 
600 -----------------------------------------------------------------------------
601 -- Function
602 --  Encrypt_Param
603 
604 -- PURPOSE
605 --   1. This Function is used by the middle tier java class to get encryption
606 --      of parameters that need to be passed to form function
607 
608 -- NOTES
609 
610 -- HISTORY
611 --   05/03/2001        yxliu            created
612 -- End of Comments
613 -----------------------------------------------------------------------------
614 Function Encrypt_Param
615   ( P_params        IN varchar2,
616     P_session_id    IN NUMBER)
617 RETURN varchar2
618 
619 IS
620 
621 BEGIN
622    RETURN icx_call.encrypt2(P_params, P_session_id);
623 
624 END Encrypt_Param;
625 
626 
627 --
628 -- NOTE
629 --    Need to
630 PROCEDURE get_source_type_code (
631    p_workbook_name   IN VARCHAR2,
632    p_worksheet_name  IN VARCHAR2,
633    x_source_type_code   OUT NOCOPY VARCHAR2
634 )
635 IS
636    -- by musman bug:4655422:fix start
637    l_source_type_code   ams_discoverer_sql.source_type_code%TYPE; --VARCHAR2(30);
638    l_search_code        VARCHAR2(50);-- VARCHAR2(30);
639    --end
640 
641    -- variables used to call search_sql_string
642    l_found              VARCHAR2(1);
643    l_found_in_str       NUMBER;
644    l_position           NUMBER;
645    l_overflow           NUMBER;
646 
647    CURSOR c_master_types IS
651       AND    enabled_flag = 'Y'
648       SELECT source_type_code
649       FROM   ams_list_src_types
650       WHERE  master_source_type_flag = 'Y'
652       and list_source_type = 'TARGET'    -- by musman bug:4655422:fix
653       order by list_source_type_id ;   -- by musman bug:4655422:fix
654 BEGIN
655    OPEN c_master_types;
656    LOOP
657       l_source_type_code := NULL;
658 
659       FETCH c_master_types INTO l_source_type_code;
660 
661       -- Need to encapsulate the source type code
662       -- with single quotes because the saved
663       -- SQL has the search string within quotes.
664       -- Without the quotes, any string with the
665       -- searched string will return regardless if it
666       -- is designated as the source type code.
667       l_search_code := '''' || l_source_type_code || '''';
668 
669       search_sql_string (
670          p_search_string      => l_search_code,
671          p_workbook_name      => p_workbook_name,
672          p_worksheet_name     => p_worksheet_name,
673          x_found              => l_found,
674          x_found_in_str       => l_found_in_str,
675          x_position           => l_position,
676          x_overflow           => l_overflow
677       );
678 
679       EXIT WHEN c_master_types%NOTFOUND OR l_found = FND_API.G_TRUE;
680    END LOOP;
681    CLOSE c_master_types;
682 
683    x_source_type_code := l_source_type_code;
684 
685 EXCEPTION
686   WHEN OTHERS THEN
687 
688    if (c_master_types%ISOPEN) then
689       Close c_master_types;
690    end if;
691 
692 END get_source_type_code;
693 
694 
695 --
696 -- Note
697 -- ======
698 -- 2 main scenarios in the processing flow: 1) all the fragments concatenated
699 -- are not longer than 32k (max PL/SQL string), so instr has to be done to only
700 -- that one str.  2) all the fragments would concatenate to a string longer than
701 -- 32k, so the instr has to be done in batches with a size no bigger than 32k
702 -- at a time.
703 Procedure batch_search_sql (
704    p_workbook_name   in  varchar2,
705    p_worksheet_name  in  varchar2,
706    p_source_type_code_tab  IN source_type_code_type,
707    x_found_index     OUT NOCOPY VARCHAR2
708 )
709 IS
710    MAX_FRAGMENTS     CONSTANT NUMBER := 8;   -- each SQL fragment is 4k, so the string can only be up to 32k
711 
712    TYPE sql_string_type IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
713    l_sql_string_tab  sql_string_type;
714 
715    l_str       VARCHAR2(32767);
716 
717    l_last_str     VARCHAR2(4000);
718    l_end_offset   NUMBER := MAX_FRAGMENTS;
719 
720    CURSOR c_sql_string IS
721       SELECT  sql_string
722       FROM  ams_discoverer_sql
723       WHERE workbook_name       = p_workbook_name
724       AND   worksheet_name      = p_worksheet_name
725       ORDER BY sequence_order;
726 BEGIN
727    x_found_index := 0;
728 
729    OPEN c_sql_string;
730    FETCH c_sql_string BULK COLLECT INTO l_sql_string_tab;
731    CLOSE c_sql_string;
732 
733    IF l_sql_string_tab.COUNT > MAX_FRAGMENTS THEN
734       --
735       -- Logic
736       -- =========
737       -- Build a string up to 32k length (max for PL/SQL
738       -- strings).  Look for code in the string, and if
739       -- not found, build another 32k string but start
740       -- with the last fragment of the previous string.
741       FOR j IN 1 .. l_sql_string_tab.COUNT LOOP
742          IF j > l_end_offset THEN
743             l_str := l_last_str;
744             l_end_offset := (j - 1) + MAX_FRAGMENTS;
745          ELSE
746             l_str := l_str || l_sql_string_tab(j);
747             IF j = l_end_offset THEN
748                l_last_str := l_sql_string_tab(j);
749             END IF;
750          END IF;
751 
752          IF j = l_end_offset OR j = l_sql_string_tab.COUNT THEN
753             --
754             -- Logic
755             -- =======
756             -- Constructing the strings is expensive, so we don't
757             -- want to keep re-doing it.  For every string, check
758             -- all the codes for a match.
759             FOR i IN 1 .. p_source_type_code_tab.COUNT LOOP
760                IF INSTR (l_str, '''' || p_source_type_code_tab(i) || '''') <> 0 THEN
761                   x_found_index := i;
762                   RETURN;
763                END IF;
764             END LOOP;
765          END IF;
766       END LOOP;
767    ELSE
768       -- construct a single string out of all the sql fragments
769       FOR i IN 1 .. l_sql_string_tab.COUNT LOOP
770          l_str := l_str || l_sql_string_tab(i);
771       END LOOP;
772 
773       FOR i IN 1 .. p_source_type_code_tab.COUNT LOOP
774          IF INSTR (l_str, '''' || p_source_type_code_tab(i) || '''') <> 0 THEN
775             x_found_index := i;
776             RETURN;
777          END IF;
778       END LOOP;
779    END IF;
780 
781 
782 END;
783 
784 END AMS_DISCOVERER_PVT;