Як знайти всі таблиці в БД, які не мають явного первинного ключа?


10

Пошуковий пошук у Google набрав мільйони звернень про те, як знайти таблиці без кластеризованого індексу, PK, як правило, є кластерним індексом таблиці. Однак таблиця може легко мати природний ключ як кластерний індекс, так і некластеризований сурогатний індекс, як стовпець ідентичності.

Як знайти всі таблиці в БД без визначеного первинного ключа? У цій БД є 245 таблиць: ручний огляд є надзвичайно неефективним.

Відповіді:


13

Кілька способів усунути цю кішку, але це прекрасно працює в SQL Server 2005 і вище, і я вважаю, що це безболісний спосіб вирішити проблему -

OBJECTPROPERTY()Функція може перерахувати різні властивості про об'єкти - як таблиці. Одне з цих властивостей полягає в тому, чи має таблиця первинний ключ.

OBJECTPROPERTY(object_id, tablehasprimarykey) = 0 - це таблиця без первинного ключа.

Тому

SELECT OBJECT_SCHEMA_NAME( object_id ) as SchemaName, name AS TableName
FROM sys.tables
WHERE OBJECTPROPERTY(object_id,'tablehasprimaryKey') = 0 
ORDER BY SchemaName, TableName ;

Слід дати вам те, що вам потрібно. Ви можете ознайомитись з іншими способами використання функції OBJECTPROPERTY () у книгах в Інтернеті. Це версія статті 2012 року.


добре, що object_id буде працювати. Я думав, що ми використовуємо функцію. але sys.tablesсам дає ідентифікатор і дякує за показ цієї чудової функції.
Biju jose

Нема проблем. Це хороша функція. Багато властивостей. У цьому випадку ви маєте право - sys.tables вже перелічує object_id всередині нього. і це object_id, який ми хочемо передати для параметра ID для функції OBJECTPROPERTY. Дякую за гарний улов зарезервованого ключового слова, яке я там використав :)
Майк Уолш

Ви точно сказали про функцію object_id, я просто перемішав там речі. Добре дякую, що вказали на це. добре, objectproperty()це доступно з 2005 року, я просто перевірив бол, чи не так?
Biju jose

Так. Там у 2005 - 2014 роках і далі :-)
Майк Уолш

Я відредагував сценарій, щоб додати ім'я схеми. Зауважте, що (як OBJECTPROPERTY) функція OBJECT_SCHEMA_NAME () була нова для MSSQL 2005.
Greenstone Walker

5

Рішення Майка відмінно підходить для конкретної проблеми.

Якщо ви хочете більше гнучкості, ось альтернатива , яка може бути легко трансформувалась в запит , який повертає іншу інформацію, наприклад, знайти всі таблиці , які купи, або знайти таблиці , які не мають обмежень унікальності на всіх .

SELECT
    OBJECT_SCHEMA_NAME(t.object_id) AS SchemaName,
    t.name AS TableName
    FROM sys.tables t
    WHERE
        NOT EXISTS
        (
            SELECT *
                FROM sys.indexes i
                WHERE
                    (i.object_id = t.object_id) AND
                    (i.is_primary_key = 1)
        );

Після того, як ваша (під) система перевищить ~ 50 таблиць, дуже важливо ознайомитись з усіма таблицями метаданих, оскільки, як ви вже говорили, переходити через кожну таблицю вручну недоцільно (і схильне до помилок!).


+1 для "тому, що, як ви вже говорили, переходити через кожну таблицю вручну недоцільно (і схильне до помилок!"). Амін там. Дуже схильний до помилок :)
Майк Уолш

4

Функція управління політикою SQL Server може зробити щось із цього.

Фасет таблиці має поля @HasIndex та @HasClusteredIndex (а також інші, які можуть бути корисними, як тригери). Політика може бути створена для перевірки умов у всіх таблицях, у всіх базах даних на ряді серверів (за допомогою функції центрального сервера управління).

Однак він не може перевірити існування індексу або обмеження первинного ключа. Я б поклявся, що там було поле @HasPrimaryKey, але його немає в MSSQL2012. Я або згадую, або божеволію.

Примітка. Управління політикою включено до видань SQL Server 2012 Enterprise, Business Intelligence та Standard. Він недоступний у виданні Express.


2
Я думаю, ви можете написати спеціальну умову, яка перевіряє це. +1 - абсолютно інший спосіб зробити це.
Джон Сейгель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.