6

我需要将一些主键从非集群更改为集群,但我不能删除约束,因为它是从其他外键引用的。

如何在不遍历数据库中的所有表的情况下找到引用父表中的主键作为外部关系的一部分的表?我需要禁用这些约束,更改 PK 并重新启用。

更新:

  1. 我不想使用纯 SQL 来执行此操作,而仅使用 SMO。

  2. 马克,我知道 ForeignKeys 我需要类似的东西: table.PrimaryKey.ForeignKeys (即哪些表正在引用我的表的主键) 我只是想避免遍历数据库中的所有表并检查每个表的 ForeignKeys 属性其中一个看看是否有任何人引用我的表。(不可扩展)

4

6 回答 6

8

好的,我想我找到了。

table.Columns[0].EnumForeignKeys()

或直接

table.EnumForeignKeys()

我期待一个属性而不是一个函数。我很确定它会在幕后执行 cmsjr 的建议。

于 2009-04-19T18:28:17.923 回答
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);
}

马克

于 2009-04-19T15:44:43.247 回答
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'

例如

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);
于 2009-04-19T15:48:56.637 回答
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 本身,但鉴于上述情况,您应该能够组合一个查询,列出您需要禁用的约束。

于 2009-04-19T15:43:35.433 回答
1

它对我不起作用。

考虑以下关系:

Table1 --> 主表;Table2 --> 从表;

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 的集合。

于 2009-11-15T16:35:15.207 回答
1

您将不得不遍历依赖关系树。以下是使用 SMO 生成创建表和插入脚本的脚本。

**

**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 );
                    }
            }**

**

于 2011-07-20T12:41:17.770 回答