简体   繁体   English

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

[英]Check if new Database has been created on remote SQL Server

I have been tasked with building an alert on new database creation. 我的任务是建立有关新数据库创建的警报。

We have a central server that reaches out to all of our SQL servers and captures different metrics via linked servers. 我们有一个中央服务器,可以连接到所有SQL服务器,并通过链接的服务器捕获不同的指标。

I need to somehow capture a list of all databases on each server and store that list on my central server. 我需要以某种方式捕获每台服务器上所有数据库的列表,并将该列表存储在我的中央服务器上。 Then a couple times a day run a SQL Agent job that compares the current database list on the remote server to the database list on the central server. 然后一天运行几次SQL Agent作业,将远程服务器上的当前数据库列表与中央服务器上的数据库列表进行比较。 And if a database has been added on the remote server or been removed send an e-mail. 并且,如果已在远程服务器上添加或删除了数据库,请发送电子邮件。

I am just having a hard time putting the pieces together and was looking for any helpful information. 我很难拼凑内容,一直在寻找任何有用的信息。 I would also be open to a different method if one would be more feasible. 如果一种方法更可行,我也会持不同的态度。

Regards gb 关于gb

Do you really have the need to maintain the list of db's? 您是否真的需要维护数据库列表? If not, just use a server-scoped DDL trigger to generate an email whenever a db is created or dropped. 如果不是,只要创建或删除数据库,就使用服务器作用域的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

I once had a maintenance database that kept track of the databases by using a RegisteredDatabases table. 我曾经有一个维护数据库,该数据库通过使用RegisteredDatabases表来跟踪数据库。 Then a SQL Agent job would run on a schedule and check to see if sys.databases drifted from what my maintenance database was aware of. 然后,SQL Agent作业将按计划运行,并检查sys.databases是否偏离了维护数据库所知道的范围。 The stored procedure would either throw an error causing the SQL Agent job to send an email via the alert system or simply remove the database from the list (usually only used when the sproc was manually run). 存储过程可能引发错误,导致SQL Agent作业通过警报系统发送电子邮件,或者只是从列表中删除数据库(通常仅在手动运行sproc时使用)。

The below code was used in a specialized project of mine. 以下代码在我的一个专门项目中使用。 You will need to take the pieces out of it that you want. 您将需要从中取出所需的碎片。

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

I'm assuming you have a list of servers already. 我假设您已经有服务器列表。 loop through the list of servers querying sys.databases. 遍历查询sys.databases的服务器列表。 Use dynamic SQL to generate the linked server query. 使用动态SQL生成链接服务器查询。

You could use SSIS for this. 您可以为此使用SSIS。 The SSIS package could go out to the servers execute the following SQL - SSIS包可能会发送到服务器,执行以下SQL-

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

and do a lookup against your central server that has the list of databases and flag the ones that do not exist in your database and insert them. 并在具有数据库列表的中央服务器上进行查找,并标记数据库中不存在的数据库并插入数据库。

I'd probably go with a PowerShell version. 我可能会使用PowerShell版本。

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

Change the localhost for each server, dump the list into memory and load into SQL for a permanent record. 更改每个服务器的本地主机,将列表转储到内存中并加载到SQL中以获取永久记录。 You could also do a quick compare to a master list. 您还可以与主列表进行快速比较。

Alternatively as you are already using linked servers, query 或者,因为您已经在使用链接服务器,请查询

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

And compare to your master list. 并与您的主列表进行比较。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM