AS 

 BEGIN
 SET NOCOUNT ON
  
-- get core data
IF OBJECT_ID('tempdb..#j') IS NOT NULL DROP TABLE #j
SELECT jpds.DataSetName, jj.JobName, jj.membername, jdr.MemberName AS dsMemberName, js.CalledPgmID, jdd.DDName
INTO #j
FROM JCLJob jj
      INNER JOIN JCLStep js ON jj.JobID = js.JobID
      INNER JOIN JCLDD jdd ON js.StepID = jdd.StepID
      INNER JOIN JCLDDRef jdr ON jdd.DDID = jdr.DDID
      INNER JOIN JCLPhysicalDataSet jpds ON jdr.DataSetID = jpds.DataSetID 
	 INNER JOIN #ds_param_temp t ON jpds.DataSetID = t.dsId AND jdr.MemberName = t.dsMemberName
CREATE NONCLUSTERED INDEX IX_1 on #j (CalledPgmID ASC) INCLUDE(DataSetName, JobName, membername, dsMemberName, DDName) 


IF OBJECT_ID('tempdb..#pgminpgm') IS NOT NULL DROP TABLE #pgminpgm
SELECT  puip.JclPgmID, puip.ProgramID
INTO #pgminpgm
FROM ProgramsUsedInPgm puip
WHERE EXISTS (
              SELECT 1 
		    FROM #j j 
		    WHERE j.CalledPgmID = puip.JclPgmID
              )
CREATE CLUSTERED INDEX IX_2 on #pgminpgm (ProgramID ASC, JclPgmID ASC)
     

IF OBJECT_ID('tempdb..#pgm') IS NOT NULL DROP TABLE #pgm
SELECT prx.ProgramId, prx.Ancestor, prx.ProgramTypeID, srx.OccurID
INTO #pgm
FROM Programs prx
    INNER JOIN StatementReference srx ON prx.ProgramID = srx.ResourceID AND srx.ResourceType = 5
WHERE prx.OccurID = 0
      AND  EXISTS (
			   SELECT 1 
			   FROM #pgminpgm pip 
			   WHERE pip.ProgramId = prx.ProgramId
			   )								  


SELECT  DataSetName, JobName, ProgramName, ProgramAncestor, Description, Count, k, MemberName, dsMemberName, PathStr
FROM
	   (
				    SELECT j.DataSetName,
						 j.JobName,
						 jp.PgmName AS ProgramName,
						 '' AS ProgramAncestor,
						 '#EZ1#' AS Description,
						 0 AS Count,
						 jp.PgmName AS k,
						 j.membername,
						 j.dsMemberName,
						 NULL AS PathStr
				    FROM #j j
					    INNER JOIN JCLPgm jp ON j.CalledPgmID = jp.PgmID
				    WHERE NOT EXISTS  (
												SELECT 1 
												FROM Programs p
													INNER JOIN ProgramAliases pa ON pa.ProgramId = p.ProgramID
												WHERE p.OccurID <> 0 AND pa.AliasName = jp.PgmName
								   ) 
						  

				    UNION

				        

					    SELECT    j.DataSetName,
							    j.JobName,
							    pa.AliasName AS ProgramName,
							    dbo.ancestor(p.ProgramTypeid, p.Ancestor) AS ProgramAncestor,
							    '#EZ2#' AS Description,
							    0 AS Count,
							    (dbo.ancestor(p.ProgramTypeid, p.Ancestor) + pa.AliasName) AS k,
							    j.membername,
							    j.dsMemberName,
							    NULL AS PathStr
						  FROM  #pgm p
						        INNER JOIN ProgramAliases pa ON p.ProgramID = pa.ProgramId AND pa.AliasType = 0
                                      INNER JOIN #pgminpgm puip ON p.ProgramID = puip.ProgramID
							   INNER JOIN #j j ON puip.JclPgmID = j.CalledPgmID
						  WHERE  p.ProgramTypeID != -1
						            -- here a deep analysis is needed :(
								  OR ( p.ProgramTypeID = -1  AND NOT EXISTS 
														    		    (
														    			 SELECT 1
														    			 FROM #pgm px WHERE px.ProgramID = p.ProgramID AND px.Occurid = p.OccurID
														    		    )
									 )
				    UNION

				    SELECT j.DataSetName,
						 j.JobName,
						 p.ProgramName,
						 p.ProgramAncestor,
						 st.Description AS Description,
						 COUNT(sr.OccurID) AS Count,
						 (p.ProgramAncestor + p.ProgramName) AS k,
						 j.membername,
						 j.dsMemberName,
						 pth.PathStr AS PathStr
				    FROM 
					    ( 
							  SELECT px.ProgramId, px.ProgramName AS ProgramNameOrig, pax.AliasName AS ProgramName, dbo.ancestor(px.ProgramTypeid, px.Ancestor) AS ProgramAncestor, px.ProgramTypeID, px.OccurID
							  FROM Programs px
								  INNER JOIN ProgramAliases pax ON px.ProgramID = pax.ProgramId AND pax.AliasType = 0
					    ) p
					    INNER JOIN #pgminpgm puip ON p.ProgramID = puip.ProgramID
					    INNER JOIN #j j ON puip.JclPgmID = j.CalledPgmID
					    INNER JOIN Files fl ON p.ProgramID = fl.ProgID AND (fl.Name = j.DDName OR fl.Name LIKE '%'+'-'+j.DDName)
					    INNER JOIN StatementReference sr ON fl.FileID = sr.ResourceID
					    INNER JOIN Statements st ON sr.StatementType = st.StatementType
					    LEFT OUTER JOIN
								    (
									   SELECT 1 AS Flag,
											pa.AliasName,
											ProgramTypeID
									   FROM Programs
										   INNER JOIN ProgramAliases pa ON Programs.ProgramID = pa.ProgramId
																  AND pa.AliasType = 0
									   GROUP BY AliasName,
											  ProgramTypeID
									   HAVING COUNT(*) > 1
								    ) f ON p.ProgramNameOrig = f.AliasName  AND p.ProgramTypeID = f.ProgramTypeID
					    LEFT JOIN Occurrences occ ON occ.OccurID = p.OccurID
					    LEFT JOIN Paths pth ON pth.PathID = occ.PathID AND f.Flag = 1
				    WHERE sr.ResourceType = 9 
				    GROUP BY j.DataSetName, j.JobName, p.ProgramName, p.ProgramAncestor, st.Description , j.membername, j.dsMemberName, pth.PathStr


				    UNION   --AMS statements

				    SELECT 
						 jpds.DataSetName,
						 jj.JobName,
						 jp.PgmName AS ProgramName,
						 '' AS ProgramAncestor,
						 'AMS: '+istmtp.Description AS Description,
						 COUNT(istm.IDCAMSStatementID) AS Count,
						 jp.PgmName AS k,
						 jj.membername,
						 idu.MemberName AS dsMemberName,
						 NULL AS PathStr
				    FROM JCLJob jj
					    INNER JOIN JCLStep js ON jj.JobID = js.JobID
					    INNER JOIN JCLIDCAMSStatements istm ON js.StepID = istm.StepID
					    INNER JOIN JCLIDCAMSDatasetUsages idu ON idu.IDCAMSStatementID = istm.IDCAMSStatementID
					    INNER JOIN JCLPhysicalDataSet jpds ON idu.DataSetID = jpds.DataSetID
					    INNER JOIN JCLPgm jp ON js.CalledPgmID = jp.PgmID
					    INNER JOIN JCLIDCAMSStatementTypes istmtp ON istm.IDCAMSStatementTypeID = istmtp.IDCAMSStatementTypeID
					    INNER JOIN #ds_param_temp t ON jpds.DataSetID = t.dsId  AND (t.dsMemberName IS NULL OR t.dsMemberName = idu.MemberName)
				    GROUP BY jpds.DataSetName, idu.MemberName, jj.JobName, jj.membername, jp.PgmName, istmtp.Description
	   )src
ORDER BY DataSetName, dsMemberName, JobName, MemberName, k, PathStr, Description 
END
