/*============================================================================= 

 User guide 
  ---------------------------------------------------

  01. Create Table [Monitoring_area]
  02. Create Table [Monitoring_counter]
  03. Create Table [Monitoring_history]
  04. Create Table [Monitoring_threshold]
  
  05. Create Indexes [NCIX_MonitoringHistory_MHDatetime]
  06. Create Index [NCIX_MonitoringHistory_COL_MHMonitoringCounter]
  
  07. Create Security User
  
  08. Insert Data in [Monitoring_area]
  09. Insert Data in [Monitoring_counter]
  10. Insert Data in [Monitoring_threshold]
  
  11. Create Stored Procedures [mon_Collect_Counters_History]
  12. Create Stored Procedures [mon_Get_Counters_History] 
  
  13. Create Job [DR92170 - Monitoring SQL Server Performances]
  
 Usage context
  ------------------------------------------
    To get sensor in the server and make a server reporting 

     
 Parameters
  ------------------------------------------

 Creation : 18.07.18 / KLU

 Modification :
    23.07.2018/LPE : Add [MC_type]=5 in SP [mon_Collect_Counters_History] to get aggregate values.
                     Modify [MC_type] from 2 to 5 for counter "Deadlock".
    26.07.2018/LPE : Add counter "Processes blocked"
    19.09.2018/SPE : #BUG 48620# [MH_value] could be NULL in table [HCITools].[dbo].[Monitoring_history]
    08.11.2018/FLA : Add counter "Memory Grants Outstanding"
    15.11.2019/LPE : #TFS56565# Optimize performance of table [HCITools].[dbo].[Monitoring_counter]
    17.03.2022/FLA : Change DBA mail
=============================================================================*/ 


/***************************************************************/
/**********      Create Table [Monitoring_area]    *************/
/***************************************************************/
USE [HCITools]
GO

/* ***** Object:  Table [dbo].[Monitoring_area]    Script Date: 12.07.2018 11:49:12 ***** */
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Monitoring_area]') AND type in (N'U'))
BEGIN

CREATE TABLE [dbo].[Monitoring_area](
     [Monitoring_area_ID] [bigint] IDENTITY(1,1) NOT NULL,
     [MA_name] [nvarchar](60) NOT NULL,
 CONSTRAINT [PK_Monitoring_area] PRIMARY KEY CLUSTERED 
(
     [Monitoring_area_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO

/*****************************************************************/
/**********      Create Table [Monitoring_counter]    ************/
/*****************************************************************/

USE [HCITools]
GO

/****** Object:  Table [dbo].[Monitoring_counter]    Script Date: 12.07.2018 12:52:58 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Monitoring_counter]') AND type in (N'U'))
BEGIN

CREATE TABLE [dbo].[Monitoring_counter](
     [Monitoring_counter_ID] [bigint] IDENTITY(1,1) NOT NULL,
     [MC_name] [nvarchar](60) NOT NULL,
     [MC_type] [smallint] NOT NULL,
     [MC_sql_query] [nvarchar](max) NULL,
     [MC_definition] [nvarchar](max) NULL,
     [MC_information] [nvarchar](max) NULL,
     [MC_problem] [nvarchar](max) NULL,
     [MC_remediation] [nvarchar](max) NULL,
     [MC_sequence] [smallint] NULL,
     [MC_is_visible] [bit] NOT NULL,
     [MC_monitoring_area] [bigint] NOT NULL,
 CONSTRAINT [PK_Monitoring_counter] PRIMARY KEY CLUSTERED 
(
     [Monitoring_counter_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
END
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF_Monitoring_counter_MC_is_visible]') AND type = 'D')
BEGIN
ALTER TABLE [dbo].[Monitoring_counter] ADD  CONSTRAINT [DF_Monitoring_counter_MC_is_visible]  DEFAULT ((1)) FOR [MC_is_visible]
END
GO
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Monitoring_counter_Monitoring_area]') AND parent_object_id = OBJECT_ID(N'[dbo].[Monitoring_counter]'))
ALTER TABLE [dbo].[Monitoring_counter]  WITH CHECK ADD  CONSTRAINT [FK_Monitoring_counter_Monitoring_area] FOREIGN KEY([MC_monitoring_area])
REFERENCES [dbo].[Monitoring_area] ([Monitoring_area_ID])
GO
IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Monitoring_counter_Monitoring_area]') AND parent_object_id = OBJECT_ID(N'[dbo].[Monitoring_counter]'))
ALTER TABLE [dbo].[Monitoring_counter] CHECK CONSTRAINT [FK_Monitoring_counter_Monitoring_area]
GO

/*****************************************************************/
/**********      Create Table [Monitoring_history]    ************/
/*****************************************************************/

USE [HCITools]
GO

/****** Object:  Table [dbo].[Monitoring_history]    Script Date: 16.07.2018 13:18:06 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Monitoring_history]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[Monitoring_history](
     [Monitoring_history_ID] [bigint] IDENTITY(1,1) NOT NULL,
     [MH_instance_name] [nvarchar](128) NULL,
     [MH_value] [bigint] NULL,                                                                                               -- [# SPE]
     [MH_original_value] [bigint] NULL,
     [MH_datetime] [datetime] NOT NULL,
     [MH_monitoring_counter] [bigint] NOT NULL,
 CONSTRAINT [PK_Monitoring_history] PRIMARY KEY CLUSTERED 
(
     [Monitoring_history_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END

GO
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Monitoring_history_Monitoring_counter]') AND parent_object_id = OBJECT_ID(N'[dbo].[Monitoring_history]'))
ALTER TABLE [dbo].[Monitoring_history]  WITH CHECK ADD  CONSTRAINT [FK_Monitoring_history_Monitoring_counter] FOREIGN KEY([MH_monitoring_counter])
REFERENCES [dbo].[Monitoring_counter] ([Monitoring_counter_ID])
GO
IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Monitoring_history_Monitoring_counter]') AND parent_object_id = OBJECT_ID(N'[dbo].[Monitoring_history]'))
ALTER TABLE [dbo].[Monitoring_history] CHECK CONSTRAINT [FK_Monitoring_history_Monitoring_counter]
GO

/*****************************************************************/
/**********      Create Table [Monitoring_threshold]    **********/
/*****************************************************************/
USE [HCITools]
GO

/****** Object:  Table [dbo].[Monitoring_threshold]    Script Date: 16.07.2018 13:20:11 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Monitoring_threshold]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[Monitoring_threshold](
     [Monitoring_threshold_ID] [bigint] IDENTITY(1,1) NOT NULL,
     [MT_warning_threshold_low] [bigint] NULL,
     [MT_warning_threshold_high] [bigint] NULL,
     [MT_critical_threshold_low] [bigint] NULL,
     [MT_critical_threshold_high] [bigint] NULL,
     [MT_server_name] [nvarchar](256) NULL,
     [MT_monitoring_counter] [bigint] NOT NULL,
 CONSTRAINT [PK_Monitoring_threshold] PRIMARY KEY CLUSTERED 
(
     [Monitoring_threshold_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO

IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Monitoring_threshold_Monitoring_counter]') AND parent_object_id = OBJECT_ID(N'[dbo].[Monitoring_threshold]'))
ALTER TABLE [dbo].[Monitoring_threshold]  WITH CHECK ADD  CONSTRAINT [FK_Monitoring_threshold_Monitoring_counter] FOREIGN KEY([MT_monitoring_counter])
REFERENCES [dbo].[Monitoring_counter] ([Monitoring_counter_ID])
GO
IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Monitoring_threshold_Monitoring_counter]') AND parent_object_id = OBJECT_ID(N'[dbo].[Monitoring_threshold]'))
ALTER TABLE [dbo].[Monitoring_threshold] CHECK CONSTRAINT [FK_Monitoring_threshold_Monitoring_counter]
GO


/**********************************************************************************************************************************/
/*****************************************************************/
/**********   Indexes [NCIX_MonitoringHistory_MHDatetime] ********/
/*****************************************************************/

USE [HCITools]
GO

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'NCIX_MonitoringHistory_MHDatetime')
BEGIN
Print 'Creation of index NCIX_MonitoringHistory_MHDatetime on table Monitoring_history'

CREATE NONCLUSTERED INDEX [NCIX_MonitoringHistory_MHDatetime] ON [dbo].[Monitoring_history]
(
     [MH_datetime] ASC
)
INCLUDE (      [MH_value],
     [MH_monitoring_counter]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

END
Go

/*****************************************************************/
/**********   Indexes [NCIX_MonitoringHistory_MHDatetime] ********/
/*****************************************************************/

USE [HCITools]
GO

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'NCIX_MonitoringHistory_COL_MHMonitoringCounter')
BEGIN
Print 'Creation of index NCIX_MonitoringHistory_COL_MHMonitoringCounter on table Monitoring_history'

CREATE NONCLUSTERED INDEX [NCIX_MonitoringHistory_COL_MHMonitoringCounter] ON [dbo].[Monitoring_history] 
(
	[MH_monitoring_counter] ASC
)
INCLUDE ([MH_instance_name]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

END
GO

/**********************************************************************************************************************************/
/******************************************************************/
/********************    Create Security User   *******************/
/******************************************************************/

USE [HCITools]
GO
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = 'sqlMonPerfUsr')
BEGIN
CREATE USER [sqlMonPerfUsr] FOR LOGIN [sqlMonPerfUsr] WITH DEFAULT_SCHEMA=[dbo]
END
GO
use [HCITools]
GO
GRANT SELECT ON [dbo].[Monitoring_area] TO [sqlMonPerfUsr]
GO
use [HCITools]
GO
GRANT SELECT ON [dbo].[Monitoring_counter] TO [sqlMonPerfUsr]
GO
use [HCITools]
GO
GRANT SELECT ON [dbo].[Monitoring_history] TO [sqlMonPerfUsr]
GO

use [HCITools]
GO
GRANT SELECT ON [dbo].[Monitoring_threshold] TO [sqlMonPerfUsr]
GO

/**********************************************************************************************************************************/
/*****************************************************************/
/**********      Insert Data in [Monitoring_area]    *************/
/*****************************************************************/

USE [HCITools]
GO
SET IDENTITY_INSERT [dbo].[Monitoring_area] ON
IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'Buffer Manager')
BEGIN
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((1)
           ,('Buffer Manager')
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'Cache')
BEGIN
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((2)
           ,('Cache')
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'Latches and Locks')
BEGIN
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((3)
           ,('Latches and Locks')
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'Memory')
BEGIN
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((4)
           ,('Memory')
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'Pages')
BEGIN
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((5)
           ,('Pages')
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'SQL Server')
BEGIN
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((6)
           ,('SQL Server')
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'Connections')
BEGIN
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((7)
           ,('Connections')
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'Sessions')
BEGIN             
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((8)
           ,('Sessions')
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'Disk')
BEGIN
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((9)
           ,('Disk')
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_area] WHERE [MA_name] = 'Processes')
BEGIN
INSERT INTO [dbo].[Monitoring_area]
           ([Monitoring_area_ID]
            ,[MA_name])
     VALUES((10)
           ,('Processes')
           )
END
SET IDENTITY_INSERT [dbo].[Monitoring_area] OFF
GO

/*****************************************************************/
/**********      Insert Data in [Monitoring_counter]    **********/
/*****************************************************************/

USE [HCITools]
GO
SET IDENTITY_INSERT [dbo].[Monitoring_counter] ON
IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Buffer Cache Hit Ratio')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
           ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((1)
           ,('Buffer Cache Hit Ratio')
           ,(1)
           ,('SELECT CONVERT(decimal(15,2), 100.0 * t.CacheHitRatio / t.CacheHitRatioBase)
                 FROM (
                    SELECT(
                          SELECT cntr_value AS ''CacheHitRatio'' 
                            FROM sys.dm_os_performance_counters
                           WHERE object_name LIKE ''%:Buffer Manager%''
                              AND counter_name = ''Buffer cache hit ratio'' 
                      ) AS ''CacheHitRatio'',  
                      (
                          SELECT cntr_value AS ''CacheHitRatioBase'' 
                            FROM sys.dm_os_performance_counters
                           WHERE object_name LIKE ''%:Buffer Manager%''
                              AND counter_name = ''Buffer cache hit ratio base''
                      ) AS ''CacheHitRatioBase''
                    ) AS t;
               ')
           ,('Indicates the percentage of pages found in the buffer cache without having to read from disk. The ratio is the total number of cache hits divided by the total number of cache lookups over the last few thousand page accesses.')
           ,('After a long period of time, the ratio moves very little. Because reading from the cache is much less expensive than reading from disk, you want this ratio to be high. Generally, you can increase the buffer cache hit ratio by increasing the amount of memory available to SQL Server. The higher this ratio, the less often SQL Server has to go to the hard disk to fetch data, and performance is boosted overall. This counter averages the Buffer Cache Hit Ratio from the time the last instance of SQL Server was restarted. This counter is not a real-time measurement, but an average of all the days since SQL Server was last restarted. In OLAP (http://en.wikipedia.org/wiki/Online_analytical_processing) applications, the ratio could be much lower because of the nature of how OLAP works.')
           ,('If the returned value is low, this could indicate that your SQL server may not have enough memory to function at peak performance.')
           ,('Check your SQL server and verify its memory is being used efficiently. Applications other than SQL may be using a great deal of memory. Try and recover memory by closing unnecessary applications. Installing additional memory may also help.')
           ,(1)
           ,(1)
           ,(1)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Page Life Expectancy')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((2)
           ,('Page Life Expectancy')
           ,(1)
           ,('SELECT cntr_value
                 FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Buffer Manager%''
                    AND counter_name = ''Page Life Expectancy'';
               ')
           ,('This performance counter returns the number of seconds a page will stay in the buffer pool (http://msdn.microsoft.com/en-us/library/aa337525.aspx) without references.')
           ,('This performance monitor reports, on average, how long data pages are staying in the buffer.')
           ,('If this value gets below 300 seconds, this is a potential indication that your SQL Server could use more memory in order to boost performance. Consistently having pages that stay in memory for less than that amount of time may indicate the need for more memory.')
           ,('Add additional memory to your SQL server.')
           ,(1)
           ,(1)
           ,(5)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Lock Waits/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((3)
           ,('Lock Waits/sec')
           ,(2)
           ,('SELECT cntr_value
                 FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Locks%''
                    AND counter_name = ''Lock Waits/sec''
                    AND instance_name = ''_Total'';
               ')
           ,('This performance counter reports the number of times users waited to acquire a lock over the past second.')
           ,('Note that this counter only gets incremented only when you “wake up” after waiting on the lock. In order for thresholds to be tuned to your environment, thresholds for this performance counter should be set using the Baseline Calculator.')
           ,('Non-zero values indicate that there is at least some level of blocking (http://support.microsoft.com/kb/224453) occurring. If you combine this with the Lock Wait Time counter, you can get some idea of how long the blocking lasted. A zero value for this counter can definitively rule out blocking as a potential cause.')
           ,('High Read queries should be reviewed.')
           ,(1)
           ,(1)
           ,(3)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Page Reads/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((4)
           ,('Page Reads/sec')
           ,(2)
           ,('SELECT cntr_value
                 FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Buffer Manager%''
                    AND counter_name = ''Page reads/sec'';
               ')
           ,('This performance counter returns the number of physical database page reads issued.')
           ,('80 – 90 physical database page reads per second is normal.')
           ,('Returned values that are high could indicate indexing or memory constraint.')
           ,('Attempt to tune the application so that fewer I/O operations are required. For example, perhaps I/O operations would be reduced if there were the appropriate indexes, or if the database design were de-normalized. If the applications cannot be tuned, you will need to acquire disk devices with more capacity. Because physical I/O operations are expensive, you may be able to minimize the cost either by using a larger data cache, intelligent indexes, more efficient queries, or by changing the database design.')
           ,(1)
           ,(1)
           ,(5)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Page Writes/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((5)
           ,('Page Writes/sec')
           ,(2)
           ,('SELECT cntr_value
                 FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Buffer Manager%''
                    AND counter_name = ''Page writes/sec'';
               ')
           ,('This performance counter returns the number of physical database page writes issued.')
           ,('80 – 90 physical database page writes per second is normal.')
           ,('If the returned values are high, you should check the Lazy Writer/sec monitor and checkpoint counters. If the value for these counters is also relatively high then, it is a memory constraint.')
           ,(NULL)
           ,(1)
           ,(1)
           ,(5)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Full Scans/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((6)
           ,('Full Scans/sec')
           ,(2)
           ,('SELECT cntr_value
                 FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Access Methods%''
                    AND counter_name = ''Full Scans/sec'';
               ')
           ,('This performance counter returns the number of Full Scans on base tables or indexes.')
           ,('This is the number of unrestricted full scans per second. These can be either base-table or full-index scans. In order for thresholds to be tuned to your environment, thresholds for this performance counter should be set using the Baseline Calculator.')
           ,('Values greater than 1 or 2 indicate table/Index page scans are occurring. If the CPU is running high, you should investigate the cause as related to this counter measurement. You can rule this out as a problem if the full scans are on small tables.')
           ,('Following are a few of the main causes of high Full Scans/sec: • Missing indexes • Too many rows requested; Queries with missing indexes or too many rows requested will have a large number of logical reads and an increased CPU time. • Scans are IO-intensive and should run within your databases minimally. Identify the tables that have a large number of scans against them. Review the fill factor you have set up on your indexes and minimize it where appropriate.')
           ,(1)
           ,(1)
           ,(6)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'User Connections')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((7)
           ,('User Connections')
           ,(1)
           ,('SELECT cntr_value 
                 FROM sys.dm_os_performance_counters
                   WHERE object_name LIKE ''%:General Statistics%''
                   AND counter_name = ''User Connections'';
               ')
           ,('The User Connections performance counter identifies the number of different users that are connected to your SQL Server at the time the sample was taken.')
           ,('You need to watch this counter over time to understand your baseline user connection numbers. Since each user connection consumes some memory space, a high number of user connections can impact throughput and cause a performance slow-down. Once you have an idea of your high and low thresholds during normal usage of your system, you can then look for times when this counter exceeds these high and low marks.')
           ,('If the returned value of this counter goes down and the load on the system remains stable, you might have a bottleneck that is not allowing your server to handle the normal load. Keep in mind that this counter value might go down just because less people are using your SQL Server instance. If you see this number jump by 500% from your baseline, you may be seeing a slowdown of your server activity.')
           ,('You may want to boost the SQL Server configuration setting, Maximum Worker Threads to a figure higher than the default setting of 255. The setting for Maximum Worker Threads should be higher than the maximum number of user connections your server ever reaches.')
           ,(1)
           ,(1)
           ,(7)
            )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Total Server Memory (MB)')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((8)
           ,('Total Server Memory (MB)')
           ,(1)
           ,('SELECT cntr_value/ 1024
              FROM sys.dm_os_performance_counters
                WHERE object_name LIKE ''%:Memory Manager%''
               AND counter_name = ''Total Server Memory (KB)'';
           ')
           ,('This performance counter measures the current amount of memory that SQL Server is using.')
           ,('If the value of this counter continues to grow larger, the server has not yet reached its steady state and is still trying to populate the cache and get pages loaded into memory. Performance will likely be somewhat slower if this value continually grows larger since more disk I/O is required. This behavior is normal. Eventually Total Server Memory should approximate Target Server Memory.')
           ,('If the Total Server Memory counter is greater than or equal to the Target Server Memory counter, this can indicate that your SQL Server may be under memory pressure.')
           ,('Installing additional memory into your SQL server should resolve the problem.')
           ,(1)
           ,(1)
           ,(4)
             )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Target Server Memory (MB)')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((9)
           ,('Target Server Memory (MB)')
           ,(1) 
           ,('SELECT cntr_value/ 1024
              FROM sys.dm_os_performance_counters
                WHERE object_name LIKE ''%:Memory Manager%''
               AND counter_name = ''Target Server Memory (KB)'';
           ')
           ,('This performance counter measures the total amount of dynamic memory the server can consume.') 
           ,('This performance counter tells you how much memory SQL Server would like to use to operate efficiently. Compare with Total Server Memory.')  
           ,('If the Total Server Memory counter is greater than or equal to the Target Server Memory counter, this could indicate that your SQL Server may be under memory pressure.') 
           ,('Installing additional memory into your SQL server should resolve the problem.')  
           ,(1) 
           ,(1) 
           ,(4)
           ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Lazy Writes/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((10)
           ,('Lazy Writes/sec')
           ,(2) 
           ,('SELECT cntr_value
              FROM sys.dm_os_performance_counters
                WHERE object_name LIKE ''%:Buffer Manager%''
                AND counter_name = ''Lazy writes/sec'';
           ')
           ,('The lazy writer is a system process that flushes out buffers that contain changes that must be written back to disk before the buffer can be reused for a different page and makes them available to user processes.') 
           ,('This performance counter tracks how many times per second that the Lazy Writer process is moving dirty pages from the buffer to disk in order to free up buffer space. The Lazy Writer eliminates the need to perform frequent checkpoints in order to create available buffers. Generally speaking, this should not be a high value, say more than 20 per second. Ideally, it should be close to zero. If it is zero, this indicates that your SQL Server''''s buffer cache is large and your SQL Server does not need to free up dirty pages.')  
           ,('If the returned value is high, this can indicate that your SQL Server''''s buffer cache is small and that your SQL Server needs to free up dirty pages.') 
           ,('Check your SQL server and verify its memory is being used efficiently. Applications other than SQL may be using a great deal of memory. Try and recover memory by closing unnecessary applications. Installing additional memory may also help.')  
           ,(1) 
           ,(1) 
           ,(1)
           ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Logins/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((11)
           ,('Logins/sec')
           ,(2) 
           ,('SELECT cntr_value
              FROM sys.dm_os_performance_counters
              WHERE object_name LIKE ''%:General Statistics%''
              AND counter_name = ''Logins/sec'';
             ')
           ,('This performance counter returns the total number of logins started, per second, and does not include pooled connections.') 
           ,('Opening and closing connections is an expensive process. A pooled connection is one which is kept open by an application for other requests to re-use.')  
           ,('If the returned value is high, this can indicate that the application is not correctly using connection pooling.') 
           ,('Review the Connection Polling (http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx) configuration.')  
           ,(1) 
           ,(1) 
           ,(7)
           ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Latch Waits/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
             ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
      VALUES((12)
           ,('Latch Waits/sec')
           ,(2) 
           ,('SELECT cntr_value
              FROM sys.dm_os_performance_counters
                WHERE object_name LIKE ''%:Latches%''
                AND counter_name = ''Latch Waits/sec'';
           ')
           ,('This is the number of latch requests that could not be granted immediately. In other words, these are the amount of latches in a one second period that had to wait.') 
           ,('Latches are light-weight synchronization constructs that are designed to protect the physical integrity of a page in a similar way to how locks protect the logical consistency of rows. They''re taken any time something wants to modify a page, be it moving the page from disk to memory or via versa, writing a record onto a page, or changing a page''s metadata.')  
           ,(NULL) 
           ,(NULL)  
           ,(1) 
           ,(1) 
           ,(3)
           ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Batch Requests/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((13)
               ,('Batch Requests/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:SQL Statistics%''
                    AND counter_name = ''Batch Requests/sec'';
                ')
               ,('This performance counter returns the number of Batch Requests (http://sqlserverplanet.com/dba/understanding-batch-requests-sec) that SQL Server receives per second.') 
               ,('The values this monitor returns generally follows in step as to how busy your server''s CPUs are. From a network bottleneck approach, a typical 100Mbs network card is only able to handle about 3,000 batch requests per second.')  
               ,('Generally speaking, over 1,000 batch requests per second indicates a very busy SQL Server. If this is the case, you may soon experience a CPU bottleneck, if you are not already. Of course, this is a relative number, and the more powerful your hardware, the more batch requests per second your SQL Server can handle. Sometimes low Batch Requests/Sec can be misleading. If there were a SQL Statements/sec counter, this would be a more accurate measure of the amount of SQL Server activity. For example, an application may call only a few stored procedures, yet each stored procedure does a great deal of work. In this case, we will see a low number for Batch Requests/sec, but each stored procedure (one batch) will execute many SQL statements that drive up CPU and other resources. As a result, many counter thresholds based on the number of Batch Requests/sec will seem to identify issues because the batch requests on such a server are unusually low for the level of activity on the server.') 
               ,('Check your SQL server and verify system resources are being used efficiently. Applications other than SQL may be using unnecessary system resources. Try and recover memory by closing unnecessary applications. Installing additional memory and upgrading your hardware should solve this problem.')  
               ,(1) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Transactions/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((14)
               ,('Transactions/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Databases%''
                    AND counter_name = ''Transactions/sec''
                    AND instance_name = ''_Total'';
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Memory Grants Pending')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((15)
               ,('Memory Grants Pending')
               ,(1) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Memory Manager%''
                    AND counter_name = ''Memory Grants Pending'';
                ')
               ,('This performance counter returns the total number of processes waiting for a workspace memory grant (http://msdn.microsoft.com/en-us/library/ms190924.aspx).') 
               ,('Memory resources are required for each user request. If sufficient memory is not available, the user waits until there is adequate memory for the query to run.')  
               ,('Returned values greater than zero for a sustained period of time is a very strong indicator of memory pressure.') 
               ,('You should first examine the database design, queries, and indexes to ensure the system is properly tuned before installing additional RAM. There may be query inefficiencies in the instance that is causing excessive memory grant requirements. For example, large Sorts (http://msdn.microsoft.com/en-us/library/ms188723.aspx) or Hashes (http://technet.microsoft.com/en-us/library/ms189313.aspx) that can be resolved by tuning the indexing or queries being executed. Compare with Memory Grants Outstanding. If the number of pending grants increases, try the following: • Add more memory to SQL Server • Add more physical memory to the server. • Check for memory pressure. See and correct indexing if you experience “Out of memory” conditions.')  
               ,(1) 
               ,(1) 
               ,(4)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Average Lock Wait Time (ms)')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((16)
               ,('Average Lock Wait Time (ms)')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Locks%''
                    AND counter_name = ''Average Wait Time (ms)''
                    AND instance_name = ''_Total'';
                ')
               ,('This performance counter reports the average amount of Wait time, in milliseconds, for each lock request that resulted in a wait.') 
               ,('Generally speaking, the lower the value, the better. This value should correlate to the Lock Waits/sec counter and move up or down with it accordingly.')  
               ,('An average wait time longer than 500ms may indicate excessive blocking (http://support.microsoft.com/kb/224453).') 
               ,('You should determine which queries are generating locks to identify where the blocking is originating.')  
               ,(1) 
               ,(1) 
               ,(3)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Lock Timeouts/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((17)
               ,('Lock Timeouts/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                   WHERE object_name LIKE ''%:Locks%''
                    AND counter_name = ''Lock Timeouts/sec''
                    AND instance_name = ''_Total'';
                ')
               ,('This performance counter returns the number of lock requests per second that have timed out, including internal requests for NoWait (http://msdn.microsoft.com/en-us/library/c8bys6hz.aspx) locks.') 
               ,('This is the number of milliseconds that will pass before Microsoft SQL Server returns a locking error. A value of -1 (default) indicates no time-out period (that is, wait forever). When a wait for a lock exceeds the time-out value, an error is returned. A value of 0 means to not wait at all and return a message as soon as a lock is encountered. In order for thresholds to be tuned to your environment, thresholds for this performance counter should be set using the Baseline Calculator.')  
               ,('If you see a value above 0 for this counter, your users will experience problems as their queries are not completing.') 
               ,('You should review your queries to determine which queries are causing this situation.')  
               ,(1) 
               ,(1) 
               ,(3)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Longest Transaction Running Time (sec)')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((18)
               ,('Longest Transaction Running Time (sec)')
               ,(1) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Transactions%''
                    AND counter_name = ''Longest Transaction Running Time'';
                ')
               ,('The length of time, in seconds, the transaction that has been running the longest, has been active.') 
               ,('Transactions that run longer than others use more resources. They can be used to track down procedures and calls that are taking longer than expected by identifying the specific transaction(s).')  
               ,('Long running transactions can prevent truncation of transaction logs. This can cause the transaction log files to grow until they consume all available physical disk space shutting down access to the database.') 
               ,('Check the functionality of the query and/or redesign the long running transaction.')  
               ,(1) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'SQL Compilations/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((19)
               ,('SQL Compilations/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:SQL Statistics%''
                    AND counter_name = ''SQL Compilations/sec'';
                ')
               ,('This performance counter returns the number of times per second that SQL Server compilations have occurred.') 
               ,('This value should be as low as possible.')  
               ,('If you see a high value, say above100, then this can be an indication that there are a great deal of ad hoc queries that are running which may cause increased CPU usage.') 
               ,('Re-write the running ad hoc queries as stored procedures or use the following command: sp_executeSQL.')  
               ,(1) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Deadlocks')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((20)
               ,('Deadlocks')
               ,(5) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                   WHERE object_name LIKE ''%:Locks%''
                    AND counter_name = ''Number of Deadlocks/sec''
                    AND instance_name = ''_Total'';
                ')
               ,('The number of lock requests that resulted in a deadlock. Since only a COMMIT, ROLLBACK, or deadlock can terminate a transaction (excluding failures or errors), this is an important value to track.') 
               ,(NULL)  
               ,('When returning value is above zero users and applications will experience problems. Their queries will abort and the applications may fail.') 
               ,('You should trace deadlocks and examine trace output in SQL Server log. Deadlocks can be prevented by one or more of the following methods: - Adding missing indexes to support faster queries; - Dropping unnecessary indexes which may slow down INSERTs for example; - Redesigning indexes to be "thinner", for example, removing columns from composite indexes or making table columns "thinner"; - Adding index hints to queries; - Redesigning tables with "thinner" columns like smalldatetime vs. datetime or smallint vs. int; - Modifying the stored procedures to access tables in a similar pattern; - Keeping transactions as short and quick as possible: "mean & lean"; - Removing unnecessary extra activity from the transactions like triggers; - Removing JOINs to Linked Server (remote) tables; - Implementing regular index maintenance; usually weekend schedule suffices; use FILLFACTOR = 80 for dynamic tables; - Setting MAXDOP=1 solves deadlocking in some cases.')  
               ,(1) 
               ,(1) 
               ,(3)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Connection Memory (KB)')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((21)
               ,('Connection Memory (KB)')
               ,(1) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%Memory Manager%''
                    AND counter_name = ''Connection Memory (KB)'';
                ')
               ,('This performance counter returns the total amount of dynamic memory the server is using for maintaining connections.') 
               ,('SQL Server sets aside three packet buffers for every connection made from a client. Each buffer is sized according to the default network packet size specified by the sp_configure stored procedure. If the default network packet size is less than 8KB, the memory for these packets comes from SQL Server''s buffer pool. If it is 8KB or larger, the memory is allocated from SQL Server''s MemToLeave region. It is worth noting that the default network packet size for the .NET Framework Data Provider for SQL Server is 8KB, so the buffers associated with managed code client connections typically come from SQL Server''s MemToLeave region. This contrasts with classic ADO applications, where the default packet size is 4KB, and the buffers are allocated form the SQL Server buffer pool.')  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(4)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Database File Data Reads')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((22)
               ,('Database File Data Reads')
               ,(4) 
               ,('SELECT DB_NAME(vfs.database_id) AS [database_name], SUM(vfs.num_of_reads) AS [num_of_reads]
                  FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS vfs
                    JOIN sys.master_files AS mf
                    ON vfs.database_id = mf.database_id
                    AND vfs.[file_id] = mf.[file_id]
                    AND mf.type_desc = ''ROWS''
                    GROUP BY DB_NAME(vfs.database_id);
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(0) 
               ,(9)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Database IO Stall Reads')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((23)
               ,('Database IO Stall Reads')
               ,(4) 
               ,('SELECT DB_NAME(vfs.database_id) AS [database_name], SUM(vfs.io_stall_read_ms) AS [num_of_reads]
                 FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS vfs
                    JOIN sys.master_files AS mf
                    ON vfs.database_id = mf.database_id
                    AND vfs.[file_id] = mf.[file_id]
                    AND mf.type_desc = ''ROWS''
                    GROUP BY DB_NAME(vfs.database_id);
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(0) 
               ,(9)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Database Read Latency')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((27)
               ,('Database Read Latency')
               ,(3) 
               ,('DECLARE @current_datetime SMALLDATETIME
                  SELECT @current_datetime = MAX(mh.MH_datetime)
                    FROM [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK)

                  SELECT (SELECT mc3.Monitoring_counter_ID
                    FROM [HCITools].[dbo].[Monitoring_counter] mc3 WITH (NOLOCK)
                    WHERE mc3.MC_name=''Database Read Latency'') as t,
                    mh1.MH_instance_name,
                    CASE WHEN mh2.MH_value = 0
                         THEN 0
                         ELSE mh1.MH_value / mh2.MH_value
                       END ''ReadLatency'',
                       @current_datetime
                      FROM [HCITools].[dbo].[Monitoring_area] ma WITH (NOLOCK)
                      JOIN [HCITools].[dbo].[Monitoring_counter] mc1 WITH (NOLOCK)
                         ON mc1.MC_monitoring_area = ma.Monitoring_area_ID
                       AND mc1.MC_name = ''Database IO Stall Reads''
                      JOIN [HCITools].[dbo].[Monitoring_history] mh1 WITH (NOLOCK)
                         ON mh1.MH_monitoring_counter = mc1.Monitoring_counter_ID
                       AND mh1.MH_datetime = @current_datetime
                      JOIN [HCITools].[dbo].[Monitoring_counter] mc2 WITH (NOLOCK)
                         ON mc2.MC_monitoring_area = ma.Monitoring_area_ID
                       AND mc2.MC_name = ''Database File Data Reads''
                      JOIN [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
                         ON mh2.MH_monitoring_counter = mc2.Monitoring_counter_ID
                       AND mh2.MH_instance_name = mh1.MH_instance_name
                       AND mh2.MH_datetime = mh1.MH_datetime
                     WHERE ma.MA_name = ''Disk''
                     ORDER BY mh1.MH_instance_name;
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(2) 
               ,(1) 
               ,(9)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Database File Data Writes')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((30)
               ,('Database File Data Writes')
               ,(4) 
               ,('SELECT DB_NAME(vfs.database_id) AS [database_name], SUM(vfs.num_of_writes) AS [num_of_writes]
                  FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS vfs
                   JOIN sys.master_files AS mf
                    ON vfs.database_id = mf.database_id
                   AND vfs.[file_id] = mf.[file_id]
                   AND mf.type_desc = ''ROWS''
                   GROUP BY DB_NAME(vfs.database_id);
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(0) 
               ,(9)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Database IO Stall Writes')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((31)
               ,('Database IO Stall Writes')
               ,(4) 
               ,('SELECT DB_NAME(vfs.database_id) AS [database_name], SUM(vfs.io_stall_write_ms) AS [num_of_io_stall_write_ms]
                 FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS vfs
                 JOIN sys.master_files AS mf
                    ON vfs.database_id = mf.database_id
                  AND vfs.[file_id] = mf.[file_id]
                  AND mf.type_desc = ''ROWS''
                 GROUP BY DB_NAME(vfs.database_id);
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(0) 
               ,(9)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Database Write Latency')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((32)
               ,('Database Write Latency')
               ,(3) 
               ,('DECLARE @current_datetime SMALLDATETIME
                    SELECT @current_datetime = MAX(mh.MH_datetime)
                      FROM [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK)

                    SELECT (SELECT mc3.Monitoring_counter_ID
                                FROM [HCITools].[dbo].[Monitoring_counter] mc3 WITH (NOLOCK)
                               WHERE mc3.MC_name=''Database Write Latency'') as t,
                            mh1.MH_instance_name,
                            CASE WHEN mh2.MH_value = 0
                                   THEN 0
                                   ELSE mh1.MH_value / mh2.MH_value
                            END ''WriteLatency'',
                            @current_datetime
                      FROM [HCITools].[dbo].[Monitoring_area] ma WITH (NOLOCK)
                      JOIN [HCITools].[dbo].[Monitoring_counter] mc1 WITH (NOLOCK)
                         ON mc1.MC_monitoring_area = ma.Monitoring_area_ID
                       AND mc1.MC_name = ''Database IO Stall Writes''
                      JOIN [HCITools].[dbo].[Monitoring_history] mh1 WITH (NOLOCK)
                         ON mh1.MH_monitoring_counter = mc1.Monitoring_counter_ID
                       AND mh1.MH_datetime = @current_datetime
                      JOIN [HCITools].[dbo].[Monitoring_counter] mc2 WITH (NOLOCK)
                         ON mc2.MC_monitoring_area = ma.Monitoring_area_ID
                       AND mc2.MC_name = ''Database File Data Writes''
                      JOIN [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
                         ON mh2.MH_monitoring_counter = mc2.Monitoring_counter_ID
                       AND mh2.MH_instance_name = mh1.MH_instance_name
                       AND mh2.MH_datetime = mh1.MH_datetime
                     WHERE ma.MA_name = ''Disk''
                     ORDER BY mh1.MH_instance_name;
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(2) 
               ,(1) 
               ,(9)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Total Pages')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((33)
               ,('Total Pages')
               ,(1) 
               ,('SELECT cntr_value
                      FROM sys.dm_os_performance_counters
                     WHERE object_name LIKE ''%:Buffer Manager%''
                       AND counter_name = ''Total pages'';
                ')
               ,('This performance counter returns the number of pages in the buffer pool.') 
               ,('The returned value includes database, free, and stolen pages. Note: This counter is not available in SQL 2012.')  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(1)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Free list stalls/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((34)
               ,('Free list stalls/sec')
               ,(2) 
               ,('SELECT cntr_value
                      FROM sys.dm_os_performance_counters
                     WHERE object_name LIKE ''%:Buffer Manager%''
                       AND counter_name = ''Free list stalls/sec'';
               ')
               ,('Indicates the number of requests per second that had to wait for a free page.') 
               ,('This displays the frequency with which requests for available database pages are suspended because no buffers are available.')  
               ,('If the returned value is high, this indicates that not enough memory is available for the SQL Server.') 
               ,('Check your SQL server and verify its memory is being used efficiently. Applications other than SQL may be using a great deal of memory. Try and recover memory by closing unnecessary applications. Installing additional memory may also help.')  
               ,(1) 
               ,(1) 
               ,(1)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Cache Object Counts')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((35)
               ,('Cache Object Counts')
               ,(1) 
               ,('SELECT cntr_value
                 FROM sys.dm_os_performance_counters
                 WHERE object_name LIKE ''%:Plan Cache%''
                  AND counter_name like ''Cache Object Counts%''
                  AND instance_name = ''_Total'';
                ')
               ,('This performance counter returns the number of cache objects in the cache.') 
               ,('The Plan Cache object provides counters to monitor how SQL Server uses memory to store objects such as stored procedures, ad hoc and prepared Transact-SQL statements, and triggers. Multiple instances of the Plan Cache object can be monitored at the same time, with each instance representing a different type of plan to monitor.')  
               ,('High numbers of total cached objects use portions of the physical memory available to a SQL instance on a per database basis. This can result in one database cache impacting the performance of other local databases due to memory contention.') 
               ,('Increase the memory available to SQL services, reduce the number of databases on this instance of SQL, or examine the volume of ad hoc queries running against the server.')  
               ,(1) 
               ,(1) 
               ,(2)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Cache Objects in use')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((36)
               ,('Cache Objects in use')
               ,(1) 
               ,('SELECT cntr_value
                 FROM sys.dm_os_performance_counters
                WHERE object_name LIKE ''%:Plan Cache%''
                  AND counter_name like ''Cache Objects in use%''
                  AND instance_name = ''_Total'';
                ')
               ,('This performance counter returns number of cache objects in use.') 
               ,('The Plan Cache object provides counters to monitor how SQL Server uses memory to store objects such as stored procedures, ad hoc and prepared Transact-SQL statements, and triggers. Multiple instances of the Plan Cache object can be monitored at the same time, with each instance representing a different type of plan to monitor.')  
               ,('High numbers of cached objects in use consume the memory available to a SQL server at a higher rate than non-active objects on a per database basis. This can result in one database cache impacting the performance of other local databases due to memory contention.') 
               ,('Increase the memory available to SQL server, reduce the number of active objects, consolidate stored procedures, consolidate and convert ad hoc queries to stored procedures where possible, or reduce the number of databases on the server.')  
               ,(1) 
               ,(1) 
               ,(2)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Cached Plans Lookup')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((37)
               ,('Cached Plans Lookup')
               ,(2) 
               ,('select SUM(usecounts)
                    from sys.dm_exec_cached_plans;
               ')
               ,('Number of times the cache object has been looked up.') 
               ,('Not incremented when parameterized queries find a plan in the cache. Can be incremented multiple times when using showplan.')  
               ,('') 
               ,('')  
               ,(1) 
               ,(1) 
               ,(2)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Logout/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((38)
               ,('Logout/sec')
               ,(2) 
               ,('SELECT cntr_value
                      FROM sys.dm_os_performance_counters
                     WHERE object_name LIKE ''%:General Statistics%''
                       AND counter_name = ''Logouts/sec'';
                ')
               ,('This performance counter returns the total number of logout operations started, per second.') 
               ,('Opening and closing connections is an expensive process. When applications do not use a connection pool, each request needs to establish its own connection before the query can be executed. It then has to close it. A pooled connection is one which is kept open by an application for other requests to re-use.')  
               ,('If the returned value is high, this can indicate that the application is not correctly using connection pooling.') 
               ,('Review the Connection Polling (http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx) configuration.')  
               ,(1) 
               ,(1) 
               ,(7)
          ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Lock Memory (MB)')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((39)
               ,('Lock Memory (MB)')
               ,(1) 
               ,('SELECT cntr_type / 1024
                 FROM sys.dm_os_performance_counters
                WHERE object_name LIKE ''%:Memory Manager%''
                  AND counter_name LIKE ''Lock Memory (KB)%'';
                ')
               ,('This performance counter returns the total amount of dynamic memory the server is using for locks.') 
               ,('Lock pages in memory is used to prevent older versions of Windows and SQL from allowing Windows operating system page out of the buffer pool.')  
               ,('Lock pages in memory determines which accounts can use a process to keep data in physical memory, which prevents the system from paging the data to virtual memory on disk. Exercising this privilege could significantly affect system performance by decreasing the amount of available random access memory (RAM).') 
               ,('Upgrade to Windows 2008 R2 or greater and SQL 2008 or greater.')  
               ,(1) 
               ,(1) 
               ,(4)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Granted Workspace Memory (MB)')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((40)
               ,('Granted Workspace Memory (MB)')
               ,(1) 
               ,('SELECT cntr_type / 1024
                      FROM sys.dm_os_performance_counters
                     WHERE object_name LIKE ''%:Memory Manager%''
                       AND counter_name LIKE ''Granted Workspace Memory (KB)%'';
               ')
               ,('This performance counter returns the total amount of memory currently granted to executing processes, such as Hash (http://technet.microsoft.com/en-us/library/ms189313.aspx), Sort (http://msdn.microsoft.com/en-us/library/ms188723.aspx), Bulk Copy (http://msdn.microsoft.com/en-us/library/ms130809.aspx), and Index creation (http://technet.microsoft.com/en-us/library/ms190197.aspx) operations.') 
               ,('This performance counter tells you how much memory has currently been granted to running queries. If there is memory pressure because of workspace memory, this value should be at least 25% of the virtual memory available to SQL Server.')  
               ,('If the memory pressure is severe, the server might return errors such as 701 or 8645.') 
               ,('If this is the case, this might be a good reason to consider using SQL Server 64-bit.')  
               ,(1) 
               ,(1) 
               ,(4)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Forwarded Records/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((41)
               ,('Forwarded Records/sec')
               ,(2) 
               ,('SELECT cntr_value
                      FROM sys.dm_os_performance_counters
                     WHERE object_name LIKE ''%:Access Methods%''
                       AND counter_name LIKE ''Forwarded Records/sec%'';
                ')
               ,('This performance counter identifies the use of a pointer which has been created when variable length columns have caused a row to move to a new page in a heap (http://msdn.microsoft.com/en-us/library/ms188270.aspx).') 
               ,(NULL)  
               ,('Rows with Varchar (http://msdn.microsoft.com/en-us/library/ms176089.aspx) columns can experience expansion when Varchar values are updated with a longer string. In the case where the row cannot fit in the existing page, the row migrates and access to the row will traverse a pointer. This only happens on heaps (tables without clustered indexes).') 
               ,('Evaluate clustered indexes for heap tables. In cases where clustered indexes cannot be used, drop non-clustered indexes, build a clustered index to Reorg (http://technet.microsoft.com/en-us/library/ms189858.aspx) pages and rows, drop the clustered index, then recreate non-clustered indexes.')  
               ,(1) 
               ,(1) 
               ,(9)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Forwarded Records/Batch Requests')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((42)
               ,('Forwarded Records/Batch Requests')
               ,(1) 
               ,('SELECT CASE WHEN mh2.MH_value = 0
                    THEN 0
                    ELSE mh1.MH_value / mh2.MH_value
                       END ''Value''
                 FROM [HCITools].[dbo].[Monitoring_counter] mc1 WITH (NOLOCK)
                 JOIN [HCITools].[dbo].[Monitoring_history] mh1 WITH (NOLOCK)
                    ON mh1.MH_monitoring_counter = mc1.Monitoring_counter_ID
                  AND mh1.MH_datetime = (SELECT MAX(mh.MH_datetime)
                                                  FROM [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK))
                 JOIN [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
                       JOIN [HCITools].[dbo].[Monitoring_counter] mc2 WITH (NOLOCK)
                          ON mc2.Monitoring_counter_ID = mh2.MH_monitoring_counter
                         AND mc2.MC_name = ''Batch Requests/sec''
                    ON mh2.MH_datetime = mh1.MH_datetime
                WHERE mc1.MC_name = ''Forwarded Records/sec'';
                ')
               ,('This performance counter identifies the use of a pointer which has been created when variable length columns have caused a row to move to a new page in a heap (http://msdn.microsoft.com/en-us/library/ms188270.aspx).') 
               ,('')  
               ,('Rows with Varchar (http://msdn.microsoft.com/en-us/library/ms176089.aspx) columns can experience expansion when Varchar values are updated with a longer string. In the case where the row cannot fit in the existing page, the row migrates and access to the row will traverse a pointer. This only happens on heaps (tables without clustered indexes).') 
               ,('Evaluate clustered indexes for heap tables. In cases where clustered indexes cannot be used, drop non-clustered indexes, build a clustered index to Reorg (http://technet.microsoft.com/en-us/library/ms189858.aspx) pages and rows, drop the clustered index, then recreate non-clustered indexes.')  
               ,(2) 
               ,(1) 
               ,(9)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Page Splits/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((43)
               ,('Page Splits/sec')
               ,(2) 
               ,('SELECT cntr_value
                      FROM sys.dm_os_performance_counters
                     WHERE object_name LIKE ''%:Access Methods%''
                       AND counter_name LIKE ''Page Splits/sec%'';
                ')
               ,('This performance counter returns the number of page splits per second.') 
               ,('The returned value for this monitor should be as low as possible.')  
               ,('Returned values that are high can indicate the overflowing of index pages. A high value for this counter is not bad in situations where many new pages are being created, since it includes new page allocations.') 
               ,('To avoid Page Splits (http://careerride.com/SQL-Server-what-is-page-splits.aspx), review the table and index design so as to reduce non-sequential inserts. You can also implement Fillfactor (http://msdn.microsoft.com/en-us/library/ms177459.aspx) and Pad_Index (http://stackoverflow.com/questions/6857007/what-is-the-purpose-of-pad-index-in-this-sql-server-constraint) to leave more empty space per page.')  
               ,(1) 
               ,(1) 
               ,(5)
               ) 
END
GO

/* Find the good name ADD the other one Page (Splits/sec)
IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Page Splits2/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
       VALUES((44)
               ,('Page Splits/sec')
               ,(1) 
               ,('SELECT CASE WHEN mh2.MH_value = 0
                    THEN 0
                    ELSE mh1.MH_value / mh2.MH_value
                 END ''Value''
                 FROM [HCITools].[dbo].[Monitoring_counter] mc1 WITH (NOLOCK)
                 JOIN [HCITools].[dbo].[Monitoring_history] mh1 WITH (NOLOCK)
                    ON mh1.MH_monitoring_counter = mc1.Monitoring_counter_ID
                  AND mh1.MH_datetime = (SELECT MAX(mh.MH_datetime)
                                                  FROM [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK))
                 JOIN [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
                       JOIN [HCITools].[dbo].[Monitoring_counter] mc2 WITH (NOLOCK)
                          ON mc2.Monitoring_counter_ID = mh2.MH_monitoring_counter
                         AND mc2.MC_name = ''Batch Requests/sec''
                    ON mh2.MH_datetime = mh1.MH_datetime
                WHERE mc1.MC_name = ''Page Splits/sec'';
                ')
               ,('This performance counter displays the number of page splits per second that occur as the result of overflowing index pages.') 
               ,('The returned value needs to be low as possible.')  
               ,('High values could mean poor table or index design.') 
               ,('If the number of page splits is high, consider increasing the Fill Factor (http://msdn.microsoft.com/en-us/library/aa933139.aspx) of your indexes. An increased Fill Factor helps to reduce page splits because there is more room in data pages before it fills up and a page split has to occur. Note that this counter also includes the new page allocations as well and does not necessarily pose a problem. The other place we can confirm the page splits that involve data or index rows moves are the fragmented indexes on page splits.')  
               ,(2) 
               ,(1) 
               ,(5)
               ) 
END
*/

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Free pages')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((45)
               ,('Free pages')
               ,(1) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                   WHERE object_name LIKE ''%:Buffer Manager%''
                   AND counter_name LIKE ''Free pages%'';
                ')
               ,('This performance counter displays the total number of pages on all free lists.') 
               ,('This is not main indicator of memory problems and could only used as signal of possible memory pressure. In order for thresholds to be tuned to your environment, thresholds for this performance counter should be set using the Baseline Calculator.')  
               ,('If this counter is critical and other memory counters are good, it is possible that there are no problems with memory.') 
               ,('Check other memory counters. If they have critical values, you may try to install additional memory into SQL server.')  
               ,(1) 
               ,(1) 
               ,(5)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Database Pages')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((46)
               ,('Database Pages')
               ,(1) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Buffer Manager%''
                    AND counter_name LIKE ''Database Pages%'';
                ')
               ,('This metric tells you have many database pages are currently being occupied in the data cache.') 
               ,('The higher the buffer manager Database Pages is, the less room there is for SQL Server to cache more data pages. This means that SQL Server may have to free up data cache pages order to make room for pages being moved in from disk to the data cache, which can increase disk IO and hurt performance. There are no specific thresholds for this counter as each server is different. Instead, watch baseline values and look for sudden changes in the baseline value.')  
               ,('If the value for this counter increases above its typical baseline value, this may indicate memory pressure for the SQL Server instance.') 
               ,('Investigate buffer management and disk I/O.')  
               ,(1) 
               ,(1) 
               ,(5)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'SQL Cache Memory (MB)')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((47)
               ,('SQL Cache Memory (MB)')
               ,(1) 
               ,('SELECT cntr_value / 1024
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Memory Manager%''
                    AND counter_name LIKE ''SQL Cache Memory (KB)%'';
                ')
               ,('This performance counter measures the total amount of dynamic memory the server is using for the Dynamic SQL cache (http://www.sommarskog.se/dynamic_sql.html).') 
               ,('Most memory used by SQL Server is allocated to the Buffer Pool, which is used to store data pages. SQL Server steals a proportion of this memory for use in caching query plans. The overall amount of memory available to SQL Server depends upon the amount of memory installed on the server, the architecture of the server, the version and edition of SQL Server and the amount of memory pressure being experienced by SQL Server. This pressure can be internal (SQL Server resources need memory) or external (operating system needs memory). SQL Server is designed to respond to memory pressure when necessary.')  
               ,('Memory contention with the buffer pool.') 
               ,('Increase memory available to SQL server.')  
               ,(1) 
               ,(1) 
               ,(4)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Optimizer Memory (MB)')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((48)
               ,('Optimizer Memory (MB)')
               ,(1) 
               ,('SELECT cntr_value / 1024
                  FROM sys.dm_os_performance_counters
                   WHERE object_name LIKE ''%:Memory Manager%''
                   AND counter_name LIKE ''Optimizer Memory (KB)%'';
                ')
               ,('This performance counter returns the total amount of dynamic memory the server is using for query optimization.') 
               ,('There are no thresholds associated with this performance counter.')  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(4)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Workfiles Created/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((49)
               ,('Workfiles Created/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Access Methods%''
                    AND counter_name LIKE ''Workfiles Created/sec%'';
                ')
               ,('This is the number of work files created per second.') 
               ,('For example, work files could be used to store temporary results for hash joins and hash aggregates. The returned value should be less than 20. Tempdb work files are used in processing hash operations when the amount of data being processed is too large to fit into the available memory.')  
               ,('High values can indicate thrash in the tempdb file as well as poorly coded queries.') 
               ,('It is possible to reduce the value this monitor returns by making queries more efficient by adding/changing indexes. Adding additional memory will also help.')  
               ,(1) 
               ,(1) 
               ,(4)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Worktables Created/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((50)
               ,('Worktables Created/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                   WHERE object_name LIKE ''%:Access Methods%''
                    AND counter_name LIKE ''Worktables Created/sec%'';
                ')
               ,('This performance counter displays the number of work tables created per second.') 
               ,('For example, work tables could be used to store temporary results for query spool, lob variables, XML variables, and cursors. The returned value should be less than 20. Worktables are used for queries that use various spools (table spool, index spool, and so on).')  
               ,('High values could cause general slowdown.') 
               ,('Remediation requires rewriting your procedures.')  
               ,(1) 
               ,(1) 
               ,(4)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Probe Scans/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((51)
               ,('Probe Scans/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Access Methods%''
                    AND counter_name LIKE ''Probe Scans/sec%'';
                ')
               ,('This performance counter returns the number of Probe Scans, per second, that are used to find at most, one single qualified row in an index or base table directly.') 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Range Scans/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((52)
               ,('Range Scans/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                   WHERE object_name LIKE ''%:Access Methods%''
                   AND counter_name LIKE ''Range Scans/sec%'';
                ')
               ,('This performance counter returns the number of Qualified Range Scans through indexes per second.') 
               ,('This monitor returns the number of qualified range scans through indexes per second.')  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Auto-Param Attempts/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((53)
               ,('Auto-Param Attempts/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:SQL Statistics%''
                    AND counter_name LIKE ''Auto-Param Attempts/sec%'';
                ')
               ,('This performance counter returns the number of auto-parameterization (http://msdn.microsoft.com/en-us/library/ms186219.aspx) attempts per second.') 
               ,('The total for this monitor should be the sum of the failed, safe, and unsafe auto-parameterizations. Auto-parameterization occurs when an instance of SQL Server tries to parameterize a Transact-SQL request by replacing some literals with parameters so that reuse of the resulting cached execution plan across multiple similar-looking requests is possible. Note that auto-parameterizations are also known as simple parameterizations in newer versions of SQL Server. This counter does not include forced parameterizations (http://technet.microsoft.com/en-us/library/ms175037.aspx).')  
               ,('Bad T-SQL coding practices can increase recompilation frequency and adversely affect SQL Server''s performance. Such situations can be debugged and corrected in many cases.') 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Failed Auto-Params/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((54)
               ,('Failed Auto-Params/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:SQL Statistics%''
                    AND counter_name LIKE ''Failed Auto-Params/sec%'';
                ')
               ,('This performance counter returns the number of failed auto-parameterization (http://msdn.microsoft.com/en-us/library/ms186219.aspx) attempts per second.') 
               ,('The value returned by this monitor should be low. Note that auto-parameterizations are also known as simple parameterizations in later versions of SQL Server. Preferred values should be near zero. In order for thresholds to be tuned to your environment, thresholds for this performance counter should be set using the Baseline Calculator.')  
               ,('Bad T-SQL coding practices can increase recompilation frequency and adversely affect SQL Server''s performance. Such situations can be debugged and corrected in many cases.') 
               ,('')  
               ,(1) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Plan Re-Use Ratio')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((55)
               ,('Plan Re-Use Ratio')
               ,(1) 
               ,('SELECT CASE WHEN mh1.MH_value > 0
                    THEN CONVERT(DECIMAL(15,2),(mh1.MH_value*1.0-mh2.MH_value*1.0)/mh1.MH_value*100)
                    ELSE 0
                            END
                      FROM [HCITools].[dbo].[Monitoring_counter] mc1 WITH (NOLOCK)
                      JOIN [HCITools].[dbo].[Monitoring_history] mh1 WITH (NOLOCK)
                         ON mh1.MH_monitoring_counter = mc1.Monitoring_counter_ID
                       AND mh1.MH_datetime = (SELECT MAX(mh.MH_datetime)
                                                       FROM [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK))
                      JOIN [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
                            JOIN [HCITools].[dbo].[Monitoring_counter] mc2 WITH (NOLOCK)
                               ON mc2.Monitoring_counter_ID = mh2.MH_monitoring_counter
                              AND mc2.MC_name = ''SQL Compilations/sec''
                         ON mh2.MH_datetime = mh1.MH_datetime
                     WHERE mc1.MC_name = ''Batch Requests/sec'';
               ')
               ,('A query plan is used to execute a query.') 
               ,('Plan re-use is desirable for OLTP workloads because re-creating the same plan (for similar or identical transactions) is a waste of CPU resources. In order for thresholds to be tuned to your environment, thresholds for this performance counter should be set using the Baseline Calculator.')  
               ,('Zero cost plans will not be cached (not re-used) in SQL 2005 SP2. Applications that use zero cost plans will have a lower plan re-use but this is not a performance issue.') 
               ,('Review your plan re-use design. Tune your plan re-use design as it is described in the following article (http://sqlmag.com/sql-server/fine-tuning-plan-reuse).')  
               ,(2) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'SQL Re-Compilations/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((56)
               ,('SQL Re-Compilations/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                     WHERE object_name LIKE ''%:SQL Statistics%''
                     AND counter_name = ''SQL Re-Compilations/sec'';
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Recompilations/Compilation Ratio')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((57)
               ,('Recompilations/Compilation Ratio')
               ,(1) 
               ,('SELECT CASE WHEN mh1.MH_value > 0
                    THEN CASE WHEN mh2.MH_value > 0
                                THEN CONVERT(DECIMAL(15,2),mh1.MH_value*1.0/mh2.MH_value*100)
                                ELSE 100
                          END
                    ELSE 0
                       END
                 FROM [HCITools].[dbo].[Monitoring_counter] mc1 WITH (NOLOCK)
                 JOIN [HCITools].[dbo].[Monitoring_history] mh1 WITH (NOLOCK)
                    ON mh1.MH_monitoring_counter = mc1.Monitoring_counter_ID
                  AND mh1.MH_datetime = (SELECT MAX(mh.MH_datetime)
                                                  FROM [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK))
                 JOIN [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
                       JOIN [HCITools].[dbo].[Monitoring_counter] mc2 WITH (NOLOCK)
                          ON mc2.Monitoring_counter_ID = mh2.MH_monitoring_counter
                         AND mc2.MC_name = ''SQL Compilations/sec''
                    ON mh2.MH_datetime = mh1.MH_datetime
                  WHERE mc1.MC_name = ''SQL Re-Compilations/sec'';
                ')
               ,('This performance counter shows the ratio of SQL Recompilations to SQL Compilations.') 
               ,('SQL Recompilations should be less than 10% of SQL Compilations. In order for thresholds to be tuned to your environment, thresholds for this performance counter should be set using the Baseline Calculator.')  
               ,('Returned values that are high can indicate more temporary tables in use.') 
               ,('Change stored procedures to not change schemas, Use table variables instead of temporary tables.')  
               ,(2) 
               ,(1) 
               ,(6)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Checkpoint Pages/sec')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((58)
               ,('Checkpoint Pages/sec')
               ,(2) 
               ,('SELECT cntr_value
                  FROM sys.dm_os_performance_counters
                    WHERE object_name LIKE ''%:Buffer Manager%''
                    AND counter_name LIKE ''Checkpoint Pages/sec%'';
                ')
               ,('The checkpoint pages per second counter measures the number of pages written to disk by a checkpoint operation.') 
               ,('You should watch this counter over time to establish a baseline for your systems. Once a baseline value has been established you can watch this value to see if it is climbing.')  
               ,('If this counter is climbing, it might mean you are running into memory pressures that are causing dirty pages to be flushed to disk more frequently than normal.') 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(5)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'SQL Server Average CPU Load')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((59)
               ,('SQL Server Average CPU Load')
               ,(1) 
               ,('SELECT CONVERT(DECIMAL(5,2),AVG(y.SQLServerProcessCPUUtilization)) AS [SQLServerProcessCPUUtilization]
                  FROM (SELECT TOP(5)
                                 SQLProcessUtilization*1.0 AS [SQLServerProcessCPUUtilization]
                           FROM (SELECT record.value(''(./Record/@id)[1]'', ''int'') AS record_id
                                          ,record.value(''(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]'', ''int'') AS [SQLProcessUtilization]
                                     FROM (SELECT CONVERT(xml, record) AS [record] 
                                               FROM sys.dm_os_ring_buffers 
                                              WHERE ring_buffer_type = N''RING_BUFFER_SCHEDULER_MONITOR''
                                                AND record LIKE ''%<SystemHealth>%'') AS x 
                                             ) AS y
                          ORDER BY record_id DESC
                       ) AS y;
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(10)
               ) 
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'System Idle Average CPU Load')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
               ([Monitoring_counter_ID]
               ,[MC_name]
               ,[MC_type]
               ,[MC_sql_query]
               ,[MC_definition]
               ,[MC_information]
               ,[MC_problem]
               ,[MC_remediation]
               ,[MC_sequence]
               ,[MC_is_visible]
               ,[MC_monitoring_area])
         VALUES((60)
               ,('System Idle Average CPU Load')
               ,(1) 
               ,('SELECT CONVERT(DECIMAL(5,2),AVG(y.SystemIdleProcess)) AS [SystemIdleProcess]
                  FROM (SELECT TOP(5)
                                 SystemIdle*1.0 AS [SystemIdleProcess]
                           FROM (SELECT record.value(''(./Record/@id)[1]'', ''int'') AS record_id
                                          ,record.value(''(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]'', ''int'') AS [SystemIdle]
                                     FROM (SELECT CONVERT(xml, record) AS [record] 
                                               FROM sys.dm_os_ring_buffers 
                                              WHERE ring_buffer_type = N''RING_BUFFER_SCHEDULER_MONITOR''
                                                AND record LIKE ''%<SystemHealth>%'') AS x 
                                             ) AS y
                          ORDER BY record_id DESC
                       ) AS y;
                ')
               ,(NULL) 
               ,(NULL)  
               ,(NULL) 
               ,(NULL)  
               ,(1) 
               ,(1) 
               ,(10)
               ) 
END

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Processes blocked')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
           ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((63)
           ,('Processes blocked')
           ,(1)
           ,('SELECT cntr_value
                FROM sys.dm_os_performance_counters
               WHERE counter_name = ''Processes blocked'';
               ')
           ,NULL
           ,NULL
           ,NULL
           ,NULL
           ,(1)
           ,(1)
           ,(3)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_counter] WHERE [MC_name] = 'Memory Grants Outstanding')
BEGIN
INSERT INTO [dbo].[Monitoring_counter]
           ([Monitoring_counter_ID]
           ,[MC_name]
           ,[MC_type]
           ,[MC_sql_query]
           ,[MC_definition]
           ,[MC_information]
           ,[MC_problem]
           ,[MC_remediation]
           ,[MC_sequence]
           ,[MC_is_visible]
           ,[MC_monitoring_area])
     VALUES((64)
           ,('Memory Grants Outstanding')
           ,(1)
           ,('SELECT cntr_value 
                FROM sys.dm_os_performance_counters   
               WHERE counter_name = ''Memory Grants Outstanding'';
               ')
           ,('Specifies the total number of processes that have successfully acquired a workspace memory grant')
           ,NULL
           ,NULL
           ,NULL
           ,(1)
           ,(1)
           ,(4)
           )
END
GO

SET IDENTITY_INSERT [dbo].[Monitoring_counter] OFF
GO

/*****************************************************************/
/**********      Insert Data in [Monitoring_threshold]    ********/
/*****************************************************************/

USE [HCITools]
GO
SET IDENTITY_INSERT [dbo].[Monitoring_threshold] ON
IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_threshold] WHERE [MT_monitoring_counter] = 1)
BEGIN
INSERT INTO [dbo].[Monitoring_threshold]
           ([Monitoring_threshold_ID]
           ,[MT_warning_threshold_low]
           ,[MT_warning_threshold_high]
           ,[MT_critical_threshold_low]
           ,[MT_critical_threshold_high]
           ,[MT_server_name]
           ,[MT_monitoring_counter])
     VALUES((1)
           ,(90)
           ,(95)
           ,(0)
           ,(90)
           ,(NULL)
           ,(1)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_threshold] WHERE [MT_monitoring_counter] = 2)
BEGIN
INSERT INTO [dbo].[Monitoring_threshold]
           ([Monitoring_threshold_ID]
           ,[MT_warning_threshold_low]
           ,[MT_warning_threshold_high]
           ,[MT_critical_threshold_low]
           ,[MT_critical_threshold_high]
           ,[MT_server_name]
           ,[MT_monitoring_counter])
     VALUES((2)
           ,(NULL)
           ,(NULL)
           ,(0)
           ,(750)
           ,(NULL)
           ,(2)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_threshold] WHERE [MT_monitoring_counter] = 16)
BEGIN
INSERT INTO [dbo].[Monitoring_threshold]
           ([Monitoring_threshold_ID]
           ,[MT_warning_threshold_low]
           ,[MT_warning_threshold_high]
           ,[MT_critical_threshold_low]
           ,[MT_critical_threshold_high]
           ,[MT_server_name]
           ,[MT_monitoring_counter])
     VALUES((3)
           ,(400)
           ,(500)
           ,(500)
           ,(NULL)
           ,(NULL)
           ,(16)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_threshold] WHERE [MT_monitoring_counter] = 20)
BEGIN
INSERT INTO [dbo].[Monitoring_threshold]
           ([Monitoring_threshold_ID]
           ,[MT_warning_threshold_low]
           ,[MT_warning_threshold_high]
           ,[MT_critical_threshold_low]
           ,[MT_critical_threshold_high]
           ,[MT_server_name]
           ,[MT_monitoring_counter])
     VALUES((4)
           ,(NULL)
           ,(NULL)
           ,(1)
           ,(NULL)
           ,(NULL)
           ,(20)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_threshold] WHERE [MT_monitoring_counter] = 15)
BEGIN
INSERT INTO [dbo].[Monitoring_threshold]
           ([Monitoring_threshold_ID]
           ,[MT_warning_threshold_low]
           ,[MT_warning_threshold_high]
           ,[MT_critical_threshold_low]
           ,[MT_critical_threshold_high]
           ,[MT_server_name]
           ,[MT_monitoring_counter])
     VALUES((5)
           ,(NULL)
           ,(NULL)
           ,(1)
           ,(NULL)
           ,(NULL)
           ,(15)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_threshold] WHERE [MT_monitoring_counter] = 4)
BEGIN
INSERT INTO [dbo].[Monitoring_threshold]
           ([Monitoring_threshold_ID]
           ,[MT_warning_threshold_low]
           ,[MT_warning_threshold_high]
           ,[MT_critical_threshold_low]
           ,[MT_critical_threshold_high]
           ,[MT_server_name]
           ,[MT_monitoring_counter])
     VALUES((6)
           ,(24000)
           ,(27000)
           ,(27000)
           ,(NULL)
           ,(NULL)
           ,(4)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_threshold] WHERE [MT_monitoring_counter] = 32)
BEGIN
INSERT INTO [dbo].[Monitoring_threshold]
           ([Monitoring_threshold_ID]
           ,[MT_warning_threshold_low]
           ,[MT_warning_threshold_high]
           ,[MT_critical_threshold_low]
           ,[MT_critical_threshold_high]
           ,[MT_server_name]
           ,[MT_monitoring_counter])
     VALUES((7)
           ,(25)
           ,(30)
           ,(30)
           ,(NULL)
           ,(NULL)
           ,(32)
           )
END
GO

IF NOT EXISTS (SELECT * FROM [dbo].[Monitoring_threshold] WHERE [MT_monitoring_counter] = 27)
BEGIN
INSERT INTO [dbo].[Monitoring_threshold]
           ([Monitoring_threshold_ID]
           ,[MT_warning_threshold_low]
           ,[MT_warning_threshold_high]
           ,[MT_critical_threshold_low]
           ,[MT_critical_threshold_high]
           ,[MT_server_name]
           ,[MT_monitoring_counter])
     VALUES((8)
           ,(25)
           ,(30)
           ,(30)
           ,(NULL)
           ,(NULL)
           ,(27)
           )
END
SET IDENTITY_INSERT [dbo].[Monitoring_threshold] OFF
GO

/*******************************************************************************************************/
/**********      Create  Stored Procedures for Monitoring: [mon_Collect_Counters_History]   ************/
/*******************************************************************************************************/


USE [HCITools]
GO

/****** Object:  StoredProcedure [dbo].[mon_Collect_Counters_History]    Script Date: 18.07.2018 10:52:46 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mon_Collect_Counters_History]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[mon_Collect_Counters_History]
GO


CREATE PROCEDURE [dbo].[mon_Collect_Counters_History]
                @in_debug              INT           = NULL
AS 

/*============================================================================= 

  Explication du traitement realise par la SP
  -------------------------------------------
    To collect performance counters in SQL Server
 
  Contexte d'utilisation
  ----------------------
    Job : SQL Server Performance - DR92170
 
  Parametres  
  ----------  
    @in_debug      
 
  Creation : 18.07.2018 / LPE
 
  Modifications : 
    23.07.2018/LPE : Add [MC_type]=5 to get aggregate values
   
=============================================================================*/ 

SET NOCOUNT ON;
--SET QUOTED_IDENTIFIER ON

DECLARE @result_sp INT,
        @errno     INT,
        @errmsg    VARCHAR(255);


/*------------------- Declaration des variables --------------------*/
DECLARE @c_monitoring_counter_id BIGINT,
        @c_mc_type               SMALLINT,
        @c_mc_sql_query          NVARCHAR(MAX),
        @cmd                     NVARCHAR(MAX),
        @monitoring_history_id   BIGINT,
        @last_original_value     BIGINT,
        @last_datetime           DATETIME,
        @current_datetime        SMALLDATETIME


/*------------ Affectation des parametres aux variables ------------*/


/*-------------------- Test des parametres input -------------------*/




/*---------------------------- Traitement --------------------------*/
DECLARE @t_current_value TABLE
        (t_current_instance NVARCHAR(128),
         t_current_value BIGINT)

DECLARE @tInstanceHistory TABLE
        (tInstance_name       NVARCHAR(128),
         tLast_original_value BIGINT,
         tLast_datetime       SMALLDATETIME)

SELECT @current_datetime = CAST(GETDATE() AS SMALLDATETIME)

DECLARE c_counters CURSOR LOCAL FORWARD_ONLY STATIC FOR
SELECT Monitoring_counter_ID,
       MC_type,
       MC_sql_query
  FROM [HCITools].[dbo].[Monitoring_counter]
 ORDER BY MC_sequence

OPEN c_counters
FETCH NEXT FROM c_counters
INTO @c_monitoring_counter_id,
     @c_mc_type,
     @c_mc_sql_query

WHILE @@FETCH_STATUS = 0
BEGIN

  SET @cmd = NULL
  SET @last_original_value = NULL
  SET @last_datetime = NULL
  DELETE FROM @t_current_value
  DELETE FROM @tInstanceHistory

  IF(@c_mc_type = 1) /* 1=instant value*/
  BEGIN 

    INSERT INTO @t_current_value
               (t_current_value)
    EXEC (@c_mc_sql_query)

    INSERT INTO [HCITools].[dbo].[Monitoring_history]
               ([MH_monitoring_counter],
                [MH_value],
                [MH_datetime])
    SELECT TOP 1
           @c_monitoring_counter_id,
           cv.t_current_value,
           @current_datetime
      FROM @t_current_value cv

  END /* @c_mc_type = 1 */
  ELSE IF(@c_mc_type = 2) /* 2=aggregate value (per second) */
  BEGIN

    SELECT @last_original_value = mh.MH_original_value,
           @last_datetime       = mh.MH_datetime
      FROM [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK)
     WHERE mh.Monitoring_history_ID = (SELECT MAX(mh2.Monitoring_history_ID)
                                         FROM [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
                                        WHERE mh2.MH_monitoring_counter = @c_monitoring_counter_id)

    INSERT @t_current_value
           (t_current_value)
    EXEC (@c_mc_sql_query)

    INSERT INTO [HCITools].[dbo].[Monitoring_history]
               ([MH_monitoring_counter],
                [MH_value],
                [MH_original_value],
                [MH_datetime])
    SELECT @c_monitoring_counter_id,
           CASE WHEN @last_original_value IS NULL
                THEN t.t_current_value -- Pour le premier, on ne divise pas par les secondes... à voir
                ELSE CASE WHEN t.t_current_value >= @last_original_value
                          THEN (t.t_current_value - @last_original_value) / DATEDIFF(ss,@last_datetime,GETDATE())
                          ELSE t.t_current_value / DATEDIFF(ss,@last_datetime,GETDATE())
                     END
           END,
           t.t_current_value,
           @current_datetime
      FROM @t_current_value t

  END /* @c_mc_type = 2 */
  ELSE IF(@c_mc_type = 3) /* 3=instant value with instance */
  BEGIN

    INSERT INTO [HCITools].[dbo].[Monitoring_history]
               ([MH_monitoring_counter],
                [MH_instance_name],
                [MH_value],
                [MH_datetime])
    EXEC (@c_mc_sql_query)

  END /* @c_mc_type = 3 */
  ELSE IF(@c_mc_type = 4) /* 4=aggregate value with instance (per second) */
  BEGIN

    INSERT INTO @tInstanceHistory
               (tInstance_name,
                tLast_original_value,
                tLast_datetime)
    SELECT mh.MH_instance_name,
           mh.MH_original_value,
           mh.MH_datetime
      FROM [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK)
     WHERE mh.Monitoring_history_ID = (SELECT MAX(mh2.Monitoring_history_ID)
                                         FROM [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
                                        WHERE mh2.MH_monitoring_counter = @c_monitoring_counter_id
                                          AND mh2.MH_instance_name = mh.MH_instance_name)

    INSERT @t_current_value
           (t_current_instance,
            t_current_value)
    EXEC (@c_mc_sql_query)

    INSERT INTO [HCITools].[dbo].[Monitoring_history]
               ([MH_monitoring_counter],
                [MH_instance_name],
                [MH_value],
                [MH_original_value],
                [MH_datetime])
    SELECT @c_monitoring_counter_id,
           t.t_current_instance,
           CASE WHEN i.tLast_original_value IS NULL
                THEN t.t_current_value -- Pour le premier, on ne divise pas par les secondes... à voir
                ELSE CASE WHEN t.t_current_value >= i.tLast_original_value
                          THEN (t.t_current_value - i.tLast_original_value) / DATEDIFF(ss,i.tLast_datetime,GETDATE())
                          ELSE t.t_current_value / DATEDIFF(ss,i.tLast_datetime,GETDATE())
                     END
           END,
           t.t_current_value,
           @current_datetime
      FROM @t_current_value t
      LEFT JOIN @tInstanceHistory i
        ON i.tInstance_name = t.t_current_instance

  END /* @c_mc_type = 4 */
  ELSE IF(@c_mc_type = 5) /* 5=aggregate value */
  BEGIN

    SELECT @last_original_value = mh.MH_original_value
      FROM [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK)
     WHERE mh.Monitoring_history_ID = (SELECT MAX(mh2.Monitoring_history_ID)
                                         FROM [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
                                        WHERE mh2.MH_monitoring_counter = @c_monitoring_counter_id)

    INSERT @t_current_value
           (t_current_value)
    EXEC (@c_mc_sql_query)

    INSERT INTO [HCITools].[dbo].[Monitoring_history]
               ([MH_monitoring_counter],
                [MH_value],
                [MH_original_value],
                [MH_datetime])
    SELECT @c_monitoring_counter_id,
           CASE WHEN @last_original_value IS NULL
                THEN t.t_current_value
                ELSE CASE WHEN t.t_current_value >= @last_original_value
                          THEN (t.t_current_value - @last_original_value)
                          ELSE t.t_current_value
                     END
           END,
           t.t_current_value,
           @current_datetime
      FROM @t_current_value t

  END /* @c_mc_type = 5 */

  FETCH NEXT FROM c_counters
  INTO @c_monitoring_counter_id,
       @c_mc_type,
       @c_mc_sql_query

END

CLOSE c_counters;
DEALLOCATE c_counters;


/*------------------ Retour au programme appelant -----------------*/ 

return(@@error); 

/*---------------------- Traitement des erreurs ----------------------*/ 
error_99: 
  raiserror (@result_sp, @errno, @errmsg) ; 
  return(@errno);

GO


/**************************************************************************************************/
/*******      Create  Stored Procedures for Monitoring: [mon_Get_Counters_History]    *************/
/**************************************************************************************************/

/*============================================================================= 

 User guide 
  ------------------------------------------
    Create  Stored Procedures for Monitoring: mon_Get_Counters_History


 Usage context
  ------------------------------------------
    To get sensor in the server and make a server reporting 

    
 Parameters
  ------------------------------------------

 Creation : 18.07.18 / KLU

 Modification :
 

=============================================================================*/ 

USE [HCITools]
GO

/****** Object:  StoredProcedure [dbo].[mon_Get_Counters_History]    Script Date: 18.07.2018 10:53:19 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mon_Get_Counters_History]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[mon_Get_Counters_History]
GO


CREATE PROCEDURE [dbo].[mon_Get_Counters_History]
                @in_start_datetime     SMALLDATETIME,
                @in_end_datetime       SMALLDATETIME,
                @in_group_counter_list NVARCHAR(200) = NULL,
                @in_segment            SMALLINT      = NULL,
                @in_frequency_in_min   SMALLINT      = NULL,
                @in_debug              INT           = NULL
AS 


/*============================================================================= 

  Explication du traitement realise par la SP
  -------------------------------------------
    To get sensor in the server and make a server reporting   
 
  Contexte d'utilisation
  ----------------------
    SSRS : GraphMonPerfSQLServer.sln
 
  Parametres  
  ----------  
    @in_start_datetime    
    @in_end_datetime      
    @in_group_counter_list
    @in_segment           
    @in_frequency_in_min  
    @in_debug             
 
  Creation : 18.07.2018 / LPE
 
  Modifications : 
   
=============================================================================*/ 
 
 
SET NOCOUNT ON;

DECLARE @result_sp INT,
        @errno     INT,
        @errmsg    VARCHAR(255);


/*------------------- Declaration des variables --------------------*/
DECLARE @param_start_datetime     SMALLDATETIME,
        @param_end_datetime       SMALLDATETIME,
        @param_group_counter_list NVARCHAR(200),
        @param_segment            SMALLINT,
        @param_frequency_in_min   SMALLINT;

/*------------------------- Dataset final -------------------------*/
DECLARE @tCalcCounterHistory TABLE
       (MC_monitoring_area          BIGINT
       ,Monitoring_counter_ID       BIGINT
       ,MH_instance_name            NVARCHAR(128)
       ,MT_warning_threshold_low    BIGINT
       ,MT_warning_threshold_high   BIGINT
       ,MT_critical_threshold_low   BIGINT
       ,MT_critical_threshold_high  BIGINT
       ,MH_datetime                 SMALLDATETIME
       ,MH_value                    BIGINT
       ,MH_min_value                BIGINT
       ,MH_max_value                BIGINT
       ,MH_min_datetime             SMALLDATETIME
       ,MH_max_datetime             SMALLDATETIME
       )

/*------------ Affectation des parametres aux variables ------------*/
SELECT @param_start_datetime     = ISNULL(@in_start_datetime, '2015-01-01'),
       @param_end_datetime       = ISNULL(@in_end_datetime, '2079-06-06'),
       @param_group_counter_list = @in_group_counter_list,
       @param_segment            = ISNULL(@in_segment,24),         /* Par defaut, on decoupe en 24 plages horaires */
       @param_frequency_in_min   = ISNULL(@in_frequency_in_min,5); /* Par defaut, frequence de recolte des donnees de 5 minutes*/


/*-------------------- Test des parametres input -------------------*/
IF @param_start_datetime IS NULL
OR @param_start_datetime IS NULL
BEGIN
  SELECT @errno = 70003, 
         @errmsg = 'Invalid input parameters in stored procedure [mon_Get_Counters_History]!';
  GOTO error_99; 
END;


/*--- Extraction de la liste des groupes de compteurs a retourner ---*/
IF @in_group_counter_list IS NOT NULL
BEGIN

  DECLARE @xml XML,
          @delimiter VARCHAR(1)

  DECLARE @tMonitoring_area_list TABLE
          (Monitoring_area_ID BIGINT)

  SET @delimiter = ','

  SET @xml = CAST(('<X>'+REPLACE(@param_group_counter_list, @delimiter, '</X><X>')+'</X>') AS XML)

  INSERT INTO @tMonitoring_area_list
              (Monitoring_area_ID)
  SELECT C.value('.', 'bigint') AS value
    FROM @xml.nodes('X') AS X(C)

  IF @in_debug = 1
    SELECT Monitoring_area_ID AS 'SELECT "@in_group_counter_list"'
      FROM @tMonitoring_area_list 

END /* IF @in_group_counter_list IS NOT NULL */


/*---------------- Recolte des plages de date/heure ----------------*/
DECLARE @tDatetimeRange TABLE
       (tdrDatetimeFrom SMALLDATETIME,
        tdrDatetimeTo   SMALLDATETIME)

DECLARE @datetime_range_in_m INT,
        @datetime_range_in_s INT,
        @current_max_MH_datetime SMALLDATETIME


/* Recherche de la date la plus recente ayant une valeur */
SELECT @current_max_MH_datetime = MAX(mh.MH_datetime)
  FROM Monitoring_history mh WITH (NOLOCK)
  JOIN Monitoring_counter mc WITH (NOLOCK)
    ON mc.Monitoring_counter_ID = mh.MH_monitoring_counter
 WHERE mc.MC_is_visible = 1
   AND (   @param_group_counter_list IS NULL
        OR EXISTS(SELECT 1
                    FROM @tMonitoring_area_list mal
                   WHERE mal.Monitoring_area_ID = mc.MC_monitoring_area))
IF @current_max_MH_datetime < @param_end_datetime
  SET @param_end_datetime = @current_max_MH_datetime


/* Calcul de la taille de la plage horaire aggregee avec gestion des arrondis */
SELECT @datetime_range_in_s = DATEDIFF(SECOND,@param_start_datetime,@param_end_datetime) / @param_segment
SELECT @datetime_range_in_m = DATEDIFF(MINUTE, '1900-01-01', DATEADD(SECOND,@datetime_range_in_s+(30*@param_frequency_in_min),'1900-01-01'))/@param_frequency_in_min*@param_frequency_in_min


/* On aggrege les donnees uniquement si la plage horaire est superieur a la frequence de recolte des donnees */
IF @datetime_range_in_m > @param_frequency_in_min
BEGIN /* donnees agregees */

--  SET @datetime_range_in_m = @param_frequency_in_min

  /* Calcul des plages horaires. On commence par la date la plus recente. */
  ;WITH mycte AS
  (
    SELECT @param_end_datetime AS DateValue
    UNION ALL
    SELECT DATEADD(MINUTE,-@datetime_range_in_m,DateValue)
      FROM mycte   
     WHERE DATEADD(MINUTE,-@datetime_range_in_m,DateValue) >= @param_start_datetime
  )
  INSERT INTO @tDatetimeRange
             (tdrDatetimeFrom,
              tdrDatetimeTo)
  SELECT DATEADD(MINUTE,-@datetime_range_in_m,DateValue),
         DateValue
    FROM mycte
   ORDER BY mycte.DateValue ASC
  OPTION (MAXRECURSION 0)

  IF @in_debug = 1
    SELECT '@tDatetimeRange',
           *
      FROM @tDatetimeRange


  /* Extraction des valeurs des compteurs agregees par plage horaire */
  INSERT INTO @tCalcCounterHistory
         (MC_monitoring_area
         ,Monitoring_counter_ID
         ,MH_instance_name
         ,MT_warning_threshold_low
         ,MT_warning_threshold_high
         ,MT_critical_threshold_low
         ,MT_critical_threshold_high
         ,MH_datetime
         ,MH_value
         ,MH_min_value
         ,MH_max_value
         ,MH_min_datetime
         ,MH_max_datetime)
  SELECT mc.MC_monitoring_area
        ,mc.Monitoring_counter_ID
        ,mh.MH_instance_name
        ,mt.MT_warning_threshold_low
        ,mt.MT_warning_threshold_high
        ,mt.MT_critical_threshold_low
        ,mt.MT_critical_threshold_high
        ,DATEADD(MINUTE,DATEDIFF(MINUTE,dtr.tdrDatetimeFrom,dtr.tdrDatetimeTo)/2,dtr.tdrDatetimeFrom) AS MH_datetime
        ,AVG(mh.[MH_value]) AS MH_value
        ,MIN(mh.[MH_value]) AS MH_min_value
        ,MAX(mh.[MH_value]) AS MH_max_value
        ,dtr.tdrDatetimeFrom AS MH_min_datetime
        ,dtr.tdrDatetimeTo AS MH_max_datetime
    FROM @tDatetimeRange dtr
   CROSS JOIN [HCITools].[dbo].[Monitoring_counter] mc WITH (NOLOCK)
    LEFT JOIN [HCITools].[dbo].[Monitoring_threshold] mt WITH (NOLOCK)
      ON mt.MT_monitoring_counter = mc.Monitoring_counter_ID
    LEFT JOIN [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK)
      ON mh.MH_datetime > dtr.tdrDatetimeFrom AND mh.MH_datetime <= dtr.tdrDatetimeTo
     AND mh.MH_monitoring_counter = mc.Monitoring_counter_ID
   WHERE mc.MC_is_visible = 1
     AND (   @param_group_counter_list IS NULL
          OR EXISTS(SELECT 1
                      FROM @tMonitoring_area_list mal
                     WHERE mal.Monitoring_area_ID = mc.MC_monitoring_area)
          )
   GROUP BY dtr.tdrDatetimeFrom,
            dtr.tdrDatetimeTo
           ,mc.MC_monitoring_area
           ,mc.Monitoring_counter_ID
           ,mh.MH_instance_name
           ,mt.MT_warning_threshold_low
           ,mt.MT_warning_threshold_high
           ,mt.MT_critical_threshold_low
           ,mt.MT_critical_threshold_high
           ,DATEADD(MINUTE,DATEDIFF(MINUTE,dtr.tdrDatetimeFrom,dtr.tdrDatetimeTo)/2,dtr.tdrDatetimeFrom)
   ORDER BY mc.MC_monitoring_area
           ,mc.Monitoring_counter_ID
           ,mh.MH_instance_name
           ,dtr.tdrDatetimeFrom
           ,dtr.tdrDatetimeTo

END /* donnees agregees */
ELSE
BEGIN /* donnees non-agregees */

  INSERT INTO @tCalcCounterHistory
         (MC_monitoring_area
         ,Monitoring_counter_ID
         ,MH_instance_name
         ,MT_warning_threshold_low
         ,MT_warning_threshold_high
         ,MT_critical_threshold_low
         ,MT_critical_threshold_high
         ,MH_datetime
         ,MH_value
         ,MH_min_value
         ,MH_max_value
         ,MH_min_datetime
         ,MH_max_datetime)
  SELECT mc.MC_monitoring_area
        ,mc.Monitoring_counter_ID
        ,mh.MH_instance_name
        ,mt.MT_warning_threshold_low
        ,mt.MT_warning_threshold_high
        ,mt.MT_critical_threshold_low
        ,mt.MT_critical_threshold_high
        ,mh.MH_datetime
        ,mh.[MH_value]
        ,mh.[MH_value] AS MH_min_value
        ,mh.[MH_value] AS MH_max_value
        ,(SELECT TOP 1 mh2.MH_datetime  -- FAIRE UN CASE AVEC LE DERNIER REDEMARRAGE DU SERVEUR SQL
            FROM [HCITools].[dbo].[Monitoring_history] mh2 WITH (NOLOCK)
           WHERE mh2.MH_monitoring_counter = mh.MH_monitoring_counter
             AND mh2.MH_datetime < mh.MH_datetime
           ORDER BY mh2.MH_datetime DESC) AS MH_min_datetime
        ,mh.MH_datetime AS MH_max_datetime
    FROM [HCITools].[dbo].[Monitoring_counter] mc WITH (NOLOCK)
    JOIN [HCITools].[dbo].[Monitoring_history] mh WITH (NOLOCK)
      ON mh.MH_datetime > @param_start_datetime AND mh.MH_datetime <= @param_end_datetime
     AND mh.MH_monitoring_counter = mc.Monitoring_counter_ID
    LEFT JOIN [HCITools].[dbo].[Monitoring_threshold] mt WITH (NOLOCK)
      ON mt.MT_monitoring_counter = mc.Monitoring_counter_ID
   WHERE mc.MC_is_visible = 1
     AND (   @param_group_counter_list IS NULL
          OR EXISTS(SELECT 1
                      FROM @tMonitoring_area_list mal
                     WHERE mal.Monitoring_area_ID = mc.MC_monitoring_area)
          )
   ORDER BY mc.MC_monitoring_area
           ,mc.Monitoring_counter_ID
           ,mh.MH_instance_name
           ,mh.MH_datetime

END /* donnees non-agregees */


/*---------- Calcul de la limite critique superieure lorsqu'elle est infinie -----------*/
/*--- (pour eviter les valeurs trop hautes qui pejorent les performances du rapport) ---*/
UPDATE cch1
   SET cch1.MT_critical_threshold_high = CASE WHEN (SELECT MAX(cch2.MH_max_value)
                                                      FROM @tCalcCounterHistory cch2
                                                     WHERE cch2.Monitoring_counter_ID = cch1.Monitoring_counter_ID) > cch1.MT_critical_threshold_low
                                              THEN (SELECT MAX(cch2.MH_max_value)
                                                      FROM @tCalcCounterHistory cch2
                                                     WHERE cch2.Monitoring_counter_ID = cch1.Monitoring_counter_ID) + 10
                                              ELSE cch1.MT_critical_threshold_low + 10
                                         END
  FROM @tCalcCounterHistory cch1
 WHERE cch1.MT_critical_threshold_low IS NOT NULL
   AND cch1.MT_critical_threshold_high IS NULL


/*---------------------- Dataset final ------------------*/
SELECT MC_monitoring_area
      ,Monitoring_counter_ID
      ,MH_instance_name
      ,MT_warning_threshold_low
      ,MT_warning_threshold_high
      ,MT_critical_threshold_low
      ,MT_critical_threshold_high
      ,MH_datetime
      ,MH_value
      ,MH_min_value
      ,MH_max_value
      ,MH_min_datetime
      ,MH_max_datetime
  FROM @tCalcCounterHistory


/*------------------ Retour au programme appelant -----------------*/ 

return(@@error); 

/*---------------------- Traitement des erreurs ----------------------*/ 
error_99: 
  raiserror( @result_sp, @errno, @errmsg ) ; 
  return(@errno);



GO


/******************************************************************************************/
/**********      User right for SP [mon_Get_Counters_History]   ***************************/
/******************************************************************************************/

use [HCITools]
GO
GRANT EXECUTE ON [dbo].[mon_Get_Counters_History] TO [sqlMonPerfUsr]
GO


/******************************************************************************************/
/**********      Create Job [DR92170 - Monitoring SQL Server Performances]    *************/
/******************************************************************************************/

/* Drop existing standard schedule for job */
declare @schedule_id int
declare c_schedules cursor local forward_only static for
    select ss.schedule_id
      from msdb.dbo.sysjobschedules sjs
INNER JOIN msdb.dbo.sysschedules ss
        ON sjs.schedule_id = ss.schedule_id
       AND ss.name NOT LIKE '%#SPEC#'
INNER JOIN msdb.dbo.sysjobs sj
        ON sjs.job_id = sj.job_id
     WHERE sj.name = N'DR92170 - Monitoring SQL Server Performances'

open c_schedules

FETCH NEXT FROM c_schedules into @schedule_id
while @@fetch_status = 0
begin
  IF ((select COUNT(*) from msdb.dbo.sysjobschedules where schedule_id=@schedule_id) = 1)
    EXEC msdb.dbo.sp_delete_schedule @schedule_id=@schedule_id, @force_delete = 1
FETCH NEXT FROM c_schedules into @schedule_id
end

close c_schedules

deallocate c_schedules

IF  EXISTS (SELECT job_id FROM msdb.dbo.sysjobs_view WHERE name = N'DR92170 - Monitoring SQL Server Performances')
EXEC msdb.dbo.sp_delete_job @job_name = N'DR92170 - Monitoring SQL Server Performances', @delete_unused_schedule=0
GO

IF  EXISTS (SELECT job_id FROM msdb.dbo.sysjobs_view WHERE name =  N'DR90290 - Monitoring SQL Server Counters')
EXEC msdb.dbo.sp_delete_job @job_name = N'DR90290 - Monitoring SQL Server Counters', @delete_unused_schedule=0
GO

/* Creation Job and Steps*/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0

IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'Database Maintenance' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'Database Maintenance'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END

/* Add Job */
DECLARE @jobId BINARY(16)
EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'DR92170 - Monitoring SQL Server Performances', 
		@enabled=1, 
		@notify_level_eventlog=0, 
		@notify_level_email=0, 
		@notify_level_netsend=0, 
		@notify_level_page=0, 
		@delete_level=0, 
		@description=N'This job get all performances of this server 

Created by: KLU
Date: 28.06.2018', 
		@category_name=N'Database Maintenance', 
		@start_step_id=1, 
		@owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Empty step', 
		@step_id=1, 
		@cmdexec_success_code=0, 
		@on_success_action=3, 
		@on_success_step_id=0, 
		@on_fail_action=3, 
		@on_fail_step_id=0, 
		@retry_attempts=0, 
		@retry_interval=0, 
		@os_run_priority=0, @subsystem=N'TSQL', 
		@command=N'/* Empty step */', 
		@database_name=N'master', 
		@output_file_name=NULL, 
		@flags=0, 
		@database_user_name=NULL, 
		@server=NULL, 
		@additional_parameters=NULL, 
		@proxy_id=NULL, 
		@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Get Counters Data', 
		@step_id=2, 
		@cmdexec_success_code=0, 
		@on_success_action=3, 
		@on_success_step_id=0, 
		@on_fail_action=4, 
		@on_fail_step_id=4, 
		@retry_attempts=0, 
		@retry_interval=0, 
		@os_run_priority=0, @subsystem=N'TSQL', 
		@command=N'EXECUTE [HCITools].[dbo].[mon_Collect_Counters_History]', 
		@database_name=N'HCITools', 
		@output_file_name=NULL, 
		@flags=0, 
		@database_user_name=NULL, 
		@server=NULL, 
		@additional_parameters=NULL, 
		@proxy_id=NULL, 
		@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Empty step for success', 
		@step_id=3, 
		@cmdexec_success_code=0, 
		@on_success_action=1, 
		@on_success_step_id=0, 
		@on_fail_action=4, 
		@on_fail_step_id=4, 
		@retry_attempts=0, 
		@retry_interval=0, 
		@os_run_priority=0, @subsystem=N'TSQL', 
		@command=N'/* Empty step */
exec Get_Job_Error_Info @in_JobName = ''DR92170 - Monitoring SQL Server Performances'', @in_Recipients = ''DBA_operator''', 
		@database_name=N'HCITools', 
		@output_file_name=NULL, 
		@flags=0, 
		@database_user_name=NULL, 
		@server=NULL, 
		@additional_parameters=NULL, 
		@proxy_id=NULL, 
		@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/* Add Step */
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Send email KO', 
		@step_id=4, 
		@cmdexec_success_code=0, 
		@on_success_action=2, 
		@on_success_step_id=0, 
		@on_fail_action=2, 
		@on_fail_step_id=0, 
		@retry_attempts=0, 
		@retry_interval=0, 
		@os_run_priority=0, @subsystem=N'TSQL', 
		@command=N'exec Get_Job_Error_Info @in_JobName = ''DR92170 - Monitoring SQL Server Performances'', @in_Recipients = ''DBA_operator''', 
		@database_name=N'HCITools', 
		@output_file_name=NULL, 
		@flags=0, 
		@database_user_name=NULL, 
		@server=NULL, 
		@additional_parameters=NULL, 
		@proxy_id=NULL, 
		@proxy_name=NULL
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

/* Add Standard Schedule */
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'DR92170-DR', 
		@enabled=1, 
		@freq_type=4, 
		@freq_interval=1, 
		@freq_subday_type=4, 
		@freq_subday_interval=5, 
		@freq_relative_interval=0, 
		@freq_recurrence_factor=0, 
		@active_start_date=20180719, 
		@active_end_date=99991231, 
		@active_start_time=0, 
		@active_end_time=235959
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

/* Attach existing specific schedule for job */
declare @enabled_schedule int,
        @schedule_name nvarchar(50)
declare c_schedules cursor local forward_only static for
select enabled, name
  from msdb.dbo.sysschedules
 where name LIKE 'DR92170%'
   and name LIKE '%#SPEC#'

open c_schedules

FETCH NEXT FROM c_schedules into @enabled_schedule, @schedule_name
while @@fetch_status = 0
begin
  EXEC @ReturnCode = msdb.dbo.sp_attach_schedule @job_id = @jobId, @schedule_name=@schedule_name
  IF(@enabled_schedule = 1)
  begin
    SET @schedule_name = SUBSTRING(@schedule_name,0,LEN(@schedule_name)-5)
    IF EXISTS (select name from msdb.dbo.sysschedules where name = @schedule_name)
      EXEC @ReturnCode = msdb.dbo.sp_update_schedule @name=@schedule_name, @enabled=0
  end
  IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
FETCH NEXT FROM c_schedules into @enabled_schedule, @schedule_name
end

close c_schedules

deallocate c_schedules

EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
    IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:

GO

-- #BUG 48620# [MH_value] could be NULL in table [HCITools].[dbo].[Monitoring_history]		[#SPE]

USE [HCITools]
GO

IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('Monitoring_history') AND name = 'MH_value' and is_nullable = 1)
BEGIN
  ALTER TABLE dbo.[Monitoring_history] ALTER COLUMN [MH_value] bigint NULL
END
GO