sql >> Base de Datos >  >> RDS >> Database

Sistema de correo electrónico automático para enviar el informe de resumen de la base de datos

El monitoreo de la base de datos es el trabajo más esencial de cualquier administrador de base de datos. Las grandes organizaciones y empresas tienen múltiples servidores de bases de datos que están ubicados en el mismo centro de datos o en centros de datos geográficamente diferentes. Existen muchas herramientas estándar para el monitoreo de bases de datos. Esas herramientas utilizan las vistas de administración dinámica de SQL Server y el procedimiento almacenado del sistema para completar los datos. Con estos DMV, podemos crear nuestro sistema automatizado personalizado para completar el estado de la base de datos y enviar el informe por correo electrónico.

En este artículo, demostraré cómo podemos usar el procedimiento almacenado del sistema y el servidor vinculado para completar la información de las bases de datos ubicadas en diferentes servidores y programar el trabajo para enviar el informe.

En esta demostración, voy a realizar las siguientes tareas:

  1. Cree los procedimientos almacenados requeridos en TTI609-VM1 , TTI609-VM2, y TTI412-VM servidores para completar la información de la base de datos, los objetos de la base de datos y los trabajos de SQL.
  2. Cree un procedimiento almacenado para completar el resumen de la base de datos, el resumen del objeto de la base de datos y el resumen del trabajo SQL desde el TTI609-VM1 y TTI609-VM2 servidores y almacenarlos en tablas relacionadas.
  3. Cree un paquete SSIS que realice las siguientes tareas:
      • Ejecuta un procedimiento almacenado usando Ejecutar tarea de secuencia de comandos SQL .
      • Exportar datos de tablas SQL creadas en TTI412-VM y guárdelo en la pestaña individual de un archivo de Excel.
  4. Cree un trabajo de SQL Server para ejecutar el paquete SSIS para completar la información de la base de datos y el procedimiento almacenado para enviar el informe por correo electrónico.

La siguiente imagen ilustra la configuración de demostración:

La siguiente es la lista de procedimientos almacenados:

A continuación se muestra la lista de tablas:

Crear procedimientos almacenados en ambos servidores de bases de datos

Como mencioné, vamos a completar los datos del TTI609-VM1 y TTI609-VM2 servidores. Los procedimientos almacenados utilizados para llenar la base de datos seguirán siendo los mismos en ambos servidores.
En primer lugar, he creado una base de datos llamada DBATools en ambos servidores. Creé un procedimiento almacenado en esas bases de datos. Para ello, ejecute el siguiente código en el TTI609-VM1 y TTI609-VM2 servidores:

USE [master] 
go 
/****** Object:  Database [DBATools]    Script Date: 10/25/2018 11:25:27 AM ******/ 
CREATE DATABASE [DBATools] containment = none ON PRIMARY ( NAME = N'DBATools', 
filename = 
N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\DBATools.mdf' 
, size = 3264kb, maxsize = unlimited, filegrowth = 1024kb ) log ON ( NAME = 
N'DBATools_log', filename = 
N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\DBATools_log.ldf' 
, size = 816kb, maxsize = 2048gb, filegrowth = 10%) 
go

Cree un procedimiento almacenado llamado Pull_Database_Information en DBATools base de datos. Este procedimiento almacenado completa la siguiente información de todas las bases de datos existentes en ambos servidores de bases de datos.

  1. Nombre de la base de datos.
  2. Nivel de compatibilidad de la base de datos.
  3. Estado de la base de datos (ONLINE/OFFLINE/RESTORING/SUSPEND).
  4. Modelo de recuperación de base de datos (SIMPLE / FULL / BULK-LOGGED).
  5. Tamaño de la base de datos en MB.
  6. Tamaño total del archivo de datos.
  7. Tamaño del archivo de datos usado.
  8. Tamaño total del archivo de registro.
  9. Tamaño del archivo de registro utilizado.

Ejecute el siguiente código en las DBATools base de datos de ambos servidores de bases de datos para crear el procedimiento almacenado:

USE DBAtools 
go 
CREATE PROCEDURE Pull_Database_Information 
AS 
  BEGIN 
      IF Object_id('tempdb.dbo.#DBSize') IS NOT NULL 
        DROP TABLE #dbsize 

      CREATE TABLE #dbsize 
        ( 
           database_id         INT PRIMARY KEY, 
           data_file_used_size DECIMAL(18, 2), 
           log_file_used_size  DECIMAL(18, 2) 
        ) 

      DECLARE @SQLCommand NVARCHAR(max) 

      SELECT @SQLCommand = Stuff((SELECT '     USE [' + d.NAME + ']     INSERT INTO #DBSize (database_id, data_file_used_size, log_File_used_size)     SELECT           DB_ID()         , SUM(CASE WHEN [type] = 0 THEN space_used END)         , SUM(CASE WHEN [type] = 1 THEN space_used END)     FROM (         SELECT s.[type], space_used = SUM(FILEPROPERTY(s.name, ''SpaceUsed'') * 8. / 1024)         FROM sys.database_files s         GROUP BY s.[type]     ) t;' 
                                  FROM   sys.databases d 
                                  WHERE  d.[state] = 0 
                                  FOR xml path(''), type).value('.', 
                           'NVARCHAR(MAX)'), 
                           1, 2, 
                                  '') 

      EXEC sys.Sp_executesql 
        @SQLCommand 

      SELECT d.database_id         AS 'Database ID', 
             d.NAME                AS 'Database Name', 
             d.state_desc          AS 'Database State', 
             d.recovery_model_desc AS 'Recovery Model', 
             t.total_db_size       AS 'Database Size', 
             t.data_file_size      AS 'Data File Size', 
             s.data_file_used_size AS 'Data File Used', 
             t.log_file_size       AS 'Log file size', 
             s.log_file_used_size  AS 'Log File Used' 
      FROM   (SELECT database_id, 
                     log_file_size = Cast(Sum(CASE 
                                                WHEN [type] = 1 THEN size 
                                              END) * 8. / 1024 AS DECIMAL(18, 2) 
                                     ), 
                     data_file_size = Cast(Sum(CASE 
                                                 WHEN [type] = 0 THEN size 
                                               END) * 8. / 1024 AS 
                                           DECIMAL(18, 2)) 
                     , 
                     total_DB_size = Cast( 
                     Sum(size) * 8. / 1024 AS DECIMAL(18, 2)) 
              FROM   sys.master_files 
              GROUP  BY database_id) t 
             JOIN sys.databases d 
               ON d.database_id = t.database_id 
             LEFT JOIN #dbsize s 
                    ON d.database_id = s.database_id 
      ORDER  BY t.total_db_size DESC 
  END

En segundo lugar, cree procedimientos almacenados llamados Pull_Database_Objects en DBATools base de datos. Este procedimiento almacenado itera a través de todas las bases de datos dentro de ambos servidores de bases de datos y completa el recuento de todos los objetos de la base de datos. Llena las siguientes columnas:

  1. Servidor/Nombre de host.
  2. Nombre de la base de datos.
  3. Tipo de objeto de la base de datos (tabla/procedimiento almacenado/funciones de SQL Scaler/restricciones, etc.)
  4. Número total de objetos de la base de datos.

Ejecute el siguiente código en DBATools base de datos en ambos servidores de bases de datos para crear el procedimiento almacenado:

USE dbatools 
go 

CREATE PROCEDURE [Pull_database_objects] 
AS 
  BEGIN 
      CREATE TABLE #finalsummery 
        ( 
           id           INT IDENTITY (1, 1), 
           databasename VARCHAR(350), 
           objecttype   VARCHAR(200), 
           totalobjects INT 
        ) 

      DECLARE @SQLCommand NVARCHAR(max) 
      DECLARE @I INT=0 
      DECLARE @DBName VARCHAR(350) 
      DECLARE @DBCount INT 

      CREATE TABLE #databases 
        ( 
           NAME VARCHAR(350) 
        ) 

      INSERT INTO #databases 
                  (NAME) 
      SELECT NAME 
      FROM   sys.databases 
      WHERE  database_id > 4 
             AND NAME NOT IN ( 'ReportServer', 'reportservertempdb' ) 

      SET @DBCount=(SELECT Count(*) 
                    FROM   #databases) 

      WHILE ( @DBCount > @I ) 
        BEGIN 
            SET @DBName=(SELECT TOP 1 NAME 
                         FROM   #databases) 
            SET @SQLCommand='             Insert Into #FinalSummery (DatabaseName,ObjectType,TotalObjects)             Select              ''' + @DBName 
                            + ''',             Case                 when Type=''TR'' then ''SQL DML trigger''              when Type=''FN'' then ''SQL scalar function''              when Type=''D'' then ''DEFAULT (constraint or stand-alone)''              when Type=''PK'' then ''PRIMARY KEY constraint''              when Type=''P'' then ''SQL Stored Procedure''              when Type=''U'' then ''Table (user-defined)''              when Type=''V''  then ''View''              when Type=''X'' then ''Extended stored procedure''             End As ObjectType,              Count(Name)TotalObjects from ' + @DBName 
                            + '.sys.all_objects               group by type' 

            EXEC Sp_executesql 
              @SQLCommand 

            DELETE FROM #databases 
            WHERE  NAME = @DBName 

            SET @[email protected] + 1 
        END 

      SELECT Host_name() AS 'Server Name', 
             databasename, 
             objecttype, 
             totalobjects, 
             Getdate()   AS 'ReportDate' 
      FROM   #finalsummery 
      WHERE  objecttype IS NOT NULL 

      DROP TABLE #finalsummery 
  END

Cree procedimientos almacenados llamados Pull_SQLJob_Information en DBATools base de datos. Este procedimiento almacenado itera a través de todo el servidor de la base de datos y completa la información de todos los trabajos de SQL y sus estados. Llena las siguientes columnas:

  1. Servidor/Nombre de host.
  2. Nombre del trabajo SQL.
  3. Propietario del trabajo de SQL.
  4. Categoría de trabajo.
  5. Descripción del trabajo.
  6. Estado del trabajo (habilitado/inhabilitado)
  7. Una fecha de creación de empleo.
  8. Fecha de modificación del trabajo.
  9. Estado del trabajo programado.
  10. Nombre del horario.
  11. Fecha y hora de la última ejecución
  12. Último estado de ejecución.

Ejecute el siguiente código en las DBATools base de datos en ambos servidores de bases de datos para crear el procedimiento almacenado:

CREATE PROCEDURE Pull_sqljob_information 
AS 
  BEGIN 
      SELECT Host_name()       AS 'Server Name', 
             a.NAME            AS 'Job Name', 
             d.NAME            AS Owner, 
             b.NAME            AS Category, 
             a.description     AS Description, 
             CASE a.enabled 
               WHEN 1 THEN 'Yes' 
               WHEN 0 THEN 'No' 
             END               AS 'IsEnabled', 
             a.date_created    AS CreatedDate, 
             a.date_modified   AS ModifiedDate, 
             CASE 
               WHEN f.schedule_uid IS NULL THEN 'No' 
               ELSE 'Yes' 
             END               AS 'Scheduled?', 
             f.NAME            AS JobScheduleName, 
             Max(Cast( 
      Stuff(Stuff(Cast(g.run_date AS VARCHAR), 7, 0, '-'), 5, 0, '-') 
           + ' ' 
           + 
Stuff(Stuff(Replace(Str(g.run_time, 6, 0), ' ', '0'), 5, 0, ':'), 3, 0, ':') 
AS DATETIME)) AS [LastRun], 
CASE g.run_status 
WHEN 0 THEN 'Failed' 
WHEN 1 THEN 'Success' 
WHEN 2 THEN 'Retry' 
WHEN 3 THEN 'Canceled' 
WHEN 4 THEN 'In progress' 
END               AS Status 
FROM   msdb.dbo.sysjobs AS a 
       INNER JOIN msdb.dbo.sysjobhistory g 
               ON a.job_id = g.job_id 
       LEFT JOIN msdb.dbo.syscategories AS b 
              ON a.category_id = b.category_id 
       LEFT JOIN msdb.dbo.sysjobsteps AS c 
              ON a.job_id = c.job_id 
                 AND a.start_step_id = c.step_id 
       LEFT JOIN msdb.sys.database_principals AS d 
              ON a.owner_sid = d.sid 
       LEFT JOIN msdb.dbo.sysjobschedules AS e 
              ON a.job_id = e.job_id 
       LEFT JOIN msdb.dbo.sysschedules AS f 
              ON e.schedule_id = f.schedule_id 
GROUP  BY a.NAME, 
          d.NAME, 
          b.NAME, 
          a.description, 
          a.enabled, 
          f.schedule_uid, 
          f.NAME, 
          a.date_created, 
          a.date_modified, 
          g.run_status 
ORDER  BY a.NAME 
END

Crear procedimientos almacenados, servidor vinculado y tablas en el servidor central

Una vez creados los procedimientos en el TTI609-VM1 y TTI609-VM2 servidores de bases de datos, cree procedimientos y tablas necesarios en el servidor central (TTI412-VM ).

Creé una base de datos separada llamada MonitoringDashboard en el TTI412-VM servidor. Ejecute el siguiente código para crear una base de datos en el servidor central.

USE [master] 
go 

/****** Object:  Database [MonitoringDashboard]    Script Date: 10/25/2018 2:44:09 PM ******/ 

CREATE DATABASE [MonitoringDashboard] containment = none ON PRIMARY ( NAME = 
N'MonitoringDashboard', filename = 
N'E:\MS_SQL\SQL2017_Data\MonitoringDashboard.mdf', size = 8192kb, maxsize = 
unlimited, filegrowth = 65536kb ) log ON ( NAME = N'MonitoringDashboard_log', 
filename = N'E:\MS_SQL\SQL2017_Log\MonitoringDashboard_log.ldf', size = 8192kb, 
maxsize = 2048gb, filegrowth = 65536kb ) 

go

Una vez que se haya creado la base de datos, cree un procedimiento almacenado que use LINKED Server para ejecutar un procedimiento en el TTI609-VM1 y TTI609-VM2 servidores de bases de datos. Ejecute el siguiente código en la base de datos "maestra" del TTI412-VM servidor de base de datos para crear un servidor vinculado:

Script 1:Crear servidor vinculado TTI609-VM1

USE [master] 
go 
/****** Object:  LinkedServer [TTI609-VM1]    Script Date: 10/25/2018 2:49:28 PM ******/ 
EXEC master.dbo.Sp_addlinkedserver 
  @server = N'TTI609-VM1', 
  @srvproduct=N'SQL Server' 

/* For security reasons the linked server remote logins password is changed with ######## */ 
EXEC master.dbo.Sp_addlinkedsrvlogin 
  @rmtsrvname=N'TTI609-VM1', 
  @useself=N'False', 
  @locallogin=NULL, 
  @rmtuser=N'sa', 
  @rmtpassword='########' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM1', 
  @optname=N'collation compatible', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM1', 
  @optname=N'data access', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM1', 
  @optname=N'dist', 
  @optvalue=N'false' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM1', 
  @optname=N'rpc', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM1', 
  @optname=N'rpc out', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM1', 
  @optname=N'connect timeout', 
  @optvalue=N'0' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM1', 
  @optname=N'query timeout', 
  @optvalue=N'0' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM1', 
  @optname=N'use remote collation', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM1', 
  @optname=N'remote proc transaction promotion', 
  @optvalue=N'false' 

go

Guión 2:Crear servidor vinculado TTI609-VM2

USE [master] 

go 

/****** Object:  LinkedServer [TTI609-VM2]    Script Date: 10/25/2018 2:55:29 PM ******/ 
EXEC master.dbo.Sp_addlinkedserver 
  @server = N'TTI609-VM2', 
  @srvproduct=N'SQL Server' 

/* For security reasons the linked server remote logins password is changed with ######## */ 
EXEC master.dbo.Sp_addlinkedsrvlogin 
  @rmtsrvname=N'TTI609-VM2', 
  @useself=N'False', 
  @locallogin=NULL, 
  @rmtuser=N'sa', 
  @rmtpassword='########' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'collation compatible', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'data access', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'dist', 
  @optvalue=N'false' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'rpc', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'rpc out', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'connect timeout', 
  @optvalue=N'0' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'collation name', 
  @optvalue=NULL 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'query timeout', 
  @optvalue=N'0' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'use remote collation', 
  @optvalue=N'true' 

go 

EXEC master.dbo.Sp_serveroption 
  @server=N'TTI609-VM2', 
  @optname=N'remote proc transaction promotion', 
  @optvalue=N'false' 

go

Crear un procedimiento almacenado y tablas

Una vez que se ha creado el servidor vinculado, necesitamos crear tres tablas llamadas Database_Object_Summery , Base de datos_Summery y SQL_Job_List en el Panel de control base de datos. Estas tablas almacenan información completada por Generate_Database_Information procedimiento almacenado y posteriormente los datos, almacenados en esas tablas que se utilizarán para generar un informe en excel.

Ejecute el siguiente código para crear la SQL_Job_List tabla:

USE [MonitoringDashboard] 
go 

CREATE TABLE [dbo].[sql_job_list] 
  ( 
     [id]             [INT] IDENTITY(1, 1) NOT NULL, 
     [servername]     [VARCHAR](250) NULL, 
     [jobname]        [VARCHAR](250) NULL, 
     [jobowner]       [VARCHAR](250) NULL, 
     [jobcategory]    [VARCHAR](250) NULL, 
     [jobdescription] [VARCHAR](250) NULL, 
     [jobstatus]      [VARCHAR](50) NULL, 
     [createdate]     [DATETIME] NULL, 
     [modifieddate]   [DATETIME] NULL, 
     [isscheduled]    [VARCHAR](5) NULL, 
     [schedulename]   [VARCHAR](250) NULL, 
     [reportdate]     [DATETIME] NULL 
  ) 
ON [PRIMARY] 

go 

ALTER TABLE [dbo].[sql_job_list] 
  ADD DEFAULT (Getdate()) FOR [ReportDate] 

go

Ejecute el siguiente código para crear los lst_dbservers tabla:

USE [MonitoringDashboard] 

go 

CREATE TABLE [dbo].[lst_dbservers] 
  ( 
     [id]         [INT] IDENTITY(1, 1) NOT NULL, 
     [servername] [VARCHAR](50) NOT NULL, 
     [addeddate]  [DATETIME] NOT NULL, 
     PRIMARY KEY CLUSTERED ( [id] ASC )WITH (pad_index = OFF, 
     statistics_norecompute = OFF, ignore_dup_key = OFF, allow_row_locks = on, 
     allow_page_locks = on) ON [PRIMARY], 
     UNIQUE NONCLUSTERED ( [servername] ASC )WITH (pad_index = OFF, 
     statistics_norecompute = OFF, ignore_dup_key = OFF, allow_row_locks = on, 
     allow_page_locks = on) ON [PRIMARY] 
  ) 
ON [PRIMARY] 

go 

ALTER TABLE [dbo].[lst_dbservers] 
  ADD DEFAULT (Getdate()) FOR [AddedDate] 

go

Ejecute el siguiente código para crear la Database_Summery tabla:

USE [MonitoringDashboard] 
go 
CREATE TABLE [dbo].[database_summery] 
  ( 
     [id]                 [INT] IDENTITY(1, 1) NOT NULL, 
     [servername]         [VARCHAR](150) NULL, 
     [databaseid]         [INT] NULL, 
     [databasename]       [VARCHAR](250) NULL, 
     [databasestatus]     [VARCHAR](50) NULL, 
     [recoverymodel]      [VARCHAR](50) NULL, 
     [compatibilitylevel] [INT] NULL, 
     [databasecreatedate] [DATE] NULL, 
     [databasecreatedby]  [VARCHAR](150) NULL, 
     [dbsize]             [NUMERIC](10, 2) NULL, 
     [datafilesize]       [NUMERIC](10, 2) NULL, 
     [datafileused]       [NUMERIC](10, 2) NULL, 
     [logfilesize]        [NUMERIC](10, 2) NULL, 
     [logfileused]        [NUMERIC](10, 2) NULL, 
     [reportdate]         [DATETIME] NULL 
  ) 
ON [PRIMARY] 
go 

ALTER TABLE [dbo].[database_summery] 
  ADD DEFAULT (Getdate()) FOR [ReportDate] 
go

Ejecute el siguiente código para crear el Database_Object_Summery tabla:

USE [MonitoringDashboard] 

go 

CREATE TABLE [dbo].[database_object_summery] 
  ( 
     [id]           [INT] IDENTITY(1, 1) NOT NULL, 
     [servername]   [VARCHAR](250) NULL, 
     [databasename] [VARCHAR](250) NULL, 
     [objecttype]   [VARCHAR](50) NULL, 
     [objectcount]  [INT] NULL, 
     [reportdate]   [DATETIME] NULL 
  ) 
ON [PRIMARY] 

go 

ALTER TABLE [dbo].[database_object_summery] 
  ADD DEFAULT (Getdate()) FOR [ReportDate] 

go

Una vez creadas las tablas, cree un procedimiento almacenado llamado Generate_Database_Information en el Panel de control base de datos. Utilizando “RPC”, ejecuta procedimientos almacenados, creados en el TTI609-VM1 y TTI609-VM2 servidores de bases de datos para completar los datos.

Ejecute el siguiente código para crear un procedimiento almacenado:

Create PROCEDURE Generate_database_information 
AS 
  BEGIN 
      /*Cleanup*/ 
      TRUNCATE TABLE database_object_summery 
      TRUNCATE TABLE database_summery 
      TRUNCATE TABLE sql_job_list 

      DECLARE @ServerCount INT 
      DECLARE @i INT =0 
      DECLARE @SQLCommand_Object_Summery NVARCHAR(max) 
      DECLARE @SQLCommand_Database_Information NVARCHAR(max) 
      DECLARE @SQLCommand_SQL_Job_Information NVARCHAR(max) 
      DECLARE @servername VARCHAR(100) 

      CREATE TABLE #db_server_list 
        ( 
           servername VARCHAR(100) 
        ) 

      INSERT INTO #db_server_list 
                  (servername) 
      SELECT servername 
      FROM   lst_dbservers 

      SET @ServerCount= (SELECT Count(servername) 
                         FROM   #db_server_list) 

      WHILE ( @ServerCount > @i ) 
        BEGIN 
            SET @servername=(SELECT TOP 1 servername 
                             FROM   #db_server_list) 
            SET @SQLCommand_Object_Summery = 
'insert into Database_Object_Summery (ServerName,DatabaseName,ObjectType,ObjectCount,ReportDate) exec [' 
+ @servername 
+ '].DBATools.dbo.[Pull_Database_Objects]' 
    SET @SQLCommand_Database_Information = 
'insert into Database_Summery (ServerName,DatabaseID,DatabaseName,DatabaseStatus,Recoverymodel,CompatibilityLevel,DatabaseCreateDate,DatabaseCreatedBy,DBSize,DataFileSize,DataFileUsed,LogFileSize,LogFileUsed) exec [' 
+ @servername 
+ '].DBATools.dbo.[Pull_Database_Information]' 
    SET @SQLCommand_SQL_Job_Information = 
'insert into SQL_Job_List (ServerName,JobName,JobOwner,Jobcategory,JobDescription,JobStatus,CreateDate,ModifiedDate,IsScheduled,ScheduleName) exec [' 
+ @servername 
+ '].DBATools.dbo.[Pull_SQLJob_Information]' 

    EXEC Sp_executesql 
      @SQLCommand_Object_Summery 

    EXEC Sp_executesql 
      @SQLCommand_Database_Information 

    EXEC Sp_executesql 
      @SQLCommand_SQL_Job_Information 

    DELETE FROM #db_server_list 
    WHERE  servername = @servername 

    SET @[email protected] + 1 
END 
END

Una vez creado el procedimiento, cree un paquete SSIS para exportar datos a un archivo de Excel.

Crear paquete SSIS para exportar datos en un archivo de Excel

En mis artículos anteriores, expliqué los pasos para configurar las tareas de flujo de datos, las conexiones OLEDB y las conexiones de Excel, por lo que omito esta parte.

Para exportar datos a un archivo de Excel, abra las herramientas de datos de SQL Server y cree un nuevo proyecto SSIS llamado Export_Database_Information.

Una vez creado el proyecto, arrastre y suelte Ejecutar tarea SQL al Flujo de control y cámbiele el nombre a Rellenar datos de servidores . Ver la siguiente imagen:

Haga doble clic en Ejecutar tarea SQL (Rellenar datos del servidor). El Editor de tareas Ejecutar SQL Se abre el cuadro de diálogo para configurar la conexión SQL. Ver la siguiente imagen:

En la Conexión archivado, seleccione el OLEDB cadena de conexión y en la instrucción SQL campo, proporcione la siguiente consulta:

USE monitoringdashboard 
go 
EXEC Generate_database_information

Haga clic en Aceptar para cerrar el cuadro de diálogo.

En el Flujo de control pantalla, arrastre y suelte Tarea de flujo de datos desde SSIS Toolbox y cámbiele el nombre a Generar informe. Ver la siguiente imagen:

Haga doble clic para abrir el Flujo de datos ventana.

Como mencioné anteriormente, Generar_información_de_base_de_datos procedimiento inserta la salida de los servidores de base de datos en las siguientes tablas:

  1. Database_Object_Summery
  2. Base de datos_Summery
  3. SQL_Job_List

Creé un archivo de Excel que tiene tres hojas de trabajo. Las siguientes tablas muestran el mapeo de las tablas SQL y la hoja de cálculo de Excel.


En el Flujo de datos ventana, arrastre y suelte tres fuentes de ADO.Net y tres destinos de Excel. Ver la siguiente imagen:

Haga doble clic en Resumen de objetos y (Fuente ADO.NET) en Fuente ADO.NET Editor.

  1. Seleccione TTI412-VM\SQL2017MonitoringDashboard desde el administrador de conexiones ADO.NET cuadro desplegable.
  2. Seleccione Tabla o Vista desde el Modo de acceso a datos cuadro desplegable.
  3. Seleccione Database_Object_Summery de Nombre de la tabla o de la vista cuadro desplegable.

Haga doble clic en Información de la base de datos (Fuente de ADO.NET) en Editor de fuente de ADO.NET .

  1. Seleccione "TTI412-VM\SQL2017MonitoringDashboard ” del administrador de conexiones ADO.NET cuadro desplegable.
  2. Seleccione Tabla o Vista desde el Modo de acceso a datos cuadro desplegable.
  3. Seleccione "Database_Summery ” del Nombre de la tabla o la vista cuadro desplegable.

Haga doble clic en Trabajos de SQL. (Fuente de ADO.NET) en Editor de fuente de ADO.NET .

  1. Seleccione TTI412-VM\SQL2017MonitoringDashboard en el administrador de conexiones ADO.NET.
  2. Seleccione Tabla o Vista desde el modo de acceso a datos cuadro desplegable.
  3. Seleccione SQL_Job_List en el Nombre de la tabla o de la vista cuadro desplegable.

Ahora, arrastre y suelte tres destinos de Excel desde SSIS Toolbox. Ver la siguiente imagen:

Una vez que se hayan copiado los destinos, arrastre la flecha azul debajo de la fuente ADO.Net y suéltela en el destino de Excel. Haz lo mismo para todos. Ver la siguiente imagen:

Haga doble clic en Resumen de objetos de Excel (Origen de ADO.NET) en Editor de destino de Excel .

  1. Seleccione Administrador de conexión de Excel desde el administrador de conexiones de Excel cuadro desplegable.
  2. Seleccione Ttabla o Ver desde el Modo de acceso a datos cuadro desplegable.
  3. Seleccione Objeto Summery$ del Nombre de la hoja de Excel cuadro desplegable.

Como mencioné, los nombres de columna de la tabla SQL y las columnas de Excel son los mismos, por lo tanto, el mapeo se realizará automáticamente. Haz clic en Mapeo para mapear las columnas. Ver la siguiente imagen:

Haga doble clic en Información de la base de datos de Excel (Destino de Excel) en Editor de destino de Excel .

  1. Seleccione Administrador de conexión de Excel desde el administrador de conexiones de Excel cuadro desplegable.
  2. Seleccione Ttabla o Ver desde el Modo de acceso a datos cuadro desplegable.
  3. Seleccione Información de la base de datos$ del Nombre de la hoja de Excel cuadro desplegable.

Como mencioné, los nombres de columna de la tabla SQL y las columnas de Excel son los mismos, por lo tanto, el mapeo se realizará automáticamente. Haz clic en Mapeo para mapear las columnas. Ver la siguiente imagen:

Haga doble clic en Excel SQL Jobs. (Destino de Excel) en Editor de destino de Excel .

  1. Seleccione Administrador de conexión de Excel desde el administrador de conexiones de Excel cuadro desplegable.
  2. Seleccione Ttabla o Ver desde el Modo de acceso a datos cuadro desplegable.
  3. Seleccione "Trabajos de SQL$ en el Nombre de la hoja de Excel cuadro desplegable.

Como mencioné, los nombres de columna de la tabla SQL y las columnas de Excel son los mismos, por lo tanto, el mapeo se realizará automáticamente. Haz clic en Mapeo para mapear las columnas. Ver la siguiente imagen:

Cree un trabajo de SQL para enviar por correo electrónico el informe de la base de datos

Una vez creado el paquete, cree un trabajo SQL para realizar las siguientes actividades:

  1. Ejecute el paquete SSIS para completar los datos de todos los servidores.
  2. Envíe por correo electrónico el informe de la base de datos al equipo requerido.

En SQL Job, necesitamos crear dos pasos. El primer paso ejecutará el paquete SSIS y el segundo paso ejecutará el procedimiento para enviar un correo electrónico.

Para crear un trabajo SQL, abra SSMS>> Agente SQL Server>> Haga clic derecho en Nuevo trabajo SQL .

Om el nuevo trabajo asistente, seleccione el Paso opción y haga clic en Ne w. En el paso de nuevo trabajo cuadro de diálogo, en el Paso nombre cuadro de texto, proporcione el nombre deseado, seleccione Paquete de servicios de integración de SQL Server del Tipo caja desplegable. Proporcione una ubicación del paquete SSIS en el Texto del paquete caja. Ver la siguiente imagen:

Haga clic en Aceptar para cerrar Nuevo paso de trabajo .

Cree otro paso de trabajo que ejecutará un procedimiento almacenado para enviar el informe por correo electrónico. Utiliza un procedimiento del sistema para enviar un correo electrónico. El paquete SSIS copia la información de la base de datos en una ubicación específica, por lo que proporciona la ruta completa del archivo de Excel en el parámetro @file_attachments de sp_send_dbmail procedimiento almacenado.

Para crear el procedimiento almacenado, ejecute el siguiente código en DBATools base de datos del Servidor Central:

CREATE PROCEDURE Send_database_report 
AS 
  BEGIN 
      DECLARE @ProfileName VARCHAR(150) 

      SET @ProfileName = (SELECT NAME 
                          FROM   msdb..sysmail_profile 
                          WHERE  profile_id = 7) 

      DECLARE @lsMessage NVARCHAR(max) 

      SET @lsMessage = '<p style="font-family:Arial; font-size:10pt">   Hello Support,   Please find attached database summery report.      ' + '</p>' 

      EXEC msdb.dbo.Sp_send_dbmail 
        @recipients='[email protected]', 
        @[email protected], 
        @subject='Database Summery Report', 
        @file_attachments= 
      'C:\Users\Administrator\Desktop\Database_Information.xlsx', 
        @copy_recipients='', 
        @blind_copy_recipients='', 
        @body_format='HTML', 
        @[email protected] 
  END

Once the procedure is created, add a new SQL Job paso. Click New . In the New Job Step dialog box, provide a Job Step name, and select Transact-SQL script (T-SQL) from the Type drop-down box. In the Command Text box, write the following code:

USE DBAtools 
Go 

EXEC Send_database_report

See the following image:

Click OK to close the wizard. Now to configure Job Schedule , select Schedules on the New Job ventana. Click New to add a schedule.

In the New Job Schedule dialog box, provide the desired name in the Name text box, choose frequency and time. See the following image:

Close OK to close the New Job Schedule and in the New Job window, click on OK to close the dialog box.

Now, to test the SQL Job, right-click the Email Database Report SQL job and click Start Job at Step .

In the result of successful completion of the SQL Job, you will receive an email with the database report. See the following image:

Resumen

In this article I have covered as follows:

  1. How to populate information of the databases located on remote DB server.
  2. Create an SSIS package to populate database information and export it to excel file
  3. Create a multi-step SQL job to generate the report by executing an SSIS package and email the report.