DBA Data[Home] [Help]

PACKAGE BODY: APPS.AMS_DISCOVERERSQL_PVT

Source


1 PACKAGE BODY AMS_DiscovererSQL_PVT AS
2 /* $Header: amsvldcb.pls 115.13 2003/03/09 10:17:50 gjoby ship $ */
3 G_PKG_NAME      CONSTANT VARCHAR2(30):='AMS_DiscovererSQL_PVT';
4 G_FILE_NAME     CONSTANT VARCHAR2(12):='amsvldcb.pls';
5 AMS_DEBUG_HIGH_ON boolean := FND_MSG_PUB.CHECK_MSG_LEVEL(FND_MSG_PUB.G_MSG_LVL_DEBUG_HIGH);
6 AMS_DEBUG_LOW_ON boolean := FND_MSG_PUB.CHECK_MSG_LEVEL(FND_MSG_PUB.G_MSG_LVL_DEBUG_LOW);
7 AMS_DEBUG_MEDIUM_ON boolean := FND_MSG_PUB.CHECK_MSG_LEVEL(FND_MSG_PUB.G_MSG_LVL_DEBUG_MEDIUM);
8 
9 PROCEDURE get_source_type_code (
10    p_workbook_name   IN VARCHAR2,
11    p_worksheet_name  IN VARCHAR2,
12    x_source_type_code   OUT NOCOPY VARCHAR2
13 );
14 
15 -- Start of Comments
16 --
17 -- NAME
18 --  EUL_TRIGGER$POST_SAVE_DOCUMENT
19 --
20 -- PURPOSE
21 --   1. This Function if registered by discoverer will save any sql from any worksheet which has been
22 --      saved to the database into the AMS_DISCOVERER_SQL table.
23 
24 --   2. If the SQL string is under 2000 bytes in length then the sequence number will be Zero.
25 
26 --   3. If the SQL string is greater than 2000 bytes then the sequence number will start from One
27 --      and subsequenct insertions will have the sequence number incremented by one.
28 
29 --   4. A check is also performed to see if the same workbook name and worksheet name combination
30 --      already exists in the AMS_DISCOVERER_SQL table. If this is the case all entries for this
31 --      workbook and sheet will be deleted from the table first.
32 
33 
34 --   Called By:
35 --   Oracle Discoverer.
36 
37 
38 -- NOTES
39 --
40 --
41 -- HISTORY
42 --   06/21/1999        tdonohoe            created
43 --   01/15/2002        yxliu               changed logic
44 -- End of Comments
45 Function  EUL_TRIGGER$POST_SAVE_DOCUMENT
46   ( P_WorkBookOwner IN varchar2,
47     P_WorkBookName  IN varchar2,
48     P_WorkSheetName IN varchar2,
49     P_Sequence      IN number,
50     P_SQLSegment    IN varchar2)  RETURN  NUMBER IS
51 
52    l_max_sequence_number number;
53 
54     -- Declare program variables
55     l_sqlerrm varchar2(600);
56     l_sqlcode varchar2(100);
57 
58    CURSOR c_get_seq IS
59       SELECT ams_discoverer_sql_s.NEXTVAL
60       FROM DUAL;
61 
62    l_discoverer_sql_id     NUMBER;
63 
64    -- choang - 24-jun-2002
65    -- get the start id for this workbook+worksheet
66    -- get the largest sequence_order and source_type_code
67    -- to determine if the requested worksheet is a replacement
68    -- or a continuation, and if source type code is defined
69    CURSOR c_disco (p_workbook_name IN VARCHAR2, p_worksheet_name IN VARCHAR2) IS
70       SELECT MIN (discoverer_sql_id), MAX (sequence_order), MAX (source_type_code)
71       FROM   ams_discoverer_sql
72       WHERE  workbook_name = p_workbook_name
73       AND    worksheet_name = p_worksheet_name
74       ;
75 
76    l_source_type_code      ams_discoverer_sql.source_type_code%TYPE;
77 BEGIN
78    OPEN c_disco (p_workbookname, p_worksheetname);
79    FETCH c_disco INTO l_discoverer_sql_id, l_max_sequence_number, l_source_type_code;
80    CLOSE c_disco;
81 
82 /* choang - 24-jun-2002 - replaced with new logic
83      --checking for an existing set of entries for this workbook and worksheet combination.
84      select max(sequence_order)
85      into   l_max_sequence_number
86      from   ams_discoverer_sql
87      where  workbook_name  = P_WorkBookName
88      and    WORKSHEET_NAME = P_WorkSheetName;
89 */
90 
91 /* choang - 24-jun-2002 - replaced to use one cursor for performance
92      -- checking the start discoverer_sql_id for this workbook and worksheet
93      -- combination
94      select min(discoverer_sql_id)
95      into l_start_id
96      from ams_discoverer_sql
97      where workbook_name = P_WorkBookName
98        and worksheet_name = P_WorkSheetName;
99 */
100 
101    --if the workbook and worksheet combination exists in the AMS_DISCOVERER_SQL table
102    --then delete all entries , then we can insert the new records for the newest version
103    --of this workbook - worksheet.
104    IF ((l_max_sequence_number >= p_sequence) OR (l_max_sequence_number = 0)) THEN
105       DELETE FROM ams_discoverer_sql
106       WHERE  workbook_name  = p_workbookname
107       AND    WORKSHEET_NAME = p_worksheetname;
108    END IF;
109 
110    -- start new logic to update source type code
111 
112    -- if updating the same workbook + worksheet, we
113    -- need to preserve the disco sql id which is
114    -- associated to marketing objects.  the logic:
115    --    - new worksheet = p_sequence in 0,1 and disco sql id is null
116    --    - updated worksheet = p_sequence in 0,1 and disco sql id not null
117    --    - wrapped long sql = p_sequence > 1
118    IF p_sequence IN (0, 1) THEN
119       IF l_discoverer_sql_id IS NULL THEN
120          OPEN c_get_seq;
121          FETCH c_get_seq INTO l_discoverer_sql_id;
122          CLOSE c_get_seq;
123       END IF;
124    ELSE
125       OPEN c_get_seq;
126       FETCH c_get_seq INTO l_discoverer_sql_id;
127       CLOSE c_get_seq;
128    END IF;
129 
130    INSERT INTO ams_discoverer_sql (
131       discoverer_sql_id,
132       workbook_owner_name,
133       workbook_name,
134       worksheet_name,
135       sequence_order,
136       last_update_date,
137       last_updated_by,
138       creation_date,
139       created_by,
140       sql_string,
141       source_type_code
142    )
143    VALUES (
144       l_discoverer_sql_id,
145       p_workbookowner,
146       p_workbookname,
147       p_worksheetname,
148       p_sequence,
149       SYSDATE,
150       FND_GLOBAL.user_id,
151       SYSDATE,
152       FND_GLOBAL.user_id,
153       p_sqlsegment,
154       l_source_type_code
155   );
156 
157    -- update needed when SQL spans multiple
158    -- segments.
159    get_source_type_code (
160       p_workbook_name   => p_workbookname,
161       p_worksheet_name  => p_worksheetname,
162       x_source_type_code   => l_source_type_code
163    );
164 
165    IF l_source_type_code IS NOT NULL THEN
166       UPDATE ams_discoverer_sql
167       SET source_type_code = l_source_type_code
168       WHERE workbook_name = p_workbookname
169       AND   worksheet_name = p_worksheetname
170       AND   (source_type_code <> l_source_type_code OR source_type_code IS NULL)
171       ;
172    END IF;
173 
174    RETURN (0);
175 
176 EXCEPTION
177    WHEN OTHERS THEN
178      l_sqlerrm := SQLERRM;
179      l_sqlcode := SQLCODE;
180      RETURN (1);
181 END EUL_TRIGGER$POST_SAVE_DOCUMENT;
182 
183 -- Start of Comments
184 --
185 -- NAME
186 --   Search SQL string
187 --
188 -- PURPOSE
189 --    1. Will search for the p_search_string variable in the set of strings which compose a workbook
190 --       SQL statement and are stored in the AMS_DISCOVERER_SQL table.
191 
192 --    2. x_found will return FND_API.G_TRUE if the string has been found.
193 
194 --    3. x_found_in_str returns the number of the sql string in which the search string was found.
195 --       each SQL string is 2000 characters in length.
196 
197 --    4. p_position returns the position in the string where the first character in the search string
198 --       was found.
199 
200 --    5. x_overflow wil return the number of characters which contain part of the search string
201 --       in the  overflow string if the searched for string spans two SQL strings.
202 
203 --    6. p_max_search_len restricts the number of characters to search on from the set of sql strings.
204 
205 --    7. A pl\sql table is returned which contains all of the sql strings that have been processed for
206 --       the specified workbook.
207 
208 
209 -- HISTORY
210 --   06/28/1999 tdonohoe created
211 --   02/08/2000 tdonohoe modified increment variable "l_str_pos" by one position after each search.
212 --                                put nvl(l_str_len,0) , it was evaluating to NULL in some cases causing
213 --                                the search to fail.
214 -- End of Comments
215 
216 Procedure Search_SQL_string(p_search_string  in  varchar2,
217                             p_workbook_name  in  varchar2,
218                             p_worksheet_name in  varchar2,
219                             p_max_search_len in  number ,--default NULL,
220                             x_found          OUT NOCOPY varchar2 ,
221                             x_found_in_str   OUT NOCOPY number,
222                             x_position       OUT NOCOPY number,
223                             x_overflow       OUT NOCOPY number) IS
224 
225   l_sql_table t_SQLtable;
226 
227  --the total number of strings for a sql statement.
228   l_str_count      number :=0;
229 
230   --the current search position in the string.
231   l_str_pos        number      :=0;
232 
233   --the length of the current sql string.
234   l_str_len        number      :=0;
235 
236   --the total number of characters read from the set of sql strings so far.
237   l_total_str_len  number      :=0;
238 
239   --this flag indicates that no more fetched of sql strings are to be made
240   --because the max. number of characters have been read.
241   l_last_fetch     varchar2(1);
242 
243   --this flag is set to 'Y' when processing on the last sql string has started.
244   l_last_str       varchar2(1) := 'N';
245 
246   --temporary substring holder used if a p_max_search_len has been reached.
247   l_tmp_str        varchar2(2000);
248 
249   --if a sub string has to be constructed because of overflow into a second string then it
250   --is stored in this variable.
251   l_substr         varchar2(1000);
252 
253   --the length of the sub string.
254   l_substr_len     number :=0;
255 
256   --set to FND_API.G_TRUE when the first character of the searched for string has been found.
257   l_first_char_found     varchar2(1);
258 
259 
260   --the first character being searched for.
261   l_first_char     varchar2(1);
262 
263   --the position that the first character was found in the current sql string.
264   l_first_char_pos number :=0;
265 
266   --the length of the string being searched for.
267   l_search_str_len number :=0;
268 
269   --the search string without its first character.
270   l_search_sub_str varchar2(2000);
271 
272 
273 
274   l_sqlerrm varchar2(600);
275   l_sqlcode varchar2(100);
276 
277   Cursor C_SQL_string IS Select Sql_String
278                          From   Ams_Discoverer_SQL
279                          Where  Workbook_name       = p_workbook_name
280                          And    Worksheet_name      = p_worksheet_name
281                          Order by Sequence_Order;
282 
283 Begin
284 
285    l_first_char     := substr(p_search_string,1,1);
286    l_search_str_len := length(p_search_string);
287    l_search_sub_str := substr(p_search_string,2,l_search_str_len);
288 
289 
290    x_found := FND_API.G_FALSE;
291 
292    --getting the total number of strings that compose the sql statement.
293    Select   Count(*)
294    into     l_str_count
295    From     ams_discoverer_sql
296    Where    Workbook_name       = p_workbook_name
297    And      Worksheet_name      = p_worksheet_name;
298 
299    if(l_str_count = 0)then
300        x_found := FND_API.G_FALSE;
301        RETURN;
302    end if;
303 
304 
305    --Getting the SQL strings.
306 	   Open C_SQL_string;
307 
308 	   --starting from Zero because the sequence in which the strings are stored
309 	   --start from Zero.
310 
311 
312 	   <<l_fetch_string>>
313        For l_iterator in 0 .. (l_str_count - 1) Loop
314 
315 
316 	         --Fetching the next string for the discoverer workbook.
317 	         Fetch C_SQL_string into l_sql_table(l_iterator + 1);
318 
319 
320 
321 			 --initializing the current search position for the string.
322 			 l_str_pos := 0;
323 
324 			 --checking for the last string.
325 		     if( l_iterator = (l_str_count -1) )then
326 			       l_last_str := 'Y';
327 			 end if;
328 
329 			 --getting the length of the current sql string.
330 			 l_str_len :=  Length(l_sql_table(l_iterator + 1));
331 
332 			 --updating the total number of characters read from the set of sql strings.
333 			 l_total_str_len := l_total_str_len + l_str_len;
334 
335 
336 			 --if the max. number of characters have been read then set this flag to break
337 			 --out of the fetch string loop.
338 			 if(l_total_str_len >= p_max_search_len)then
339 
340 
341                  l_last_fetch := FND_API.G_TRUE;
342                	 l_tmp_str    := substr(l_sql_table(l_iterator + 1),1,p_max_search_len - 1);
343 
344 
345                  l_sql_table(l_iterator + 1) := NULL;
346 	             l_sql_table(l_iterator + 1) := l_tmp_str;
347 
348  			 end if;
349 
350 
351 			 --If First character of search string has been found in the previous string but
352 			 --the remainder of previous string is too short to contain the rest of the search string.
353 			 if(l_first_char_found  = FND_API.G_TRUE)then
354 
355      		      --getting the substring length.
356 			      l_substr_len :=  length(l_substr);
357 
358 			      --concatenating the substring and the necessary number of characters in the current
359 				  --string to search for search string minus the first character of it.
360 
361 
362 				  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
363 
364 
365 						x_found         := FND_API.G_TRUE;
366 						x_overflow      := (l_search_str_len-1)- l_substr_len;
367 
368 
369 						exit l_fetch_string;
370 				  else
371 
372 				        x_found         := FND_API.G_FALSE;
373 				        --calculating the new search position.
374 				   	l_str_pos :=  l_str_pos + 1;
375 
376 
377 				  end if;
378 			  end if;
379 
380 
381 		   --Loop through the current sql string searching for  l_first_char,
382 		   --If this is  found then check that the next length(l_search_sub_str - 1)
383 		   --characters are part of the search string.
384 
385 		   --If when l_first_char is found there are not enough characters to perform a match, copy the
386 		   --remaining characters into l_sub_str, read the next string(this is done before this loop,
387 		   --after the string is fetched) and then perform a check for a match.
388 
389 		   --If l_first_char is not found then read in the next string and continue searching.
390 
391 		   <<l_search_string>>
392 		   Loop
393 
394 
395 			  --getting the position of l_first_char in the current string.
396 			  l_first_char_pos := Instr(l_sql_table(l_iterator + 1),l_first_char,l_str_pos+1);
397 
398 
399 		      --the first character of the search string has been found.
400 	          if( l_first_char_pos <> 0 )then
401 
402 			      --setting current position in sql string.
403 			      l_str_pos := l_first_char_pos;
404 
405 				  --indicating that the first character of the searched for string has been found.
406 				  l_first_char_found := FND_API.G_TRUE;
407 
408 
409 				  if(l_str_count = 1) then
410 				     x_found_in_str := l_iterator;
411 				  else
412                                      x_found_in_str := l_iterator + 1;
413                                   end if;
414 
415 
416 				  x_position     := l_first_char_pos;
417 
418                   if(l_search_str_len = 1 )then
419 						 x_found := FND_API.G_TRUE;
420 						 exit       l_search_string;
421 			      --there are enough characters left in the current string to find a match.
425 		                 l_substr := substr(l_sql_table(l_iterator + 1),l_str_pos + 1,l_search_str_len - 1);
422 			      elsif ( (l_str_len - (l_str_pos + 1)) >= (l_search_str_len - 1) )then
423 
424 
426 
427 
428 						 --match has been found.
429 						 if(l_substr = l_search_sub_str )then
430 
431 						        x_found := FND_API.G_TRUE;
432 						   	    exit       l_search_string;
433 
434 						 --no match found, update string search position.
435 						 else
436 						        x_found := FND_API.G_FALSE;
437 						        l_str_pos    := l_str_pos + 1;
438 				   	     end if;
439 
440 				  --not enough characters remaining in current sql string to perform a match.
441 				  --creating a sub string of the remaining characters, which are used with
442 				  --the next string	fetched to perform a check.
443 				  elsif((l_str_len - l_str_pos) < (l_search_str_len-1))then
444 
445 				          l_substr := substr(l_sql_table(l_iterator + 1),l_str_pos + 1,l_str_len) ;
446 
447 						  --exit the search string loop and fetch another sql string.
448 						  exit       l_search_string;
449 				  end if;
450 
451 			  else
452     		       --l_first_char has not been been found in the current string.
453 
454 
455 				  --indicating that the first character of the searched for string has not been found.
456 				  l_first_char_found := FND_API.G_FALSE;
457 
458                   --indicating that the search string has not been found;
459                   x_found := FND_API.G_FALSE;
460 
461 				  --exit the search string loop and fetch another sql string.
462 				  exit l_search_string;
463 			  end if;
464 
465 
466 			End Loop l_search_string;--Searching the current strings.
467 
468             --the string has been found , no need to fetch any more sql strings.
469 			--OR the max. number of characters have been read.
470             If(x_found = FND_API.G_TRUE or l_last_fetch = FND_API.G_TRUE )then
471 
472 			       exit l_fetch_string;
473 		    end If;
474 
475 	   End Loop l_fetch_string;--Fetching the SQL strings.
476 	   Close C_SQL_string;
477 
478 EXCEPTION
479 WHEN OTHERS THEN
480 
481         if(c_sql_string%ISOPEN)then
482               Close C_SQL_string;
486         l_sqlcode := SQLCODE;
483         end if;
484 
485 		l_sqlerrm := SQLERRM;
487 
488 
489 End Search_SQL_string;
490 
491 
492 PROCEDURE get_source_type_code (
493    p_workbook_name   IN VARCHAR2,
494    p_worksheet_name  IN VARCHAR2,
495    x_source_type_code   OUT NOCOPY VARCHAR2
496 )
497 IS
498    l_source_type_code   VARCHAR2(30);
499    l_search_code        VARCHAR2(30);
500 
501    -- variables used to call search_sql_string
502    l_found              VARCHAR2(1);
503    l_found_in_str       NUMBER;
504    l_position           NUMBER;
505    l_overflow           NUMBER;
506 
507    CURSOR c_master_types IS
508       SELECT source_type_code
509       FROM   ams_list_src_types
510       WHERE  master_source_type_flag = 'Y'
511       AND    enabled_flag = 'Y'
512       ;
513 BEGIN
514    OPEN c_master_types;
515    LOOP
516       l_source_type_code := NULL;
517 
518       FETCH c_master_types INTO l_source_type_code;
519 
520       -- Need to encapsulate the source type code
521       -- with single quotes because the saved
522       -- SQL has the search string within quotes.
523       -- Without the quotes, any string with the
524       -- searched string will return regardless if it
525       -- is designated as the source type code.
526       l_search_code := '''' || l_source_type_code || '''';
527 
528       search_sql_string (
529          p_search_string      => l_search_code,
530          p_workbook_name      => p_workbook_name,
531          p_worksheet_name     => p_worksheet_name,
532          x_found              => l_found,
533          x_found_in_str       => l_found_in_str,
534          x_position           => l_position,
535          x_overflow           => l_overflow
536       );
537 
538       EXIT WHEN c_master_types%NOTFOUND OR l_found = FND_API.G_TRUE;
539    END LOOP;
540    CLOSE c_master_types;
541 
542    x_source_type_code := l_source_type_code;
543 END get_source_type_code;
544 
545 
546 END AMS_DiscovererSQL_PVT;
547 
548 
549