我需要将一些主键从非群集更改为群集但我不能删除约束,因为它是从其他外键引用的。
如何在不绕过数据库中所有表的情况下找到引用父表中主键的表作为外部关系的一部分?我需要禁用那些约束,更改PK并重新启用。
更新
我不想使用纯SQL来执行此操作,只能使用SMO。
Marc,我知道关于ForeignKeys,我需要这样的东西: table.PrimaryKey.ForeignKeys(即哪些表引用了我的表的主键) 我只是想避免遍历数据库中的所有表,并检查每个表上的ForeignKeys属性,看看它们中是否有任何一个引用了我的表。(不可扩展)
答案 0 :(得分:5)
好的,我想我找到了它。
table.Columns[0].EnumForeignKeys()
或直接
table.EnumForeignKeys()
我期待一个属性而不是一个函数。我非常肯定它在幕后做了cmsjr的建议。
答案 1 :(得分:4)
使用SMO,您可以这样做:
using Microsoft.SqlServer.Management.Smo;
Server localServer = new Server("your server name");
Database dasecoDB = localServer.Databases["your database name"];
Table table = dasecoDB.Tables["your table name"];
foreach(ForeignKey fk in table.ForeignKeys)
{
Console.WriteLine("Foreign key {0} references table {1} and key {2}", fk.Name, fk.ReferencedTable, fk.ReferencedKey);
}
马克
答案 2 :(得分:3)
此查询应该有效,并且可以使用Database.ExecuteWithResults
执行Select fk.Table_Name from
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN
INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK
ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN
INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK
ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
where PK.Table_Name = 'SomeTable'
e.g。
SqlConnection sqlConnection =
new SqlConnection(@"Integrated Security=SSPI; Data Source=SomeInstance");
Server server = new Server(serverConnection);
Database db = server.Databases["somedatabase"];
DataSet ds = db.ExecuteWithResults(thesqlabove);
答案 3 :(得分:2)
您可以使用INFORMATION_SCHEMA
观看次数。
INFORMATION_SCHEMA.TABLE_CONSTRAINTS
将为您提供该表上主键的名称。
SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = @TableName
给定主键名称,您可以获得使用INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
然后通过查询INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE
不是SMO,但鉴于上述情况,您应该能够将查询列出需要禁用的约束。
答案 4 :(得分:1)
这对我不起作用。
考虑以下关系:
表1 - >主表; 表2 - >奴隶表;
Table2.Table1_ID是Table1.ID
的外键Table1.EnumForeignKeys()返回null。
相反,我成功尝试了DependencyWalker对象。以下代码列出了从给定表集合中删除的所有表。
DependencyWalker w = new DependencyWalker(db.Parent);
DependencyTree tree = w.DiscoverDependencies(urns,false);
DependencyCollection depends = w.WalkDependencies(tree);
foreach (DependencyCollectionNode dcn in depends)
{
if (dcn.Urn.Type == "Table")
{
dcn.Urn.GetNameForType("Table");
Console.WriteLine(dcn.Urn.GetNameForType("Table"));
}
}
其中“urns”是table.Urn。
的集合答案 5 :(得分:1)
您必须通过依赖树。 以下是使用SMO生成Create表和插入脚本的脚本。
**
**ServerConnection conn = new ServerConnection( GetConnection() );
Server server = new Server( conn );
Database db = server.Databases[ mDestinationDatabase ];
// Create database script
StringBuilder dbScript = new StringBuilder();
ScriptingOptions dbCreateOptions = new ScriptingOptions();
dbCreateOptions.DriAll = true;
dbCreateOptions.NoCollation = true;
StringCollection coll = db.Script( dbCreateOptions );
foreach( string str in coll )
{
dbScript.Append( str );
dbScript.Append( Environment.NewLine );
}
sqlInsertCommands = dbScript.ToString();
// Create dependency tree
DependencyWalker w = new DependencyWalker(db.Parent);
UrnCollection urnCollection = new UrnCollection();
DataTable table = db.EnumObjects( DatabaseObjectTypes.Table );
string tableName = string.Empty;
foreach( DataRow row in table.Rows )
{
urnCollection.Add( new Urn( ( string )row[ "Urn" ] ) );
}
DependencyTree tree = w.DiscoverDependencies( urnCollection, true );
DependencyCollection depends = w.WalkDependencies(tree);
// walk through the dependency tree and for each table generate create and insert scripts
foreach (DependencyCollectionNode dcn in depends)
{
if (dcn.Urn.Type == "Table")
{
tableName = dcn.Urn.GetNameForType( "Table" );
DataTable dataTableWithData = GetTableWithData( tableName);
ArrayList columnList = new ArrayList();
foreach(DataColumn dataColumn in dataTableWithData.Columns)
{
columnList.Add( dataColumn.ColumnName );
}
sqlInsertCommands = sqlInsertCommands + Environment.NewLine + Environment.NewLine
+ GetCreateTableScript(tableName )
+ Environment.NewLine + Environment.NewLine
+ BuildInsertSQL( columnList, dataTableWithData, tableName );
}
}**
**