dmpippin
5/17/2013 - 2:01 PM

Updated computer checkin proc using ROW_COUNT()

Updated computer checkin proc using ROW_COUNT()

/****** Object:  StoredProcedure [dbo].[usp_import_computer_checkin_history]    Script Date: 05/17/2013 14:01:04 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO





CREATE PROCEDURE [dbo].[usp_import_computer_checkin_history]
AS
  SET NOCOUNT ON;

BEGIN

	DECLARE @MinRow INT
	DECLARE @MaxRow INT
	DECLARE @CurrentRow INT
	DECLARE @Event VARCHAR(32)
	DECLARE @RegionalCollector VARCHAR(32)
	DECLARE @DatabaseName VARCHAR(32)
	DECLARE @SchemaName VARCHAR(32)
	DECLARE @TranName varchar(100)
	DECLARE @sepmSQL nvarchar(max)
	
	IF OBJECT_ID('tempdb.dbo.#ComputerCheckinHistoryTempTable' ) IS NOT NULL
	BEGIN
	  DROP TABLE #ComputerCheckinHistoryTempTable
	END
	
	CREATE TABLE #ComputerCheckinHistoryTempTable
	(
		[USER_NAME] [nvarchar](512) NULL,
		[COMPUTER_NAME] [nvarchar](128) NULL,
		[IP_ADDR1] [varchar](15) NULL,
		[LAST_UPDATE_TIME] [datetime] NULL,
		[LAST_CONNECTED_IP_ADDR] [varchar](15) NULL,
		[AGENT_VERSION] [nvarchar](128) NULL,
		[VERSION] [varchar](255) NULL,
		[REGIONAL_COLLECTOR] [varchar](64) NULL
    )
	
	IF OBJECT_ID('tempdb.dbo.#ComputerCheckinHistoryRegionTempTable' ) IS NOT NULL
	BEGIN
	  DROP TABLE #ComputerCheckinHistoryRegionTempTable
	END

	CREATE TABLE #ComputerCheckinHistoryRegionTempTable
	(
		RowId INT PRIMARY KEY IDENTITY(1,1)
	  , RegionalCollector VARCHAR(32)
	  , DatabaseName VARCHAR(32)
	  , SchemaName VARCHAR(32)
	)
	
	INSERT INTO #ComputerCheckinHistoryRegionTempTable
	SELECT [REGIONAL_COLLECTOR], [DATABASE], [SCHEMA_NAME]
	FROM [SEPM].[dbo].[EVENT_CONFIGURATION]
	WHERE [EVENT_TYPE] = 'SCANS_READABLE' AND ENABLED = 1;
      
	SELECT @MinRow = (SELECT MIN(RowId) FROM #ComputerCheckinHistoryRegionTempTable)
	SELECT @MaxRow = (SELECT MAX(RowId) FROM #ComputerCheckinHistoryRegionTempTable)

	WHILE @MinRow <= @MaxRow
	
	BEGIN

    SET @CurrentRow = @MinRow
    SET @RegionalCollector = (SELECT RegionalCollector FROM #ComputerCheckinHistoryRegionTempTable WHERE RowId = @CurrentRow)
    SET @DatabaseName = (SELECT DatabaseName FROM #ComputerCheckinHistoryRegionTempTable WHERE RowId = @CurrentRow)
    SET @SchemaName = (SELECT SchemaName FROM #ComputerCheckinHistoryRegionTempTable WHERE RowId = @CurrentRow)
          
    SET @TranName =  @Event +' import from ' + @RegionalCollector

	-- Used to fetch only data from the last timestamp([LAST_UPDATE_TIME])
	
	DECLARE @LastImportDateTime datetime
	SET @LastImportDateTime = (SELECT MAX(LAST_UPDATE_TIME) FROM [SEPM].[dbo].[COMPUTER_CHECKIN_HISTORY] where Regional_Collector = @RegionalCollector)
	
	DECLARE @LastImportDateAsTimeStamp bigint
	SET @LastImportDateAsTimeStamp = (Select convert(bigint,(datediff(ss,'19700101',@LastImportDateTime)))*1000) 
	
	-- Create a retention period of one year
	
	DECLARE @RetentionPeriod datetime
	SET @RetentionPeriod = GETDATE() - 365
	
	
	IF  @LastImportDateTime IS NULL OR  @LastImportDateTime <= 0
	BEGIN
		SET  @LastImportDateTime = @RetentionPeriod
	END
	
	BEGIN TRAN @TranName
	
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
	
	-- DELETES data older than what is specified by the Retention Period
	
	DELETE FROM [SEPM].[dbo].[COMPUTER_CHECKIN_HISTORY] WHERE LAST_UPDATE_TIME < @RetentionPeriod

	-- OPENQUERY to pull full table of all computer check in history within the SEPM regional collectors
	
	
	SET @sepmSQL = 
	N'INSERT INTO #ComputerCheckinHistoryTempTable
		(
				[USER_NAME],
				[COMPUTER_NAME],
				[IP_ADDR1],
				[LAST_UPDATE_TIME],
				[AGENT_VERSION],            
				[VERSION],
				[REGIONAL_COLLECTOR]   
		)
		SELECT 
			USER_NAME,
			COMPUTER_NAME,
			sepm.dbo.IntegerToIPAddress(IP_ADDR1),
			LAST_UPDATE_TIME,
			AGENT_VERSION,
			VERSION,
			'''+@RegionalCollector+''' AS REGIONAL_COLLECTOR 
		         
		FROM OPENQUERY	      
		(        
		   ['+@RegionalCollector+'],    
			''SELECT
			    c.USER_NAME,
				sc.COMPUTER_NAME,
				sc.IP_ADDR1,
				dateadd(ss, sa.LAST_UPDATE_TIME/1000, ''''1970-01-01'''') as LAST_UPDATE_TIME,
				sa.AGENT_VERSION,
				p.VERSION	
			FROM ['+@DatabaseName+'].['+@SchemaName+'].[SEM_COMPUTER] sc
			INNER JOIN ['+@DatabaseName+'].['+@SchemaName+'].[SEM_CLIENT] c ON sc.COMPUTER_ID = c.COMPUTER_ID 
			INNER JOIN ['+@DatabaseName+'].['+@SchemaName+'].[SEM_AGENT] sa ON sc.COMPUTER_ID = sa.COMPUTER_ID 
			INNER JOIN ['+@DatabaseName+'].['+@SchemaName+'].PATTERN p ON sa.PATTERN_IDX = p.PATTERN_IDX
			WHERE 
				p.PATTERN_TYPE =  ''''VIRUS_DEFS''''
				AND p.DELETED=''''0''''
				AND sa.DELETED=''''0''''
				AND sc.DELETED=''''0'''' 
				and sa.LAST_UPDATE_TIME > CONVERT(bigint,'+CONVERT(varchar,@LastImportDateAsTimeStamp)+') ''	
		) as scans_readable 
		ORDER BY scans_readable.LAST_UPDATE_TIME;';
	
	
	
	
	EXEC SP_EXECUTESQL @sepmSQL;
	 
 SET TRANSACTION ISOLATION LEVEL READ COMMITTED
      
-- Error handling
      
      IF @@ERROR <> 0
      BEGIN
            PRINT 'Rolling back ' + @TranName
            ROLLBACK TRAN @TranName
      END
      ELSE
      BEGIN
            PRINT 'Committing ' + @TranName
            COMMIT TRAN @TranName
      END
      
      -- Advance to next row in our loop
      SET @MinRow = @MinRow + 1
	
   END
	/*Statement to insert a subset of records into the COMPUTER_CHECKIN_HISTORY table from #ComputerCheckinHistoryTempTable (master pull).
	  Description of ROW_NUMBER() clause: Command to create partitions within the data, based on row-sets, grouped by columns declared
	  in the PARTITION BY clause and placed in the order declared by the ORDER BY clause. The partition will include data where only, but all
	  columns declared contain similar values. Row numbers are assigned to each element in a partition, starting at 1. The OVER clause simply 
	  executes the PARTITION and ORDER BY clause before associating the result set with aggregate or ranking function. 

      Needs: The set we return could be grouped by a single value and will return the latest scan for the element we group by. This will not
      capture chnages on the network in regards to different users signed into a single machine during a similar timeframe or a machine having
	  mutiple IP addresses within a similar timeframe. By partitioning on all three values, we are creating sets of these unique values for 
      one-offs or changes in the network that would otherwise be missed if just selecting the top value of one grouping. 	  
	
	*/
	
	INSERT INTO [SEPM].[dbo].[COMPUTER_CHECKIN_HISTORY]
	(
		[USER_NAME],
		[COMPUTER_NAME],
		[IP_ADDR1],
		[LAST_UPDATE_TIME],
		[AGENT_VERSION],            
		[VERSION],
		[REGIONAL_COLLECTOR]
	) 
	
		SELECT  
			USER_NAME,
			COMPUTER_NAME,
			IP_ADDR1,
			LAST_UPDATE_TIME,
			AGENT_VERSION,
			VERSION,
			REGIONAL_COLLECTOR

    FROM (  SELECT *, ROW_NUMBER() OVER(PARTITION BY USER_NAME,COMPUTER_NAME,IP_ADDR1 ORDER BY LAST_UPDATE_TIME DESC) part
        FROM #ComputerCheckinHistoryTempTable) A
        WHERE part = 1
	
	
	/* Drop the two #temptables created within Proc*/
	
	IF OBJECT_ID('tempdb.dbo.#ComputerCheckinHistoryTempTable' ) IS NOT NULL
	BEGIN
      DROP TABLE #ComputerCheckinHistoryTempTable
	END
	
	IF OBJECT_ID('tempdb.dbo.#ComputerCheckinHistoryRegionTempTable' ) IS NOT NULL
	BEGIN
      DROP TABLE #ComputerCheckinHistoryRegionTempTable
	END
	
	
 END




GO