SQL 2005 SMO - найти таблицу ссылок - PullRequest
5 голосов
/ 19 апреля 2009

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

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

Обновление:

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

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

Ответы [ 6 ]

5 голосов
/ 19 апреля 2009

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

table.Columns[0].EnumForeignKeys()

или напрямую

table.EnumForeignKeys ()

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

4 голосов
/ 19 апреля 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);
}

Марк

3 голосов
/ 19 апреля 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'

, например

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);
2 голосов
/ 19 апреля 2009

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

1 голос
/ 20 июля 2011

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

**

1 голос
/ 15 ноября 2009

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

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

Table1 -> главная таблица; Table2 -> ведомый стол;

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" - это набор таблиц. Урна.

...