2009-04-19 8 views
5

Je dois changer certaines clés primaires de non-clustered en cluster mais je ne peux pas supprimer la contrainte car elle est référencée par d'autres clés étrangères.SQL 2005 SMO - find referencing table

Comment puis-je trouver les tables qui référencent une clé primaire dans la table parente dans le cadre d'une relation étrangère sans parcourir toutes les tables de la base de données? Je dois désactiver les contraintes sur ceux-ci, changer le PK et le réactiver.

Mise à jour:

  1. Je ne veux pas utiliser SQL simple pour le faire, mais seulement SMO.

  2. Marc, je sais à propos ForeignKeys par je besoin de quelque chose comme: table.PrimaryKey.ForeignKeys (c.-à-tables qui font référence à la clé primaire de ma table) Je veux juste éviter une boucle à travers toutes les tables de la base de données et vérification la propriété ForeignKeys sur chacun d'entre eux pour voir si l'un d'eux la référence de ma table. (non extensible)

Répondre

5

Ok Je pense que je l'ai trouvé.

table.Columns[0].EnumForeignKeys() 

ou directement

table.EnumForeignKeys()

Je me attendais une propriété au lieu d'une fonction. Je suis sûr que dans les coulisses, il fait ce que cmsjr suggéré.

+0

Ma lecture de MSDN est qu'il fait ce que yo voulez (juste après avoir regardé, ayant pas remarqué cet ajout!) – Murph

2

Vous pouvez utiliser les INFORMATION_SCHEMA vues.

INFORMATION_SCHEMA.TABLE_CONSTRAINTS vous donnera les noms des clés primaires de cette table.

SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = @TableName

Étant donné les noms de clé primaire, vous pouvez obtenir les contraintes référentielles qui utilisent ces clés de INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS

Et puis les noms de table en questionnant INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE

Non SMO en tant que telle, mais étant donné la ci-dessus, vous devriez être capable de mettre en place une requête qui liste les contraintes que vous devez désactiver.

4

En utilisant SMO, vous pouvez le faire:

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

Marc

3

Cette requête devrait fonctionner, et pourrait être exécuté en utilisant 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' 

par exemple

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); 
1

Ça ne marche pas pour moi.

Tenir compte les relations suivantes:

Tableau 1 -> table maître; Tableau 2 -> table esclave;

Table2.Table1_ID est une clé étrangère de Table1.ID

Table1.EnumForeignKeys() null retour. Au lieu de cela, j'ai essayé avec succès l'objet DependencyWalker. Le code suivant répertorie toutes les tables qui sont dérivées d'une collection de tables donnée.

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

où "urns" est une collection de table.Urn.

1

Vous devrez parcourir l'arborescence des dépendances. Voici le script qui utilise SMO pour générer le script Créer une table et insérer.

**

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

**