目录
方案 1:Central Management Server (CMS)
2️⃣ 使用旧版 SQLPS 模块(兼容 SQL Server 2012/2014)
3️⃣ 使用 Invoke-Sqlcmd 的替代方法(如果不能安装模块)
一、自身需求(单个数据库示例)
a、需求说明:
有一个存储过程脚本,需要在一个 SQL Server 实例中的 所有数据库 都创建或更新。
b、核心思路
在 SQL Server 中,可以通过遍历 sys.databases 来实现,核心思路是:
-
获取所有数据库列表(排除系统库
master,tempdb,model,msdb)。 -
动态拼接 USE + 存储过程脚本。
-
循环执行。
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、注意事项
-
GO 不能直接在动态 SQL 中用,所以要么去掉 GO,要么拆分执行。
-
如果存储过程逻辑比较复杂,可以把脚本写成一个
.sql文件,然后在sqlcmd或 PowerShell 中循环执行。 -
如果你有很多实例(不仅仅是一个实例里的多个库),就需要结合 Central Management Server 或者 PowerShell/Ansible 来批量分发。
二、需求扩展(多个数据库示例)
在多个SQLServer实例的所有数据库中同步(排除系统自带数据库)
对象类型检测 :
P → 存储过程
V → 视图
FN / IF / TF → 标量函数/内联表函数/多语句表函数
TR → 触发器
U →用户表
所以脚本需要:
-
从
.sql文件里解析出CREATE ... ObjectName -
根据对象类型,拼接对应的
sys.objects查询(表的话查sys.tables)。 -
如果已存在 → 跳过。
运行逻辑
-
遍历实例 → 遍历用户数据库 → 遍历 SQL 文件
-
检测 SQL 文件中的
CREATE语句类型 -
根据对象类型在
sys.objects/sys.tables/sys.triggers查是否存在-
已存在 → 跳过并记录日志
-
不存在 → 执行 SQL 文件
-
-
日志记录实例名、数据库名、文件名、执行结果
推荐有三种方案按需应用:
方案 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

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



