多个SQLServer实例同步脚本到所有数据库中(包括存储过程,试图,触发器,函数,表)

目录

一、自身需求(单个数据库示例)

a、需求说明:

b、核心思路

c、注意事项

二、需求扩展(多个数据库示例)

方案 1:Central Management Server (CMS)

方案 2:PowerShell + SMO (推荐自动化)

1️⃣ 安装 SqlServer 模块(推荐)

2️⃣ 使用旧版 SQLPS 模块(兼容 SQL Server 2012/2014)

3️⃣ 使用 Invoke-Sqlcmd 的替代方法(如果不能安装模块)

方案 3:sqlcmd + 批处理(轻量)

三、完整过程

1. 准备实例列表文件 instances.csv

2. PowerShell 同步脚本

3. 执行方法

4.执行逻辑总结

5.执行优点


一、自身需求(单个数据库示例)

a、需求说明:

 有一个存储过程脚本,需要在一个 SQL Server 实例中的 所有数据库 都创建或更新。

b、核心思路

在 SQL Server 中,可以通过遍历 sys.databases 来实现,核心思路是:

  1. 获取所有数据库列表(排除系统库 master, tempdb, model, msdb)。

  2. 动态拼接 USE + 存储过程脚本

  3. 循环执行

DECLARE @DBName NVARCHAR(128);
DECLARE @SQL NVARCHAR(MAX);

-- 要同步的存储过程脚本
DECLARE @ProcScript NVARCHAR(MAX) = N'
IF OBJECT_ID(''dbo.MyProc'') IS NOT NULL
    DROP PROCEDURE dbo.MyProc;
GO
CREATE PROCEDURE dbo.MyProc
AS
BEGIN
    SELECT DB_NAME() AS CurrentDatabase;
END;
';

-- 游标遍历数据库
DECLARE db_cursor CURSOR FOR
SELECT name 
FROM sys.databases
WHERE database_id > 4  -- 排除系统库
  AND state = 0;       -- 仅在线数据库

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @DBName;

WHILE @@FETCH_STATUS = 0
BEGIN
    -- 拼接动态 SQL:USE 数据库 + 存储过程脚本
    SET @SQL = 'USE [' + @DBName + ']; ' + CHAR(13) + @ProcScript;

    -- 因为 @ProcScript 内可能包含 GO,需要用 sp_executesql 执行一段一段的
    -- 简单方法:去掉 GO (否则 EXEC 不支持)
    SET @SQL = REPLACE(@SQL, 'GO', '');

    PRINT '正在同步到数据库: ' + @DBName;
    EXEC sp_executesql @SQL;

    FETCH NEXT FROM db_cursor INTO @DBName;
END

CLOSE db_cursor;
DEALLOCATE db_cursor;

c、注意事项

  1. GO 不能直接在动态 SQL 中用,所以要么去掉 GO,要么拆分执行。

  2. 如果存储过程逻辑比较复杂,可以把脚本写成一个 .sql 文件,然后在 sqlcmd 或 PowerShell 中循环执行。

  3. 如果你有很多实例(不仅仅是一个实例里的多个库),就需要结合 Central Management Server 或者 PowerShell/Ansible 来批量分发。

二、需求扩展(多个数据库示例)

在多个SQLServer实例的所有数据库中同步(排除系统自带数据库)

对象类型检测 :

P → 存储过程

V → 视图

FN / IF / TF → 标量函数/内联表函数/多语句表函数

TR → 触发器

U →用户表

所以脚本需要:

  1. .sql 文件里解析出 CREATE ... ObjectName

  2. 根据对象类型,拼接对应的 sys.objects 查询(表的话查 sys.tables)。

  3. 如果已存在 → 跳过。

运行逻辑

  1. 遍历实例 → 遍历用户数据库 → 遍历 SQL 文件

  2. 检测 SQL 文件中的 CREATE 语句类型

  3. 根据对象类型在 sys.objects/sys.tables/sys.triggers 查是否存在

    • 已存在 → 跳过并记录日志

    • 不存在 → 执行 SQL 文件

  4. 日志记录实例名、数据库名、文件名、执行结果

推荐有三种方案按需应用:

方案 1:Central Management Server (CMS)

SQL Server 自带的 Central Management Server 功能,可以统一管理多个实例。

  • 把所有目标实例注册到 CMS。

  • 在 CMS 下对“服务器组”右键 → 新建查询,写一份脚本,它会并行执行到所有实例。

  • 脚本内部只需要遍历 sys.databases(排除系统库),创建存储过程即可。

优点:
✅ 原生工具,不需要额外安装。
✅ 一次写脚本,多个实例同时执行。
缺点:
❌ 只能人工执行,自动化程度有限。

 

方案 2:PowerShell + SMO (推荐自动化)

PowerShell 可以批量连接多个实例,遍历所有数据库,然后执行存储过程脚本。

完整示例(你只需要替换实例名和存储过程内容)

# 实例列表(可以写成文件再 Import)
$instances = @(
    "SQLSERVER1",
    "SQLSERVER2\INSTANCE",
    "192.168.1.10"
)

# 存储过程脚本
$procScript = @"
IF OBJECT_ID('dbo.MyProc') IS NOT NULL
    DROP PROCEDURE dbo.MyProc;
CREATE PROCEDURE dbo.MyProc
AS
BEGIN
    SELECT DB_NAME() AS CurrentDatabase, GETDATE() AS ExecTime;
END;
"@

# 引用 SQLServer 模块
Import-Module SqlServer

foreach ($instance in $instances) {
    Write-Host "正在连接实例: $instance" -ForegroundColor Cyan
    
    # 获取实例下所有用户数据库(排除系统库)
    $dbs = Invoke-Sqlcmd -ServerInstance $in
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

战族狼魂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值