Làm cách nào để tìm tất cả các bảng trong DB không có khóa chính rõ ràng?


10

Một tìm kiếm của Google đã tạo ra hàng triệu lượt truy cập về cách tìm các bảng mà không được lập chỉ mục theo cụm, PK thường là chỉ mục được nhóm của một bảng. Tuy nhiên, một bảng có thể dễ dàng có một khóa tự nhiên là một chỉ mục được nhóm và một chỉ mục thay thế không được phân cụm, như một cột định danh.

Làm cách nào để tìm tất cả các bảng trong DB mà không có khóa chính được xác định? Tôi có 245 bảng trong DB này: kiểm tra thủ công là không hiệu quả.

Câu trả lời:


13

Vài cách để lột da con mèo này nhưng nó hoạt động tốt trong SQL Server 2005 trở lên và tôi thấy đó là cách không đau để xử lý vấn đề -

Các OBJECTPROPERTY()chức năng có thể liệt kê các thuộc tính khác nhau về đối tượng - như bàn. Một trong những thuộc tính đó là liệu bảng có khóa chính hay không.

OBJECTPROPERTY(object_id, tablehasprimarykey) = 0 sẽ là bảng không có khóa chính.

Vì thế

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

Nên cung cấp cho bạn những gì bạn cần. Bạn có thể thấy tất cả về các cách khác để sử dụng hàm OBRIPROPERTY () trong sách trực tuyến. Đây là phiên bản 2012 của bài viết.


Đối tượng này sẽ hoạt động tốt. Tôi nghĩ chúng ta đang sử dụng hàm. Nhưng sys.tableschính nó cung cấp cho id và cảm ơn vì đã hiển thị chức năng tuyệt vời này.
Biju jose

Không vấn đề gì. Đó là một chức năng tốt để có. Rất nhiều tài sản. Trong trường hợp này, bạn có quyền - sys.tables đã liệt kê object_id bên trong nó. và đó là object_id mà chúng ta muốn truyền tham số ID cho hàm OBRIPROPERTY. Cảm ơn bạn đã nắm bắt tốt từ khóa dành riêng mà tôi đã sử dụng ở đó :)
Mike Walsh

, bạn đã chính xác về hàm object_id, tôi chỉ trộn mọi thứ lên đó. Cảm ơn vì đã chỉ ra nó. Ở objectproperty()đây có sẵn từ năm 2005 trở đi, tôi chỉ kiểm tra bol, phải không?
Biju jose

Đúng. Có vào năm 2005 - 2014 và hơn thế nữa tại thời điểm này :-)
Mike Walsh

Tôi đã chỉnh sửa tập lệnh để thêm Tên Schema. Lưu ý rằng (như OBRIPROPERTY) chức năng OBJECT_SCHema_NAME () là mới đối với MSSQL 2005.
Greenstone Walker

5

Giải pháp của Mike là tuyệt vời cho vấn đề cụ thể.

Nếu bạn muốn linh hoạt hơn, đây là một sự thay thế có thể dễ dàng biến thành một truy vấn mà trở về các thông tin khác, chẳng hạn như việc tìm kiếm tất cả các bảng có đống, hoặc tìm bảng mà không có ràng buộc duy nhất ở tất cả .

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

Khi hệ thống (phụ) của bạn vượt quá ~ 50 bảng, việc làm quen với tất cả các bảng siêu dữ liệu là rất quan trọng, vì như bạn đã nói, việc đi qua từng bảng theo cách thủ công là không thực tế (và dễ bị lỗi!).


+1 cho "bởi vì như bạn đã nói, việc đi qua từng bảng theo cách thủ công là không thực tế (và dễ bị lỗi!)." Amen đấy. Rất dễ bị lỗi :)
Mike Walsh

4

Các Policy Management tính năng của SQL Server có thể làm một số điều này.

Khía cạnh Bảng có các trường @HasIndex và @HasClusteredIndex (cũng như các trường khác có thể hữu ích, như kích hoạt). Một chính sách có thể được tạo để kiểm tra các điều kiện trên tất cả các bảng, trong tất cả các cơ sở dữ liệu, trong một số máy chủ (sử dụng tính năng Máy chủ quản lý trung tâm).

Tuy nhiên, không thể kiểm tra sự tồn tại của một chỉ số hoặc ràng buộc khóa chính. Tôi đã thề rằng có một lĩnh vực @HasPrimaryKey nhưng nó không có trong MSSQL2012. Tôi đang thất vọng hoặc phát điên.

Lưu ý: Quản lý chính sách được bao gồm trong phiên bản SQL Server 2012 Enterprise, Business Intelligence và Standard. Nó không có sẵn trong phiên bản Express.


2
Tôi nghĩ rằng bạn có thể viết một điều kiện tùy chỉnh để kiểm tra điều này. +1 cho một cách hoàn toàn khác để làm điều này.
Jon Seigel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.