ฉันจะค้นหาตารางทั้งหมดในฐานข้อมูลที่ไม่มีคีย์หลักที่ชัดเจนได้อย่างไร


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 จะทำงานฉันคิดว่าเราใช้ function.but sys.tablesตัวเองให้ id และขอบคุณสำหรับการแสดงฟังก์ชั่นที่ยอดเยี่ยมนี้
Biju jose

ไม่มีปัญหา. มันเป็นฟังก์ชั่นที่ดีที่จะมี คุณสมบัติมากมาย ในกรณีนี้คุณมีสิทธิ์ - sys.tables แสดงรายการ object_id ที่อยู่ภายใน และนั่นคือ object_id ที่เราต้องการส่งผ่านสำหรับพารามิเตอร์ ID ไปยังฟังก์ชัน OBJECTPROPERTY ขอบคุณสำหรับคำที่ถูกสงวนไว้อย่างดีที่ฉันใช้อยู่ที่นั่น :)
Mike Walsh

คุณถูกต้องแม่นยำเกี่ยวกับฟังก์ชั่น object_id ฉันแค่ผสมมันขึ้นมาขอบคุณที่ชี้มันออกมาobjectproperty()ใช้ได้ตั้งแต่ปี 2005 เป็นต้นไปฉันตรวจสอบ bol ใช่ไหม?
Biju jose

ใช่. มีในปี 2005 - 2014 และมากกว่านั้น ณ จุดนี้ :-)
Mike Walsh

ฉันแก้ไขสคริปต์เพื่อเพิ่มชื่อสคีมา โปรดทราบว่า (เช่น OBJECTPROPERTY) ฟังก์ชัน OBJECT_SCHEMA_NAME () เป็นของใหม่สำหรับ MSSQL 2005
Greenstone Walker

5

วิธีการแก้ปัญหาของ Mike นั้นยอดเยี่ยมสำหรับปัญหาเฉพาะ

หากคุณต้องการความยืดหยุ่นมากขึ้นนี่เป็นทางเลือกที่สามารถ morphed ในแบบสอบถามที่ส่งคืนข้อมูลอื่น ๆ ได้อย่างง่ายดายเช่นการค้นหาตารางทั้งหมดที่เป็น heaps หรือการค้นหาตารางที่ไม่มีข้อ จำกัดที่ไม่ซ้ำกันเลย

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 สำหรับ "เพราะอย่างที่คุณพูดการทำแต่ละตารางด้วยตนเองนั้นเป็นไปไม่ได้ (และมีแนวโน้มที่จะเกิดข้อผิดพลาด!") อาเมนที่นั่น เกิดข้อผิดพลาดได้ง่ายมาก :)
Mike Walsh

4

การจัดการนโยบายคุณลักษณะของ SQL Server สามารถทำบางนี้

Table facet มีฟิลด์ @HasIndex และ @HasClusteredIndex (รวมถึงฟิลด์อื่นที่อาจมีประโยชน์เช่นทริกเกอร์) สามารถสร้างนโยบายเพื่อตรวจสอบเงื่อนไขในตารางทั้งหมดในฐานข้อมูลทั้งหมดในเซิร์ฟเวอร์จำนวนหนึ่ง (ใช้คุณสมบัติเซิร์ฟเวอร์การจัดการจากศูนย์กลาง)

อย่างไรก็ตามไม่สามารถตรวจสอบการมีอยู่ของดัชนีคีย์หลักหรือข้อ จำกัด ฉันจะสาบานว่าจะมีฟิลด์ @HasPrimaryKey แต่ไม่มีอยู่ใน MSSQL2012 ฉันอาจจะเข้าใจผิดหรือเป็นบ้า

หมายเหตุ: การจัดการนโยบายรวมอยู่ใน SQL Server 2012 Enterprise, Business Intelligence และ Standard Editions ไม่สามารถใช้งานได้ในรุ่นด่วน


2
ฉันคิดว่าคุณสามารถเขียนเงื่อนไขที่กำหนดเองเพื่อตรวจสอบสิ่งนี้ได้ +1 สำหรับวิธีที่แตกต่างอย่างสิ้นเชิงในการทำสิ่งนี้
Jon Seigel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.