SQL 2005 SMO - найти таблицу ссылок

Мне нужно изменить некоторые первичные ключи с некластеризованных на кластеризованные, но я не могу удалить ограничение, потому что на него ссылаются другие внешние ключи.

Как я могу найти таблицы, которые ссылаются на первичный ключ в родительской таблице как часть внешнего отношения, не перебирая все таблицы в БД? Мне нужно отключить ограничения на них, изменить ПК и снова включить.

Обновлять:

  1. Я не хочу использовать для этого простой SQL, а только SMO.

  2. Марк, я знаю о ForeignKeys, мне нужно что-то вроде: table.PrimaryKey.ForeignKeys (т.е. какие таблицы ссылаются на первичный ключ моей таблицы). Я просто хочу избежать циклического просмотра всех таблиц в базе данных и проверять свойство ForeignKeys на каждом один из них, чтобы узнать, ссылаются ли какие-либо из них на мою таблицу (не масштабируется)


person Cosmin Onea    schedule 19.04.2009    source источник


Ответы (6)


Хорошо, я думаю, что нашел это.

table.Columns[0].EnumForeignKeys()

или напрямую

таблица.EnumForeignKeys()

Я ожидал свойства вместо функции. Я почти уверен, что за кулисами он делает то, что предложил cmsjr.

person Cosmin Onea    schedule 19.04.2009
comment
Мое прочтение MSDN заключается в том, что он делает то, что вы хотите (только что посмотрел, не заметив этого дополнения!) - person Murph; 20.04.2009

Используя 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);
}

Марк

person marc_s    schedule 19.04.2009

Этот запрос должен работать и может быть выполнен с использованием 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);
person cmsjr    schedule 19.04.2009

Вы можете использовать INFORMATION_SCHEMA Views.

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 как таковой, но, учитывая вышесказанное, вы сможете составить запрос, в котором будут перечислены ограничения, которые необходимо отключить.

person Murph    schedule 19.04.2009

Это не работает для меня.

Рассмотрим следующие отношения:

Таблица1 --> главная таблица; Таблица2 --> подчиненная таблица;

Table2.Table1_ID является внешним ключом Table1.ID

Table1.EnumForeignKeys() возвращает ноль.

Вместо этого я успешно попробовал объект 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.

person franz976    schedule 15.11.2009

Вам придется путешествовать по дереву зависимостей. Ниже приведен сценарий, который использует 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 );
                    }
            }**

**

person Siddharth    schedule 20.07.2011