检查是否已在远程SQL Server上创建新数据库

时间:2014-08-12 17:34:55

标签: sql sql-server tsql

我的任务是在新数据库创建时建立警报。

我们有一个中央服务器,可以连接到我们所有的SQL服务器,并通过链接服务器捕获不同的指标。

我需要以某种方式捕获每个服务器上的所有数据库的列表,并将该列表存储在我的中央服务器上。然后每天运行几次SQL代理作业,将远程服务器上的当前数据库列表与中央服务器上的数据库列表进行比较。如果已在远程服务器上添加数据库或已删除数据库,请发送电子邮件。

我只是很难把各个部分放在一起,并且正在寻找任何有用的信息。如果一个方法更可行,我也会对另一种方法持开放态度。

此致 GB

5 个答案:

答案 0 :(得分:2)

你真的需要维护db的列表吗?如果没有,只需使用服务器范围的DDL触发器在创建或删除数据库时生成电子邮件。

CREATE TRIGGER trgCreateDatabase 
ON ALL SERVER 
FOR CREATE_DATABASE 
AS 
    DECLARE @Subj NVARCHAR(255) 
    DECLARE @MailBody NVARCHAR(MAX)

    SET @Subj = @@SERVERNAME + ' - Database Created'
    SELECT @MailBody = 
        'TSql Command: ' + EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)') + CHAR(13) + CHAR(10) +
        'Login Name: ' + EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]','nvarchar(max)')
    EXEC msdb..sp_send_dbmail
        @from_address = 'From@Someone.com',
        @recipients = 'To@Someeone.com', 
        @Subject = @Subj,
        @body = @MailBody
GO

CREATE TRIGGER trgDropDatabase 
ON ALL SERVER 
FOR DROP_DATABASE 
AS 
    DECLARE @Subj NVARCHAR(255) 
    DECLARE @MailBody NVARCHAR(MAX)

    SET @Subj = @@SERVERNAME + ' - Database Dropped'
    SELECT @MailBody = 
        'TSql Command: ' + EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)') + CHAR(13) + CHAR(10) +
        'Login Name: ' + EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]','nvarchar(max)')
    EXEC msdb..sp_send_dbmail
        @from_address = 'From@Someone.com',
        @recipients = 'To@Someeone.com', 
        @Subject = @Subj,
        @body = @MailBody
GO

答案 1 :(得分:1)

我曾经有一个维护数据库,它使用RegisteredDatabases表跟踪数据库。然后,SQL代理作业将按计划运行,并检查sys.databases是否从我的维护数据库知道的内容中移除。存储过程将引发错误,导致SQL代理作业通过警报系统发送电子邮件,或者只是从列表中删除数据库(通常仅在手动运行sproc时使用)。

以下代码用于我的专业项目。你需要从中取出你想要的碎片。

CREATE PROCEDURE [Configuration].[usp_RefreshRegisteredDatabases] 
    @Purge BIT = 0
AS 
    SET NOCOUNT ON;

    --Vars
    DECLARE @PurgeDBList udt_DatabaseList

    --Populate new databases, if there are any
    INSERT INTO [Configuration].[RegisteredDatabases] (DatabaseName)
            SELECT  [Sdb].[name]
            FROM    [sys].[databases] Sdb
                    LEFT OUTER JOIN [Configuration].[RegisteredDatabases] Rdb ON [Sdb].name = Rdb.DatabaseName
            WHERE   Rdb.DatabaseName IS NULL

    --Throw error if database(s) no longer exist but the @Purge flag is set to 0.
    IF EXISTS ( SELECT   [Rdb].[DatabaseName]
                FROM     [sys].[databases] Sdb
                        RIGHT OUTER JOIN [Configuration].[RegisteredDatabases] Rdb ON [Sdb].name = Rdb.DatabaseName
                WHERE    Sdb.name IS NULL)
                AND @Purge = 0 
        BEGIN
            RAISERROR('Registered database(s) no longer exists. If any configurations are pointing to this database they will fail. Query Configuration.vwOrphanedDatabases for more details.',16,1)
        END 

    --Remove databases from the list where they don't exist anymore
    IF EXISTS ( SELECT   [Rdb].[DatabaseName]
                FROM     [sys].[databases] Sdb
                        RIGHT OUTER JOIN [Configuration].[RegisteredDatabases] Rdb ON [Sdb].name = Rdb.DatabaseName
                WHERE    Sdb.name IS NULL )
                AND @Purge = 1
        BEGIN  
            INSERT INTO @PurgeDBList (RegisteredDatabaseID, DatabaseName)
            SELECT   Rdb.DatabaseID, [Rdb].[DatabaseName]
            FROM     [sys].[databases] Sdb
            RIGHT OUTER JOIN [Configuration].[RegisteredDatabases] Rdb ON [Sdb].name = Rdb.DatabaseName
            WHERE    Sdb.name IS NULL

            EXEC [Configuration].[usp_PurgeAllReferencesToDatabase] @DatabaseList = @PurgeDBList        
        END

答案 2 :(得分:0)

我假设您已经拥有服务器列表。循环查询sys.databases的服务器列表。使用动态SQL生成链接服务器查询。

答案 3 :(得分:0)

您可以使用SSIS。 SSIS包可以发送到服务器执行以下SQL -

USE master;
SELECT @@ServerName, NAME FROM sysdatabases;

并对具有数据库列表的中央服务器进行查找,并标记数据库中不存在的数据库并插入它们。

答案 4 :(得分:0)

我可能会使用PowerShell版本。

 import-module sqlps
 DIR SQLSERVER:\SQL\localhost\DEFAULT\Databases | select Name

更改每个服务器的localhost,将列表转储到内存中并加载到SQL中以获取永久记录。您还可以快速比较主列表。

或者,因为您已经在使用链接服务器,所以查询

select @@servername, name from linkedserver.master.sys.databases

与主列表进行比较。