C# 如何从多个服务器/数据库中查找相同、修改过且唯一的SQL对象?
问题摘要: 我们在多个服务器上有一组数据库,它们“应该”都具有相同的SQL对象。多年来,我们的开发人员在各种数据库中添加/修改了对象,使它们不再匹配。我需要从多个服务器上完全相同的多个数据库中获取所有SQL对象(表、视图、存储过程、用户定义函数)的列表。(稍后获取唯一项目列表,稍后获取修改项目列表)。我目前的解决方案有效,但速度相当慢。我想知道是否有更好的替代方案,但我找不到 当前解决方案: 目前,我一直在使用C#中的SMO获取所有对象的URN并编写脚本。当我试图一次编写一个对象的脚本时,过程很慢(对服务器的大量调用)。如果我尝试通过将它们的URN打包到一个数组中来编写脚本,过程会更快,但我只得到结果脚本的可枚举或StringCollection,而没有组织脚本来自哪个对象等。有什么更好的方法来实现这一点(我知道现有的工具,如ApexSQL或RedGate,它们目前是不可能的)。我目前的解决方案是按名称对它们进行分组(并按服务器划分),然后在那些较小的按名称批中编写脚本 请原谅我目前的代码,我一直在各地尝试不同的方法。也许有一种解决方案甚至不需要分析代码。需要注意两件事:C# 如何从多个服务器/数据库中查找相同、修改过且唯一的SQL对象?,c#,sql,sql-server,smo,ssms-2017,C#,Sql,Sql Server,Smo,Ssms 2017,问题摘要: 我们在多个服务器上有一组数据库,它们“应该”都具有相同的SQL对象。多年来,我们的开发人员在各种数据库中添加/修改了对象,使它们不再匹配。我需要从多个服务器上完全相同的多个数据库中获取所有SQL对象(表、视图、存储过程、用户定义函数)的列表。(稍后获取唯一项目列表,稍后获取修改项目列表)。我目前的解决方案有效,但速度相当慢。我想知道是否有更好的替代方案,但我找不到 当前解决方案: 目前,我一直在使用C#中的SMO获取所有对象的URN并编写脚本。当我试图一次编写一个对象的脚本时,过程很
//创建数据表
var表=新数据表(“相等对象”);
表.列.添加(“名称”);
表.列.添加(“类型”);
//创建数据行
int dbCount=items.SqlObjects.GroupBy(obj=>obj.Database.Count();
DMP DMP=DiffMatchPatchModule.Default;
var rows=新列表();
foreach(items.SqlObjects.GroupBy(obj=>obj.Name)中的igroupingnamegroup)
{
var likamedobjs=nameGroup.ToList();
if(likamedobjs.Count!=dbCount)
{
continue;//对象不在所有数据库中
}
//脚本对象
var rawScripts=新列表();
bool scriptingSucceeded=true;
foreach(nameGroup.GroupBy(obj=>obj.Server)中的igroupingservergroup)
{
Server=serverGroup.Key;
Urn[]urns=serverGroup.Select(obj=>obj.Urn.ToArray();
var scripter=新脚本编写器(服务器)
{
选项=项。脚本选项
};
i数不清的结果;
尝试
{
结果=scripter.EnumScript(urns);
}
捕获(失败操作异常)
{
scriptingSucceeded=false;
break;//对象可能已加密
}
rawScripts.AddRange(结果);
}
如果(!scriptingsucceed)
{
继续;
}
如果(rawScripts.Count%nameGroup.Count()!=0)
{
继续;
}
var allScripts=new List();
int stringsPerScript=rawScripts.Count/nameGroup.Count();
对于(inti=0;idiff.Operation.IsEqual))
{
allEqual=假;
break;//脚本不相等
}
}
//如果所有脚本都相等,则为对象创建数据行
如果(allEqual)
{
DataRow行=table.NewRow();
行[“名称”]=LIKEAMEDOBJS[0]。名称;
行[“类型”]=LikeAmedobjs[0]。类型;
行。添加(行);
}
}
//将数据行添加到数据表
foreach(rows.OrderBy中的DataRow行(r=>r[“Type”])。然后是by(r=>r[“Name”]))
{
table.Rows.Add(行);
}
//将数据表写入csv
var builder=新的StringBuilder();
AppendLine(string.Join(“,”,table.Columns.Cast().Select(col=>col.ColumnName));
foreach(table.Rows中的DataRow行)
{
AppendLine(string.Join(“,”,row.ItemArray.Select(field=>field.ToString());
}
writealText(“equalObjects.csv”,builder.ToString());
代码运行正常。我可以得到预期的csv文件(名称|类型)在多个服务器上的所有数据库中,所有对象都完全相同。速度太慢了。我的方法正确吗?有更好/更现代的解决方案吗?所有数据库中都有表具有对象。在sqlserver中,它是sysobj。首先需要创建一个主列表。您可以从.all d合并此视图然后将其连接到每个db sysobj