Smo 是一大笑点,不是吗?你会发现依赖遍历器对每个表产生了明显的冗余引用......因为多个关系......和级联关系。
帮自己一个忙,输出依赖walker的树的结果(做你自己的walking)......所以你可以看到这是真的。这就是我所做的只是为了“看看”我得到了什么。请注意,缩进说明表被多次提及...当您调用 WalkDependencies 时,这些表只会被展平为“线性列表”...这对您没有任何好处。
class Program
{
static void Main( string[ ] args )
{
using ( var connection = new SqlConnection( "Data Source=.;Initial Catalog=...;Integrated Security=True" ) )
{
connection.Open( );
var serverConnection = new ServerConnection( connection );
var server = new Server( serverConnection );
var db = server.Databases[ "..." ];
var objects = new UrnCollection( );
foreach ( Table table in db.Tables )
{
objects.Add( table.Urn );
}
var dependency = new DependencyWalker( server );
var tree = dependency.DiscoverDependencies( objects, DependencyType.Parents );
Walk( tree.FirstChild );
}
}
static void Walk( DependencyTreeNode node, int depth = 0 )
{
Print( node.Urn, depth );
if ( node.HasChildNodes )
{
Walk( node.FirstChild, depth + 1 );
}
if ( node.NextSibling != null )
{
Walk( node.NextSibling, depth );
}
}
static void Print( string message, int depth )
{
var space = string.Empty;
for ( int i = 0; i < depth; i++ ) space += " ";
Debug.WriteLine( string.Format( "{0}{1}", space, message ) );
}
}
我在一个小型规范化数据库上运行上述代码,并使用一组名义上的外键。正是这些外键导致了给定表的多次提及。
这是部分编辑的输出:
Server[@Name='...']/Database[@Name='...']/Table[@Name='AddressTypes' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='ApplicationComponents' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/UserDefinedFunction[@Name='GetApplicationElementExtension' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='ApplicationElements' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/UserDefinedFunction[@Name='GetApplicationElementName' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='ApplicationElements' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/UserDefinedFunction[@Name='GetArchitecture' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/UserDefinedFunction[@Name='GetArchitectureName' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/UserDefinedFunction[@Name='GetSetting' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Settings' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='ApplicationElements' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='ApplicationElements' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='DataFiles' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='FileSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='DirectoryEntries' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Lists' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='ListSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Names' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='NameSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='SecurityIds' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='SecuritySequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='DirectoryEntrySequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Images' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Snapshots' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Machines' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='SnapshotSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Progress' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Progress' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='KeyTypes' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='ListItems' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Streams' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='DataFiles' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='FileSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Lists' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='ListSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Lists' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='ListSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='MachineAddresses' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Machines' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='AddressTypes' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='MachineKeys' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Machines' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='MachineKeySequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='KeyTypes' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Machines' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Names' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='NameSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Progress' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='SecurityIds' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='SecuritySequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Settings' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='SnapshotDirectoryEntries' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Snapshots' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Machines' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='SnapshotSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Progress' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='DirectoryEntries' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Lists' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='ListSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Names' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='NameSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='SecurityIds' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='SecuritySequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='DirectoryEntrySequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Snapshots' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Machines' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Architectures' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='SnapshotSequence' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Progress' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='Streams' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Table[@Name='DataFiles' and @Schema='dbo']
Server[@Name='...']/Database[@Name='...']/Sequence[@Name='FileSequence' and @Schema='dbo']
快速扫描发现某些表被引用了六七次。
在好转之前会变得更糟。你最终要做的就是找出独立的东西......可以首先编写脚本的东西。这些东西没有依赖关系。然后,将这些独立的项目放在一个列表中并一遍又一遍地运行依赖项步行器,将内容添加到您的列表中......其中项目仅依赖于您已经添加的项目。因此,您将拥有可编写脚本的订单。
请注意,就地数据库在技术上可能仍然无法以这种方式解决。表 a 可以具有表 b 的引用,而表 b 具有表 a 的引用。这是完全合法的(即使不受欢迎)。
我更喜欢用 Visual Studio 来做艰苦的工作:
- 从here 添加适用于 Visual Studio 的 SQL Server Data Tools
- 创建一个数据库项目。
- 导入现有数据库。
- Build+Publish 菜单生成脚本。
它可以做一些神奇的事情......比如创建对象,然后稍后修改它们以处理 a->b->a 类型的事情。您还可以发布到现有数据库,它会仔细生成仅进行更改的脚本。太棒了。