 ( 
   IN p_DIRECTION INTEGER,
   IN p_VALID_FROM TIMESTAMP ,
   IN p_VALID_TO TIMESTAMP ,
   IN p_RESTRICT_APPS INTEGER , 
   IN p_MaxLevels INTEGER 
 )
DYNAMIC RESULT SETS 100
CALLED ON NULL INPUT
LANGUAGE SQL
ss: BEGIN

     -- clean up temp table if exists 
	BEGIN
		DECLARE CONTINUE HANDLER FOR SQLSTATE '42704'
		BEGIN END;
		
		COMMIT;
		DROP TABLE SESSION.Discovered ;	
		DROP TABLE SESSION.DistinctApps ;	
	END;


    BEGIN
       --A. Declare variable/Create temporary objects 

			 --direction is 0 -> forward
			 --             1 -> backward
			 --             2 -> both

           DECLARE v_DIRECTION, v_RESTRICT_APPS, v_MaxLevels INTEGER;
           DECLARE v_VALID_FROM, v_VALID_TO TIMESTAMP;
	       DECLARE v_Level, v_RC INTEGER DEFAULT 1;



        

           DECLARE GLOBAL TEMPORARY TABLE SESSION.Discovered
			( 
			     srcJobNr              VARCHAR(5),
				 srcAppId              INTEGER,
				 tgtJobNr              VARCHAR(5),
				 tgtAppId              INTEGER,
				 level                 INTEGER,
				 DependencyDescription VARCHAR(50),
				 c                     INTEGER
			)
			ON COMMIT PRESERVE ROWS  NOT LOGGED ;

           
           
            DECLARE GLOBAL TEMPORARY TABLE SESSION.DistinctApps
			( 
			         c               INTEGER,
					 appid           INTEGER,
					 applicationname VARCHAR(16)
			)
			ON COMMIT PRESERVE ROWS NOT LOGGED ;

           

 --B. Get basic data 

		  
		  SET v_RESTRICT_APPS = p_RESTRICT_APPS;
		  SET v_RESTRICT_APPS = COALESCE(v_RESTRICT_APPS, 0);
		  
          SET v_VALID_FROM = p_VALID_FROM; --(SELECT (CASE WHEN p_VALID_FROM = '' THEN NULL ELSE p_VALID_FROM END) FROM SYSIBM.SYSDUMMY1);
          SET v_VALID_TO = p_VALID_TO; --(SELECT (CASE WHEN p_VALID_TO = '' THEN NULL ELSE p_VALID_TO END) FROM SYSIBM.SYSDUMMY1);
		 
		  SET v_DIRECTION = (SELECT (CASE WHEN p_DIRECTION > 2 OR p_DIRECTION < 0 THEN 2 ELSE p_DIRECTION END) FROM SYSIBM.SYSDUMMY1);
          SET v_DIRECTION = COALESCE(v_DIRECTION, 2);
		 
		  SET v_MaxLevels = (SELECT (CASE WHEN p_MaxLevels > 100 THEN 100 ELSE p_MaxLevels END) FROM SYSIBM.SYSDUMMY1);
          SET v_MaxLevels = COALESCE(v_MaxLevels, 100);


		  INSERT INTO SESSION.DistinctApps (c, appid, applicationname)
		  SELECT COUNT(twa.ApplicationName) AS c,
			       MIN(twa.AppID) AS AppID,
			       twa.ApplicationName
		  FROM TWS_Applications twa
		  WHERE twa.ApplicationType = 'A'
			      AND twa.ApplicationStatus = 'A' --only active applications
		  GROUP BY twa.ApplicationName;
 
 

		INSERT INTO SESSION.Discovered(srcJobNr, srcAppId, tgtJobNr, tgtAppId, level, DependencyDescription)
		SELECT CAST(NULL AS VARCHAR(5)),
		       CAST(NULL AS INTEGER),
		       j.jobnr,
		       j.appid,
		       0,
		       CAST(NULL AS VARCHAR(50))
		FROM SESSION.jobids j;
     
 
 --select * from SESSION.DistinctApps where appid in (1,2,3)
 --select * from SESSION.Discovered
 --select * from TWS_Jobs
 --select * from TWS_Applications


--C. create appropriate indexes

        --CREATE INDEX ncidx12 ON SESSION.Discovered (src ASC, tgt ASC);

         WHILE  (v_RC > 0 AND v_MaxLevels > v_Level) 
         DO
			     SET v_Level = v_Level + 1;

               
                INSERT INTO SESSION.Discovered (srcJobNr, srcAppId, tgtJobNr, tgtAppId, level, DependencyDescription, c)
				SELECT *
				FROM (
								--forward
								SELECT d.tgtJobNr,
									  d.tgtAppId,
									  e.JobNumber,
									  e.JobAppID,
									  (v_LEVEL - 1),
									  e.DependencyDescription,
									  da.c
								FROM SESSION.Discovered d
									INNER JOIN SESSION.DistinctApps AS da ON da.appid = d.tgtAppId
									INNER JOIN TWS_Jobs AS e ON e.PredecessorJobNumber = d.tgtJobNr
															  AND d.level >= 0
															  AND ((e.PredecessorApplication IS NULL AND e.JobAppID = da.appid)
																    OR 
																    e.PredecessorApplication = da.applicationname)
									INNER JOIN TWS_Applications oa ON oa.AppID = e.JobAppID
																   AND ((v_VALID_FROM IS NULL  OR oa.ValidFromDate >= v_VALID_FROM)
																	   AND (v_VALID_TO IS NULL OR oa.ValidToDate <= v_VALID_TO))
												    --only active applications
																   AND oa.ApplicationType = 'A'
																   AND oa.ApplicationStatus = 'A'
												    --id constraints for application      
																   AND (v_RESTRICT_APPS = 0
																	   OR (e.JobAppID IN
																		 (
																			SELECT appid
																			FROM SESSION.appids
																		 )))
								WHERE --direction choice
								      (v_DIRECTION = 0 OR v_DIRECTION = 2)
											--cycle stop
								      AND NOT EXISTS
													(
													    SELECT 1
													    FROM SESSION.Discovered AS dd
													    WHERE e.PredecessorJobNumber = dd.srcJobNr
															AND dd.srcAppId = e.JobAppId
													)
				                    
							UNION
							
						    --backward
							SELECT d.tgtJobNr,
								   d.tgtAppId,
								   e.PredecessorJobNumber,
								   da.appID,
								  -(v_LEVEL - 1),
								  e.DependencyDescription,
								  da.c
							FROM SESSION.Discovered d
								INNER JOIN TWS_Jobs AS e ON e.JobNumber = d.tgtJobNr
														  AND d.tgtAppId = e.JobAppID
														  AND d.level <= 0
								INNER JOIN SESSION.DistinctApps AS da ON((e.PredecessorApplication IS NULL
															AND e.JobAppID = da.AppID) --same application
														    OR e.PredecessorApplication = da.ApplicationName)
								INNER JOIN TWS_Applications oa ON oa.AppID = da.appid
											    --date constraints for application
															   AND ((v_VALID_FROM IS NULL OR oa.ValidFromDate >= v_VALID_FROM)
																   AND (v_VALID_TO IS NULL OR oa.ValidToDate <= v_VALID_TO))
											    --only active applications
															   AND oa.ApplicationType = 'A'
															   AND oa.ApplicationStatus = 'A'
											    --id constraints for application      
															   AND (v_RESTRICT_APPS = 0
																   OR (e.JobAppID IN
																	 (
																		SELECT appid
																		FROM SESSION.appids
																	 )))
							WHERE --direction choice
							        (v_DIRECTION = 1 OR v_DIRECTION = 2)
								  --cycle stop
									AND NOT EXISTS
													(
													    SELECT 1
													    FROM SESSION.Discovered AS dd
													    WHERE e.JobNumber = dd.srcJobNr
															AND dd.srcAppId = e.JobAppId
													) 
						)src;
                

                 GET DIAGNOSTICS v_RC = ROW_COUNT; 

                 COMMIT;
				 
         END WHILE;
          
          
	     
                 BEGIN
              
					     DECLARE crs CURSOR WITH RETURN FOR	 
					     SELECT    d.srcJobNr,
							       d.srcAppId,
							       d.tgtJobNr,
							       d.tgtAppId,
							       d.level,
							    -- TWS_Jobs.JobName as tgtJobName,
							    -- TWS_Jobs.JobDescription as tgtJobDescription,
							       d.DependencyDescription,
							    -- TWS_Applications.ApplicationName as tgtApplicationName,
							    -- abs(d.level) 
							       c
						FROM SESSION.Discovered d
							     --left join TWS_Jobs on d.tgtJobNr = TWS_Jobs.JobNumber AND d.tgtAppId = TWS_Jobs.JobAppID
							     --left join TWS_Applications on d.tgtAppId = TWS_Applications.AppID
						ORDER BY level;--abs(d.level)

                        OPEN crs;
                        
                  END;  
	END;			  
            
END ss	




 

 
 
 

