Wednesday, August 11, 2010

GIMPI Production Server Code (Part 2)



StoredProcedure [dbo].[dbasp_GIMPI_CaptureAndExport]

This Stored Procedure is the one that does all the work and will be called by the Agent Job when needed. This process cleans out any existing data and reloads the local holding tables with fresh data. Then it BCP's out the data to files and then sends them over to our central aggregation server. There was a pre-existing system in place here using the stored procedure dbasp_File_Transit which is being used to deliver the file to a central location. I am not able to dissect this currently and am only going to identify this a a "Black Box" process which can be replaced by any other method of copying the file to the report server. In the past I have used "Data Domain" SAN Replication for this. Because I was using a generic File Mover, I standardized the way that my servers create and import these files. When the file is created, it is named using a function that base64 encodes several pieces of information into a single filename that can then be decoded on the other side revealing where it came from and what to do with it. I am sure there are many other useful places to implement this logic and would love to hear how you have used the encode and decode functions.

This Stored Procedure has been over designed for how I currently use it but is very flexible, which will make my rewrite that does not use the unioned views much easier. The @target% and @retry_limit parameters are simply passed through to the "Black Box" file mover process and would probably be changed to match what ever method is utilized. While the other parameters can be used to run against a single database, schema, and/or table.

USE [dbaperf]
GO

/****** Object:  StoredProcedure [dbo].[dbasp_GIMPI_CaptureAndExport]    Script Date: 06/09/2010 11:36:56 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[dbasp_GIMPI_CaptureAndExport]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'
CREATE PROC [dbo].[dbasp_GIMPI_CaptureAndExport]
(
@UNCPath VarChar(6000) = NULL
,@target_env VarChar(50) = ''amer''
,@target_server sysname = ''SEAFRESQLDBA01''
,@target_share VarChar(2048) = ''SEAFRESQLDBA01_dbasql\IndexAnalysis''
,@retry_limit INT = 5
,@Fill_Factor int = 98
,@PopulateDMVsForAll bit = 1
,@database_name sysname = NULL
,@schema_name sysname = NULL
,@table_name sysname = NULL
)

/***************************************************************
 **  Stored Procedure dbasp_GIMPI_CaptureAndExport                 
 **  Written by Steve Ledridge, Getty Images                
 **  June 2010                                      
 **
 **  
 **  Description: Generates two DMV''s used for the GIMPI Reports and sends the data 
 **   To SEAFRESQLDBA01 to be aggregated.
 **
 **
 **  This proc accepts the following input parameters:
 **  
 **   @UNCPath = Whether or not online reindexing is used.
 **   @target_env = Passed to [dbasp_File_Transit]. 
 **   @target_server = Passed to [dbasp_File_Transit].
 **   @target_share = Passed to [dbasp_File_Transit].
 **   @retry_limit = Value User for FILLFACTOR on REBUILDS when Read Percentage > 60%
 **   @Fill_Factor = Value User for FILLFACTOR on REBUILDS when Read Precentage < 30%
 **   @PopulateDMVsForAll = Ignore any specific DB,SCHEMA,or TABLE VALUES (GET IT ALL)
 ** @database_name = FILTER - Only repopulate with tables in the specific Database.
 ** @schema_name = FILTER - Only repopulate with tables in the specific Schema. 
 ** @table_name = FILTER - Only repopulate with tables with the specific Name.
 **
 ***************************************************************/
  as
set nocount on


-- ======================================================================================
-- Revision History
-- Date Author      Desc
-- ========== ==================== =============================================
-- 2010-00-00 Steve Ledridge Created
-- 2010-06-07 Steve Ledridge Modified deletes to use truncates when they can.
-- Added missing delete for one of the DMV''s
-- ======================================================================================

/***
DECLARE @UNCPath VarChar(6000)
,@target_env VarChar(50)
,@target_server sysname
,@target_share VarChar(2048)
,@retry_limit INT
,@Fill_Factor int
,@PopulateDMVsForAll bit
,@database_name sysname
,@schema_name sysname
,@table_name sysname
SELECT @UNCPath = ''\\g1sqla\G1SQLA$A_dbasql\dba_reports''
,@target_env = ''amer''
,@target_server = ''SEAFRESQLDBA01''
,@target_share = ''SEAFRESQLDBA01_dbasql\IndexAnalysis''
,@retry_limit = 5
,@Fill_Factor = 98
,@PopulateDMVsForAll = 1
,@database_name = NULL
,@schema_name = NULL
,@table_name = NULL
--***/

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

DECLARE @TSQL1 VarChar(max)
,@TSQL2 VarChar(max)
,@TSQL3 VarChar(max)
,@Object sysname
,@object_id int
,@database_id int
,@IndexScript nvarchar(max)
,@RC int
,@Script VarChar(6000)
,@Export_Source sysname
,@LocalPath VarChar(6000)
,@FileName VarChar(6000)

SELECT @UNCPath = COALESCE(@UNCPath,''\\'' + LEFT(@@SERVERNAME,(CHARINDEX(''\'',@@SERVERNAME+''\'')-1)) + ''\'' + REPLACE(@@SERVERNAME,''\'',''$'') + ''_dbasql\dba_reports'')
,@object_id = OBJECT_ID(@database_name+''.''+@schema_name+''.''+@table_name)
,@database_id = db_id(@database_name)
,@IndexScript = ''''
,@LocalPath = @UNCPath
If @PopulateDMVsForAll = 0 AND @database_name IS NULL
BEGIN
PRINT ''A DATABASE NAME MUST BE SPECIFIED IF @PopulateDMVsForAll=0''
RETURN -1
END


IF OBJECT_ID(''tempdb..#ForeignKeys'') IS NOT NULL
    DROP TABLE #ForeignKeys

CREATE TABLE #ForeignKeys
    (
    database_id int
    ,foreign_key_name sysname
    ,object_id int
    ,fk_columns nvarchar(max)
    ,fk_columns_compare nvarchar(max)
    );
    
if @@SERVERNAME IN (''SEADCASPSQLA\A'')
 GOTO SkipCreateViews
    
DECLARE CreateAllDBViews CURSOR
FOR
SELECT ''sys'',''tables''
UNION ALL
SELECT ''sys'',''schemas''
UNION ALL
SELECT ''sys'',''sysindexes''
UNION ALL
SELECT ''sys'',''indexes''
UNION ALL
SELECT ''sys'',''dm_db_partition_stats''
UNION ALL
SELECT ''sys'',''allocation_units''
UNION ALL
SELECT ''sys'',''partitions''
UNION ALL
SELECT ''sys'',''columns''
UNION ALL
SELECT ''sys'',''index_columns''
UNION ALL
SELECT ''sys'',''foreign_keys''
UNION ALL
SELECT ''sys'',''foreign_key_columns''


OPEN CreateAllDBViews
FETCH NEXT FROM CreateAllDBViews INTO @TSQL2,@TSQL3
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
SET @TSQL1 = ''IF OBJECT_ID(''''[dbo].[vw_AllDB_''+@TSQL3+'']'''') IS NOT NULL'' +CHAR(13)+CHAR(10)
+ ''DROP VIEW [dbo].[vw_AllDB_''+@TSQL3+'']'' +CHAR(13)+CHAR(10)
SET @TSQL1 = ''USE [dbaperf];''+CHAR(13)+CHAR(10)+''EXEC ('''''' + REPLACE(@TSQL1,'''''''','''''''''''') + '''''')''
EXEC (@TSQL1)

SET @TSQL1 = ''CREATE VIEW [dbo].[vw_AllDB_''+@TSQL3+''] AS'' +CHAR(13)+CHAR(10)+''SELECT ''''master'''' AS database_name, DB_ID(''''master'''') AS database_id, * From [master].[''+@TSQL2+''].[''+@TSQL3+'']''+CHAR(13)+CHAR(10)
SELECT @TSQL1 = @TSQL1 +
''UNION ALL''+CHAR(13)+CHAR(10)+''SELECT ''''''+name+'''''', DB_ID(''''''+name+''''''), * From [''+name+''].[''+@TSQL2+''].[''+@TSQL3+'']''+CHAR(13)+CHAR(10)
FROM master.sys.databases
WHERE name != ''master''
SET @TSQL1 = ''USE [dbaperf];''+CHAR(13)+CHAR(10)+''EXEC ('''''' + REPLACE(@TSQL1,'''''''','''''''''''') + '''''')''
EXEC (@TSQL1)
END
FETCH NEXT FROM CreateAllDBViews INTO @TSQL2,@TSQL3
END

CLOSE CreateAllDBViews
DEALLOCATE CreateAllDBViews    

SkipCreateViews:
    

BEGIN -- POPULATE DMVs or TEMP TABLES

-------------------------------------------------------
-------------------------------------------------------
-- POPULATE dmv_MissingIndexSnapshot
-------------------------------------------------------
-------------------------------------------------------

SELECT @database_name = QUOTENAME(@database_name)
,@schema_name = QUOTENAME(@schema_name)
,@table_name = QUOTENAME(@table_name)

if @PopulateDMVsForAll = 1
TRUNCATE TABLE [dbo].[dmv_MissingIndexSnapshot]
ELSE
DELETE dmv_MissingIndexSnapshot
WHERE (
QUOTENAME(database_name) = @database_name
OR @database_name IS NULL
OR @PopulateDMVsForAll = 1
)
AND (
QUOTENAME(table_name) = @table_name
OR @table_name IS NULL
OR @PopulateDMVsForAll = 1
)

;WITH XMLNAMESPACES (DEFAULT ''http://schemas.microsoft.com/sqlserver/2004/07/showplan'')
, PlanData AS
SELECT ecp.plan_handle
, MissingIndex.value (''(.//MissingIndex/@Database)[1]'',''sysname'') AS database_name
, MissingIndex.value (''(.//MissingIndex/@Schema)[1]'',''sysname'') AS schema_name
, MissingIndex.value (''(.//MissingIndex/@Table)[1]'',''sysname'') AS table_name
, MissingIndex.query (''.'') AS Statements 
, MissingIndex.value (''(./@StatementId)[1]'', ''int'') AS StatementID 
, MissingIndex.value (''(./@StatementText)[1]'', ''varchar(max)'') AS StatementText 
, MissingIndex.value (''(./@StatementSubTreeCost)[1]'', ''float'') AS StatementSubTreeCost
, MissingIndex.value (''(.//MissingIndexGroup/@Impact)[1]'',''float'') AS Impact
, usecounts AS UseCounts
, eqp.[dbid]
, eqp.[objectid]
, ecp.objtype

FROM sys.dm_exec_cached_plans AS ecp
CROSS APPLY sys.dm_exec_query_plan(ecp.plan_handle) AS eqp
CROSS APPLY query_plan.nodes
 (''for $stmt in .//Statements/*
where count($stmt/Condition/QueryPlan/MissingIndexes) > 0
or count($stmt/QueryPlan/MissingIndexes) > 0
return $stmt'') AS qp(MissingIndex)
WHERE (
MissingIndex.exist 
 (''.//MissingIndex[@Database = sql:variable("@database_name")]'') = 1
OR @database_name IS NULL
OR @PopulateDMVsForAll = 1
)
AND (
MissingIndex.exist 
 (''.//MissingIndex[@Table = sql:variable("@table_name")]'') = 1
OR @table_name IS NULL
OR @PopulateDMVsForAll = 1
)
)
, FormatedData AS
(
SELECT @@ServerName AS server_name
, REPLACE(REPLACE(
  [database_name]
  ,''['',''''),'']'','''') AS database_name
, DB_ID(REPLACE(REPLACE(
  [database_name]
  ,''['',''''),'']'','''')) AS database_id
, SCHEMA_ID(REPLACE(REPLACE(
  [schema_name]
  ,''['',''''),'']'','''')) AS schema_id
, REPLACE(REPLACE(
  [schema_name]
  ,''['',''''),'']'','''') AS schema_name
, OBJECT_ID(
  [database_name]
  +''.''+[schema_name]
  +''.''+[table_name]
  ) AS object_id
, REPLACE(REPLACE(
  [table_name]
   ,''['',''''),'']'','''') AS table_name
, [StatementSubTreeCost]
  * ISNULL([Impact], 0) 
  * usecounts AS Improvement 
, [Statements] AS CompleteQueryPlan 
, OBJECT_NAME([objectid],[dbid]) AS Sproc_name
, [StatementId] AS StatementID 
, [StatementText] AS StatementText 
, [StatementSubTreeCost] AS StatementSubTreeCost
, NULL AS MissingIndex 
, [Impact] AS IndexImpact 
, [usecounts] AS UseCounts
, REPLACE(CAST(Mi.query
   (''data( for $cg in .//ColumnGroup
where $cg/@Usage="EQUALITY" or $cg/@Usage="INEQUALITY"
return $cg/Column/@Name )'')
AS NVarchar(4000)),''] ['',''], ['') AS IndexColumns
, REPLACE(CAST(Mi.query
   (''data( for $cg in .//ColumnGroup
where $cg/@Usage="INCLUDE"
return $cg/Column/@Name )'')
AS NVarchar(4000)),''] ['',''], ['') AS IncludeColumns
,REPLACE(REPLACE(REPLACE(CAST(Mi.query
    (''data( for $cg in .//ColumnGroup
where $cg/@Usage="EQUALITY" or $cg/@Usage="INEQUALITY"
return $cg/Column/@ColumnId )'')
AS NVarchar(4000)),''['',''''),'']'',''''),'' '',''_'') AS IndexColumnIDs
,REPLACE(REPLACE(REPLACE(CAST(Mi.query
   (''data( for $cg in .//ColumnGroup
where $cg/@Usage="INCLUDE"
return $cg/Column/@ColumnId )'')
AS NVarchar(4000)),''['',''''),'']'',''''),'' '',''_'') AS IncludeColumnIDs
From PlanData AS pd
CROSS APPLY Statements.nodes
 (''.//MissingIndex'') AS St(Mi)
)
INSERT INTO dmv_MissingIndexSnapshot
SELECT server_name
, database_name
, database_id
, schema_id
, schema_name
, object_id
, table_name
, Improvement 
, CompleteQueryPlan 
, Sproc_name
, StatementID 
, StatementText 
, StatementSubTreeCost
, MissingIndex 
, IndexImpact 
, UseCounts
, IndexColumns
, '', '' + [IncludeColumns] AS IncludeColumns
, ''IX_'' 
+ REPLACE(REPLACE(
  [table_name]
   ,''['',''''),'']'','''')
+ ''_''
+ [IndexColumnIDs]
+ CASE
  WHEN [IncludeColumnIDs] = ''''
  THEN ''''
  ELSE ''_INC_'' + [IncludeColumnIDs]
  END AS IndexName
,getdate()
FROM FormatedData
ORDER BY Improvement DESC

-------------------------------------------------------
-------------------------------------------------------
-- POPULATE dmv_IndexBaseLine
-------------------------------------------------------
-------------------------------------------------------
SELECT @database_name = REPLACE(REPLACE(
  @database_name
  ,''['',''''),'']'','''')
,@schema_name = REPLACE(REPLACE(
  @schema_name
  ,''['',''''),'']'','''')
,@table_name = REPLACE(REPLACE(
  @table_name
  ,''['',''''),'']'','''')


if @PopulateDMVsForAll = 1
TRUNCATE TABLE [dbo].[dmv_IndexBaseLine]
ELSE
DELETE dmv_IndexBaseLine
WHERE (
database_name = @database_name
OR @database_name IS NULL
OR @PopulateDMVsForAll = 1
)
AND (
table_name = @table_name
OR @table_name IS NULL
OR @PopulateDMVsForAll = 1
)


;WITH AllocationUnits
AS (
SELECT p.database_id
,p.object_id
,p.index_id
,p.partition_number 
,au.allocation_unit_id
FROM dbaperf.dbo.vw_AllDB_allocation_units AS au
JOIN dbaperf.dbo.vw_AllDB_partitions AS p 
 ON au.container_id = p.hobt_id 
 AND au.database_id = p.database_id
 AND (au.type = 1 OR au.type = 3)
 WHERE (p.database_id = @database_id OR @database_id IS NULL OR @PopulateDMVsForAll = 1)
  AND (p.object_id = @object_id OR @object_id IS NULL OR @PopulateDMVsForAll = 1)
UNION ALL
SELECT p.database_id
,p.object_id
,p.index_id
,p.partition_number 
,au.allocation_unit_id
FROM dbaperf.dbo.vw_AllDB_allocation_units AS au
JOIN dbaperf.dbo.vw_AllDB_partitions AS p 
 ON au.container_id = p.partition_id
 AND au.database_id = p.database_id 
 AND au.type = 2
 WHERE (p.database_id = @database_id OR @database_id IS NULL OR @PopulateDMVsForAll = 1)
  AND (p.object_id = @object_id OR @object_id IS NULL OR @PopulateDMVsForAll = 1)
)
,MemoryBuffer
AS (
SELECT au.database_id
,au.object_id
,au.index_id
,au.partition_number
,COUNT(*)AS buffered_page_count
,CONVERT(decimal(12,2), CAST(COUNT(*) as bigint)*CAST(8 as float)/1024) as buffer_mb
FROM sys.dm_os_buffer_descriptors AS bd 
JOIN AllocationUnits au 
ON bd.allocation_unit_id = au.allocation_unit_id
AND bd.database_id = au.database_id
 WHERE (au.database_id = @database_id OR @database_id IS NULL OR @PopulateDMVsForAll = 1)
  AND (au.object_id = @object_id OR @object_id IS NULL OR @PopulateDMVsForAll = 1)
GROUP BY au.database_id, au.object_id, au.index_id, au.partition_number
)
INSERT INTO dmv_IndexBaseLine
    (server_name, database_name, database_id, schema_id, schema_name, object_id, table_name, index_id, index_name, is_unique, type_desc, partition_number, reserved_page_count, size_in_mb, buffered_page_count, buffer_mb, pct_in_buffer, row_count, page_count, existing_ranking
    , user_total_read, user_total_read_pct
    , user_total_write, user_total_write_pct
    , user_seeks, user_scans, user_lookups,user_updates
    , row_lock_count, row_lock_wait_count, row_lock_wait_in_ms, row_block_pct, avg_row_lock_waits_ms
    , page_lock_count, page_lock_wait_count, page_lock_wait_in_ms, page_block_pct, avg_page_lock_waits_ms
    , splits, indexed_columns, included_columns, indexed_columns_compare, included_columns_compare)
SELECT @@SERVERNAME
,DB_Name(t.database_id)
,t.database_id 
,s.schema_id
,s.name as schema_name
,t.object_id
,t.name as table_name
,i.index_id
,COALESCE(i.name, ''N/A'') as index_name
,i.is_unique
,CASE WHEN i.is_unique = 1 THEN ''UNIQUE '' ELSE '''' END + i.type_desc as type_desc
,ps.partition_number
,ps.reserved_page_count 
,CAST(reserved_page_count * CAST(8 as float) / 1024 as decimal(12,2)) as size_in_mb
,mb.buffered_page_count
,mb.buffer_mb
,CAST(100*buffer_mb/NULLIF(CAST(reserved_page_count * CAST(8 as float) / 1024 as decimal(12,2)),0) AS decimal(12,2)) as pct_in_buffer
,row_count
,used_page_count
,ROW_NUMBER()
OVER (PARTITION BY i.object_id ORDER BY i.is_primary_key desc, ius.user_seeks + ius.user_scans + ius.user_lookups desc) as existing_ranking

,ius.user_seeks + ius.user_scans + ius.user_lookups as user_total_read
,COALESCE(CAST(100 * (ius.user_seeks + ius.user_scans + ius.user_lookups)
/(NULLIF(SUM(ius.user_seeks + ius.user_scans + ius.user_lookups) 
OVER(PARTITION BY i.object_id), 0) * 1.) as decimal(6,2)),0) as user_total_read_pct

,ius.user_updates as user_total_write
,COALESCE(CAST(100 * (ius.user_updates)
/(NULLIF(SUM(ius.user_updates) 
OVER(PARTITION BY i.object_id), 0) * 1.) as decimal(6,2)),0) as user_total_write_pct
,ius.user_seeks
,ius.user_scans
,ius.user_lookups
,ius.user_updates

,ios.row_lock_count 
,ios.row_lock_wait_count 
,ios.row_lock_wait_in_ms 
,CAST(100.0 * ios.row_lock_wait_count/NULLIF(ios.row_lock_count, 0) AS decimal(12,2)) AS row_block_pct 
,CAST(1. * ios.row_lock_wait_in_ms /NULLIF(ios.row_lock_wait_count, 0) AS decimal(12,2)) AS avg_row_lock_waits_ms 

,ios.page_lock_count 
,ios.page_lock_wait_count 
,ios.page_lock_wait_in_ms 
,CAST(100.0 * ios.page_lock_wait_count/NULLIF(ios.page_lock_count, 0) AS decimal(12,2)) AS page_block_pct 
,CAST(1. * ios.page_lock_wait_in_ms /NULLIF(ios.page_lock_wait_count, 0) AS decimal(12,2)) AS avg_page_lock_waits_ms 

,ios.leaf_allocation_count + ios.nonleaf_allocation_count AS [Splits]

,STUFF((SELECT '', '' + QUOTENAME(c.name)
FROM dbaperf.dbo.vw_AllDB_index_columns ic
JOIN dbaperf.dbo.vw_AllDB_columns c 
ON ic.database_id = c.database_id 
AND ic.object_id = c.object_id 
AND ic.column_id = c.column_id
    WHERE is_included_column = 0
     AND i.database_id = ic.database_id 
     AND i.object_id = ic.object_id
     AND i.index_id = ic.index_id
    ORDER BY key_ordinal ASC
    FOR XML PATH('''')), 1, 2, '''') AS indexed_columns
    ,STUFF((SELECT '', '' + QUOTENAME(c.name)
    FROM dbaperf.dbo.vw_AllDB_index_columns ic
    JOIN dbaperf.dbo.vw_AllDB_columns c 
ON ic.database_id = c.database_id 
AND ic.object_id = c.object_id 
AND ic.column_id = c.column_id
    WHERE i.database_id = ic.database_id 
    AND i.object_id = ic.object_id
    AND i.index_id = ic.index_id
    
    AND is_included_column = 1
    ORDER BY key_ordinal ASC
    FOR XML PATH('''')), 1, 2, '''') AS included_columns
    ,(SELECT QUOTENAME(ic.column_id,''('')
    FROM dbaperf.dbo.vw_AllDB_index_columns ic
    WHERE i.database_id = ic.database_id 
    AND i.object_id = ic.object_id
    AND i.index_id = ic.index_id
    AND is_included_column = 0
    ORDER BY key_ordinal ASC
    FOR XML PATH('''')) AS indexed_columns_compare
    ,COALESCE((SELECT QUOTENAME(ic.column_id, ''('')
    FROM dbaperf.dbo.vw_AllDB_index_columns ic
    WHERE i.database_id = ic.database_id 
    AND i.object_id = ic.object_id
    AND i.index_id = ic.index_id
    AND is_included_column = 1
    ORDER BY key_ordinal ASC
    FOR XML PATH('''')), SPACE(0)) AS included_columns_compare
FROM dbaperf.dbo.vw_AllDB_tables t
JOIN dbaperf.dbo.vw_AllDB_schemas s 
    ON t.database_id = s.database_id
    AND t.schema_id = s.schema_id
    
JOIN dbaperf.dbo.vw_AllDB_indexes i 
    ON t.database_id = i.database_id
    AND t.object_id = i.object_id
    
JOIN dbaperf.dbo.vw_AllDB_dm_db_partition_stats ps 
    ON i.database_id = ps.database_id
    AND i.object_id = ps.object_id 
    AND i.index_id = ps.index_id
    
LEFT JOIN sys.dm_db_index_usage_stats ius 
    ON i.database_id = ius.database_id
    AND i.object_id = ius.object_id 
    AND i.index_id = ius.index_id 
    
LEFT JOIN sys.dm_db_index_operational_stats(@database_id, @object_id, NULL, NULL) ios 
    ON ps.database_id = ios.database_id
    AND ps.object_id = ios.object_id 
    AND ps.index_id = ios.index_id 
    AND ps.partition_number = ios.partition_number
    
LEFT JOIN MemoryBuffer mb 
    ON ps.database_id = mb.database_id
    AND ps.object_id = mb.object_id 
    AND ps.index_id = mb.index_id 
    AND ps.partition_number = mb.partition_number
    
WHERE (t.database_id = @database_id OR @database_id IS NULL OR @PopulateDMVsForAll = 1)
    AND (t.object_id = @object_id OR @object_id IS NULL OR @PopulateDMVsForAll = 1)


INSERT INTO dmv_IndexBaseLine
    (server_name, database_name, database_id, schema_id, schema_name, object_id, table_name, index_name
    , type_desc, impact, existing_ranking, user_total_read, user_seeks, user_scans, user_lookups, indexed_columns
    , indexed_column_count, included_columns, included_column_count)
SELECT @@Servername
,db_name(mid.database_id)
,mid.database_id
,s.schema_id
,s.name AS schema_name
,t.object_id
,t.name AS table_name
,''IX_''+t.name
+COALESCE((SELECT ''_''+CAST(column_id AS VarChar)
FROM dbaadmin.dbo.dbaudf_split(equality_columns,'','') T1
JOIN dbaperf.dbo.vw_AllDB_columns T2
ON LTRIM(RTRIM(REPLACE(REPLACE(T1.SplitValue,''['',''''),'']'',''''))) = T2.name
AND T2.database_id = t.database_id
AND T2.object_id = t.object_id
order by OccurenceId
FOR XML PATH('''')),'''')
+COALESCE((SELECT ''_''+CAST(column_id AS VarChar)
FROM dbaadmin.dbo.dbaudf_split(inequality_columns,'','') T1
JOIN dbaperf.dbo.vw_AllDB_columns T2
ON LTRIM(RTRIM(REPLACE(REPLACE(T1.SplitValue,''['',''''),'']'',''''))) = T2.name
AND T2.database_id = t.database_id
AND T2.object_id = t.object_id
order by OccurenceId
FOR XML PATH('''')),'''')
+CASE WHEN included_columns IS NULL THEN '''' ELSE ''_INC'' END
+COALESCE((SELECT ''_''+CAST(column_id AS VarChar)
FROM dbaadmin.dbo.dbaudf_split(included_columns,'','') T1
JOIN dbaperf.dbo.vw_AllDB_columns T2
ON LTRIM(RTRIM(REPLACE(REPLACE(T1.SplitValue,''['',''''),'']'',''''))) = T2.name
AND T2.database_id = t.database_id
AND T2.object_id = t.object_id
order by OccurenceId
FOR XML PATH('''')),'''')
,''--NONCLUSTERED--'' AS type_desc
,(migs.user_seeks + migs.user_scans) * migs.avg_user_impact as impact
,0 AS existing_ranking
,migs.user_seeks + migs.user_scans as user_total_read
,migs.user_seeks 
,migs.user_scans
,0 as user_lookups
,COALESCE(equality_columns,'''')
+COALESCE(CASE WHEN equality_columns IS NULL THEN '''' ELSE '', '' END + inequality_columns,'''') as indexed_columns
,(LEN(COALESCE(equality_columns + '', '', SPACE(0)) + COALESCE(inequality_columns, SPACE(0))) - LEN(REPLACE(COALESCE(equality_columns + '', '', SPACE(0)) + COALESCE(inequality_columns, SPACE(0)),''['',''''))) indexed_column_count
,'', ''+ included_columns 
,(LEN(included_columns) - LEN(REPLACE(included_columns,''['',''''))) included_column_count
FROM dbaperf.dbo.vw_AllDB_tables t
JOIN dbaperf.dbo.vw_AllDB_schemas s 
ON t.database_id = s.database_id
AND t.schema_id = s.schema_id
JOIN sys.dm_db_missing_index_details mid 
ON t.database_id = mid.database_id
AND t.object_id = mid.object_id
JOIN sys.dm_db_missing_index_groups mig 
ON mid.index_handle = mig.index_handle
JOIN sys.dm_db_missing_index_group_stats migs 
ON mig.index_group_handle = migs.group_handle
   
WHERE (t.database_id = @database_id OR @database_id IS NULL OR @PopulateDMVsForAll = 1)
AND (t.object_id = @object_id OR @object_id IS NULL OR @PopulateDMVsForAll = 1)

UPDATE T1
SET size_in_mb = 
[dbaperf].[dbo].[dbaudf_GetLeafLevelIndexSpace] 
(
T1.indexed_column_count
,0
,0
,T3.TotalIndexKeySize
,98
,T2.row_count)/1000.00/1000.00
+
[dbaperf].[dbo].[dbaudf_getIndexSpace] (
T1.indexed_column_count
,0
,0
,T3.TotalIndexKeySize
,T2.row_count)/1000.00/1000.00
,max_key_size = T3.TotalIndexKeySize
FROM dmv_IndexBaseLine T1
JOIN dmv_IndexBaseLine T2
ON T1.database_id = T2.database_id
AND T1.object_id = T2.Object_id
AND T2.type_desc IN (''CLUSTERED'', ''HEAP'', ''UNIQUE CLUSTERED'')
JOIN (
Select T1.row_id
,SUM(T3.max_length)AS TotalIndexKeySize
FROM dmv_IndexBaseLine T1
CROSS APPLY dbaadmin.dbo.dbaudf_split(indexed_columns,'','') T2
JOIN dbaperf.dbo.vw_AllDB_columns T3
ON T1.database_id = T3.database_id
AND T1.object_id = T3.object_id
AND ltrim(rtrim(T2.SplitValue)) = QUOTENAME(T3.name)
WHERE type_desc = ''--NONCLUSTERED--''
GROUP BY T1.row_id
) T3
ON T1.row_id = T3.row_id
where T2.row_count > 0



INSERT INTO #ForeignKeys
    (database_id, foreign_key_name, object_id, fk_columns, fk_columns_compare)
SELECT fk.database_id, fk.name + ''|PARENT'' AS foreign_key_name
    ,fkc.parent_object_id AS object_id
    ,STUFF((SELECT '', '' + QUOTENAME(c.name)
FROM dbaperf.dbo.vw_AllDB_foreign_key_columns ifkc
JOIN dbaperf.dbo.vw_AllDB_columns c
ON ifkc.database_id = c.database_id  
AND ifkc.parent_object_id = c.object_id 
AND ifkc.parent_column_id = c.column_id
WHERE fk.database_id = ifkc.database_id
AND fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('''')), 1, 2, '''') AS fk_columns
    ,( SELECT QUOTENAME(ifkc.parent_column_id,''('')
FROM dbaperf.dbo.vw_AllDB_foreign_key_columns ifkc
WHERE fk.database_id = ifkc.database_id
AND fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('''')) AS fk_columns_compare
FROM dbaperf.dbo.vw_AllDB_foreign_keys fk
JOIN dbaperf.dbo.vw_AllDB_foreign_key_columns fkc 
ON fk.database_id = fkc.database_id
AND fk.object_id = fkc.constraint_object_id
WHERE fkc.constraint_column_id = 1
AND (fkc.database_id = @database_id OR @database_id IS NULL OR @PopulateDMVsForAll = 1)
AND (fkc.parent_object_id = @object_id OR @object_id IS NULL OR @PopulateDMVsForAll = 1)
UNION ALL
SELECT fk.database_id, fk.name + ''|REFERENCED'' as foreign_key_name
    ,fkc.referenced_object_id AS object_id
    ,STUFF(( SELECT '', '' + QUOTENAME(c.name)
FROM dbaperf.dbo.vw_AllDB_foreign_key_columns ifkc
JOIN dbaperf.dbo.vw_AllDB_columns c 
ON ifkc.database_id = c.database_id 
AND ifkc.referenced_object_id = c.object_id 
AND ifkc.referenced_column_id = c.column_id
WHERE fk.database_id = ifkc.database_id
AND fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('''')), 1, 2, '''') AS fk_columns
    ,( SELECT QUOTENAME(ifkc.referenced_column_id,''('')
FROM dbaperf.dbo.vw_AllDB_foreign_key_columns ifkc
WHERE fk.database_id = ifkc.database_id
AND fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('''')) AS fk_columns_compare
FROM dbaperf.dbo.vw_AllDB_foreign_keys fk
JOIN dbaperf.dbo.vw_AllDB_foreign_key_columns fkc 
ON fk.database_id = fkc.database_id
AND fk.object_id = fkc.constraint_object_id
WHERE fkc.constraint_column_id = 1
AND (fkc.database_id = @database_id OR @database_id IS NULL OR @PopulateDMVsForAll = 1)
AND (fkc.referenced_object_id = @object_id OR @object_id IS NULL OR @PopulateDMVsForAll = 1)

UPDATE ibl
SET duplicate_indexes = STUFF(( SELECT '', '' + index_name AS [data()]
FROM dmv_IndexBaseLine iibl
WHERE ibl.database_id = iibl.database_id
 AND ibl.object_id = iibl.object_id
 AND ibl.index_id <> iibl.index_id
 AND ibl.indexed_columns_compare = iibl.indexed_columns_compare
 AND ibl.included_columns_compare = iibl.included_columns_compare
FOR XML PATH('''')), 1, 2, '''')
,overlapping_indexes = STUFF(( SELECT '', '' + index_name AS [data()]
FROM dmv_IndexBaseLine iibl
WHERE ibl.object_id = iibl.object_id
 AND ibl.index_id <> iibl.index_id
 AND (ibl.indexed_columns_compare LIKE iibl.indexed_columns_compare + ''%'' 
 OR iibl.indexed_columns_compare LIKE ibl.indexed_columns_compare + ''%'')
 AND ibl.indexed_columns_compare <> iibl.indexed_columns_compare 
FOR XML PATH('''')), 1, 2, '''')
,related_foreign_keys = STUFF(( SELECT '', '' + foreign_key_name AS [data()]
FROM #ForeignKeys ifk
WHERE ifk.object_id = ibl.object_id
 AND ibl.indexed_columns_compare LIKE ifk.fk_columns_compare + ''%''
FOR XML PATH('''')), 1, 2, '''')
,related_foreign_keys_xml = CAST(( SELECT foreign_key_name
FROM #ForeignKeys ForeignKeys
WHERE ForeignKeys.object_id = ibl.object_id
 AND ibl.indexed_columns_compare LIKE ForeignKeys.fk_columns_compare + ''%''
FOR XML AUTO) as xml) 
FROM dmv_IndexBaseLine ibl

INSERT INTO dmv_IndexBaseLine
    (server_name, database_name, database_id, schema_id, schema_name, object_id, table_name, index_name, type_desc, existing_ranking, indexed_columns)
SELECT @@ServerName
,DB_Name(t.database_id)
,t.database_id
,s.schema_id
,s.name AS schema_name
,t.object_id
,t.name AS table_name
,fk.foreign_key_name AS index_name
,''--MISSING FOREIGN KEY--'' as type_desc
,9999
,fk.fk_columns
FROM dbaperf.dbo.vw_AllDB_tables t
JOIN dbaperf.dbo.vw_AllDB_schemas s 
ON t.database_id = s.database_id
AND t.schema_id = s.schema_id
JOIN #ForeignKeys fk 
ON t.database_id = fk.database_id
AND t.object_id = fk.object_id
LEFT JOIN dmv_IndexBaseLine ia 
ON fk.database_id = ia.database_id 
AND fk.object_id = ia.object_id 
AND ia.indexed_columns_compare LIKE fk.fk_columns_compare + ''%''
WHERE ia.index_name IS NULL;


;WITH ReadAggregation
AS (
SELECT row_id
,CAST(100. * (user_seeks + user_scans + user_lookups)
    /(NULLIF(SUM(user_seeks + user_scans + user_lookups) 
    OVER(PARTITION BY database_id, schema_name, table_name), 0) * 1.) as decimal(12,2)) AS estimated_user_total_pct
,SUM(buffer_mb) OVER(PARTITION BY database_id, schema_name, table_name) as table_buffer_mb
FROM dmv_IndexBaseLine
)
,WriteAggregation
AS (
SELECT row_id
,CAST((100.00 * user_updates)
    /(NULLIF(SUM(user_updates) 
    OVER(PARTITION BY database_id, schema_name, table_name), 0) * 1.) as decimal(12,2)) AS estimated_user_total_pct
FROM dmv_IndexBaseLine 
)
UPDATE ibl
SET estimated_user_total_read_pct = COALESCE(r.estimated_user_total_pct, 0.00)
,estimated_user_total_write_pct = COALESCE(w.estimated_user_total_pct, 0.00)
,table_buffer_mb = r.table_buffer_mb
,index_read_pct = (COALESCE(user_total_read,0.00) * 100.00) / CASE WHEN COALESCE(user_total_read,0.00) + COALESCE(user_total_write,0.00) = 0.00 THEN 1.00 ELSE COALESCE(user_total_read,0.00) + COALESCE(user_total_write,0.00) END
,index_write_pct = (COALESCE(user_total_write,0.00) * 100.00) / CASE WHEN COALESCE(user_total_read,0.00) + COALESCE(user_total_write,0.00) = 0.00 THEN 1.00 ELSE COALESCE(user_total_read,0.00) + COALESCE(user_total_write,0.00) END
FROM dmv_IndexBaseLine ibl
JOIN ReadAggregation r 
ON ibl.row_id = r.row_id
JOIN WriteAggregation w 
ON ibl.row_id = w.row_id


;WITH IndexAction
AS (
    SELECT row_id
,CASE WHEN user_lookups > user_seeks AND type_desc IN (''CLUSTERED'', ''HEAP'', ''UNIQUE CLUSTERED'') THEN ''REALIGN''
    WHEN type_desc = ''--MISSING FOREIGN KEY--'' THEN ''CREATE''
    WHEN type_desc = ''XML'' THEN ''---''
    WHEN is_unique = 1 THEN ''---''
    WHEN type_desc = ''--NONCLUSTERED--'' AND ROW_NUMBER() OVER (PARTITION BY table_name ORDER BY user_total_read desc) <= 10 AND estimated_user_total_read_pct > 1 THEN ''CREATE''
    WHEN type_desc = ''--NONCLUSTERED--'' THEN ''BLEND''
    WHEN ROW_NUMBER() OVER (PARTITION BY database_id, table_name ORDER BY user_total_read desc, existing_ranking) > 10 THEN ''DROP'' 
    WHEN user_total_read = 0 THEN ''DROP'' 
    ELSE ''---'' END AS index_action
    FROM dmv_IndexBaseLine
)
UPDATE ibl
SET index_action = ia.index_action
FROM dmv_IndexBaseLine ibl 
JOIN IndexAction ia
ON ibl.row_id = ia.row_id

UPDATE ibl
SET has_unique = 1
FROM dmv_IndexBaseLine ibl
JOIN (
SELECT DISTINCT
database_id 
,object_id 
FROM dbaperf.dbo.vw_AllDB_indexes i 
WHERE i.is_unique = 1
) x 
ON ibl.database_id = x.database_id
AND ibl.object_id = x.object_id
END




SELECT @Database_Name = COALESCE(@Database_Name,''NULL'')
,@Schema_Name = COALESCE(@Schema_Name,''NULL'')
,@Table_Name = COALESCE(@Table_Name,''NULL'')

-------------------------------------------------------
-------------------------------------------------------
-- EXPORT DATA dbaperf.dbo.dmv_IndexBaseLine
-------------------------------------------------------
-------------------------------------------------------


SET @Export_Source = ''dbaperf.dbo.dmv_IndexBaseLine''
SELECT @FileName = REPLACE([dbaadmin].[dbo].[dbaudf_base64_encode] (@@SERVERNAME+''|''+REPLACE(@Export_Source,''dbaperf.dbo.'','''')+''|''+@Database_Name+''|''+@Schema_Name+''|''+@Table_Name)+''.dat'',''='',''$'')
SET @SCRIPT = ''bcp ''+@Export_Source+'' out "''+@LocalPath+''\''+@FileName+''" -S ''+@@Servername+'' -T -N''
--Print @Script

Print ''Exporting Data from '' + @Export_Source
PRINT ''To File: '' + @FileName
EXEC xp_cmdshell @SCRIPT, no_output

Print ''Sending Data from '' + @Export_Source
EXEC [dbaadmin].[dbo].[dbasp_File_Transit] 
@source_name = @FileName
,@source_path = @UNCPath
,@target_env = @target_env
,@target_server = @target_server
,@target_share = @target_share
,@retry_limit = @retry_limit
  
waitfor delay ''00:00:05''  
  
-- DELETE FILE AFTER SENDING
SET @Script = ''DEL "''+ @UNCPath+''\''+@FileName+''"''
--Print @Script

Print ''Deleting File from '' + @Export_Source
exec master..xp_cmdshell @Script, no_output


-------------------------------------------------------
-------------------------------------------------------
-- EXPORT DATA dbaperf.dbo.dmv_MissingIndexSnapshot
-------------------------------------------------------
-------------------------------------------------------

SET @Export_Source = ''dbaperf.dbo.dmv_MissingIndexSnapshot''
SELECT @FileName = REPLACE([dbaadmin].[dbo].[dbaudf_base64_encode] (@@SERVERNAME+''|''+REPLACE(@Export_Source,''dbaperf.dbo.'','''')+''|''+@Database_Name+''|''+@Schema_Name+''|''+@Table_Name)+''.dat'',''='',''$'')
SET @SCRIPT = ''bcp ''+@Export_Source+'' out "''+@LocalPath+''\''+@FileName+''" -S ''+@@Servername+'' -T -N''
--Print @Script

Print ''Exporting Data from '' + @Export_Source
PRINT ''To File: '' + @FileName
EXEC xp_cmdshell @SCRIPT, no_output

Print ''Sending Data from '' + @Export_Source
EXEC [dbaadmin].[dbo].[dbasp_File_Transit] 
@source_name = @FileName
,@source_path = @UNCPath
,@target_env = @target_env
,@target_server = @target_server
,@target_share = @target_share
,@retry_limit = @retry_limit
  
waitfor delay ''00:00:05''  
  
-- DELETE FILE AFTER SENDING
SET @Script = ''DEL "''+ @UNCPath+''\''+@FileName+''"''
--Print @Script

Print ''Deleting File from '' + @Export_Source
exec master..xp_cmdshell @Script, no_output
END
GO



AgentJob [UTIL - PERF - GIMPI Collect and Export]
This job is only created and enabled on servers select to report on. If this job doesn't fire the sproc, then everything is just sitting there waiting to be used. The scheduling of this job can vary depending on how responsive your developers are and how quickly changes can be tested and deployed. It doesn't make any sense to run this hourly if the fastest turnaround you can do is weekly.




/**************************************************************
Generated SQL - SYSaddjobs
For Server: G1SQLA\A on Jun  9 2010 12:02:32:860PM
NOTE:  The following SQL jobs were scripted using the input parm
       @leave_enabled = 'y'.
**************************************************************/
use [msdb]
go
/*************************************************************************************************
Create new job: UTIL - PERF - GIMPI Collect and Export
**************************************************************************************************/
BEGIN TRANSACTION
  DECLARE @JobID BINARY(16)
  DECLARE @ReturnCode INT
  DECLARE @charpos INT
  DECLARE @miscprint nvarchar(500)
  DECLARE @save_servername sysname
  DECLARE @save_servername2 sysname
  DECLARE @save_servername3 sysname
  DECLARE @save_servername4b sysname
  DECLARE @save_output_filename sysname
  DECLARE @save_jname sysname
  DECLARE @save_sname sysname
  DECLARE @parm01 sysname
  DECLARE @logpath sysname
  Select  @ReturnCode = 0
  -- Set up the servername variables
  Select @save_servername = @@servername
  Select @save_servername2 = @@servername
  Select @save_servername3 = @@servername
  Select @save_servername4b = @@servername
  Select @charpos = charindex('\', @save_servername)
  IF @charpos <> 0
     begin
        Select @save_servername = substring(@@servername, 1, (CHARINDEX('\', @@servername)-1))
        Select @save_servername2 = stuff(@save_servername2, @charpos, 1, '$')
        Select @save_servername3 = stuff(@save_servername3, @charpos, 1, '(')
        Select @save_servername3 = @save_servername3 + ')'
        Select @save_servername4b = stuff(@save_servername4b, @charpos, 1, '_')
     end
  -- Set up the output file path variable
  Select @parm01 = @save_servername2 + '_SQLjob_logs'
  If exists(select 1 from master.sys.sysdatabases where name = 'dbaadmin')
     begin
        exec dbaadmin.dbo.dbasp_get_share_path @parm01, @logpath output
     end
  -- Verify the proper category exists
  IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
     begin
        EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'Job', @type=N'Local', @name=N'[Uncategorized (Local)]'
        IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
     end
  -- Delete the job with the same name (if it exists)
  Select @JobID = job_id
  from   msdb.dbo.sysjobs
  where (name = N'UTIL - PERF - GIMPI Collect and Export')
  If (@JobID is not null)
     begin
        -- Check if the job is a multi-server job
        IF (exists (Select * From msdb.dbo.sysjobservers
                    Where (job_id = @JobID) and (server_id <> 0)))
           begin
              -- This is a mult server job, so abort the script
              Select @miscprint = 'Unable to delete job ''UTIL - PERF - GIMPI Collect and Export'' since there is already a multi-server job with this name.'
              RAISERROR (@miscprint, 16, 1)
              GOTO QuitWithRollback
           end
        Else
           begin
              -- Delete the [local] job
              Select @miscprint = N'UTIL - PERF - GIMPI Collect and Export'
              EXEC msdb.dbo.sp_delete_job @job_name = @miscprint
              Select @JobID = null
           end
     end
  -- Add the job
  Select @save_jname = N'UTIL - PERF - GIMPI Collect and Export'
  EXEC @ReturnCode = msdb.dbo.sp_add_job @job_id = @JobID OUTPUT
                                           ,@job_name = @save_jname
                                           ,@owner_login_name = N'sa'
                                           ,@description = N'Collect and Export Index Performance Data to support the GIMPI Reports'
                                           ,@category_name = N'[Uncategorized (Local)]'
                                           ,@enabled = 1
                                           ,@notify_level_email = 0
                                           ,@notify_level_page = 0
                                           ,@notify_level_netsend = 0
                                           ,@notify_level_eventlog = 0
                                           ,@delete_level= 0
  IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
  -- Preparation for job step 1
  -- Move the output file name and path to a variable
  Select @save_output_filename = '\\g1sqla\G1SQLA$A_SQLjob_logs\UTIL_PERF_EXPORT_IndexAnalysisReport_Data.txt'
  -- Move the command syntax for this job step to a variable
  Declare @command_vrb1  NVARCHAR(MAX)
  Select @command_vrb1 = ''
  Select  @command_vrb1 = @command_vrb1 + 'exec dbaperf.dbo.dbasp_GIMPI_CaptureAndExport'
  -- Add job step 1
  Select @save_sname = N'Export Data'
  EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID
                                               ,@step_id = 1
                                               ,@step_name = @save_sname
                                               ,@command = @command_vrb1
                                               ,@database_name = N'master'
                                               ,@server = N''
                                               ,@database_user_name = N''
                                               ,@subsystem = N'TSQL'
                                               ,@cmdexec_success_code = 0
                                               ,@flags = 6
                                               ,@retry_attempts = 0
                                               ,@retry_interval = 0
                                               ,@os_run_priority = 0
                                               ,@output_file_name = @save_output_filename
                                               ,@on_success_step_id = 0
                                               ,@on_success_action = 1
                                               ,@on_fail_step_id = 0
                                               ,@on_fail_action = 2
  IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
  -- Add the job schedules
  EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id = @JobID
                                                   ,@name = N'Daily at 1AM'
                                                   ,@enabled = 1
                                                   ,@freq_type = 4
                                                   ,@active_start_date = 20100507
                                                   ,@active_start_time = 10000
                                                   ,@freq_interval = 1
                                                   ,@freq_subday_type = 1
                                                   ,@freq_subday_interval = 1
                                                   ,@freq_relative_interval = 0
                                                   ,@freq_recurrence_factor = 0
                                                   ,@active_end_date = 99991231
                                                   ,@active_end_time = 235959
  IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
  -- Update the job start step
  EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID, @start_step_id = 1
  IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
  -- Add the Target Servers
  EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)'
  IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
  -- Update Production Job Status Info
  IF exists(select * from master.sys.sysdatabases where name = 'DEPLinfo')
     begin
  IF exists(select * from DEPLinfo.sys.objects where name = 'ProdJobStatus')
     begin
  IF exists(select * from DEPLinfo.dbo.ProdJobStatus where JobName = 'UTIL - PERF - GIMPI Collect and Export')
     begin
  update DEPLinfo.dbo.ProdJobStatus set JobStatus = 1 where JobName = 'UTIL - PERF - GIMPI Collect and Export'
     end
  ELSE
     begin
  insert into DEPLinfo.dbo.ProdJobStatus (JobName, JobStatus) values ('UTIL - PERF - GIMPI Collect and Export', 1)
     end
     end
     end
COMMIT TRANSACTION
GOTO   EndSave
QuitWithRollback:
  IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION 
EndSave:
GO


There is a lot here and I hope I didn't introduce any typos in my process of trying to make it readable for you. feel free to let me know if I screwed it up or if it could be better.





No comments:

Post a Comment