แสดงรายการคีย์หลักสำหรับตารางทั้งหมด - Postgresql


14

มีคำถามที่จะทำเช่นนั้น?

ฉันพบข้อสงสัยบางอย่างที่สามารถทำได้สำหรับหนึ่งตาราง แต่ฉันไม่สามารถแก้ไขได้ดังนั้นฉันจึงเห็น:

tablename | column | type

1
ถ้าฉันถามเรื่องนี้ฉันอยากจะรู้ว่าตำแหน่งอันดับของคอลัมน์ใน PK (PKs บางอันมีมากกว่า 1 คอลัมน์และลำดับอาจมีความสำคัญ)
ypercubeᵀᴹ

คำตอบ:


13

บางสิ่งเช่นนี้

select tc.table_schema, tc.table_name, kc.column_name
from information_schema.table_constraints tc
  join information_schema.key_column_usage kc 
    on kc.table_name = tc.table_name and kc.table_schema = tc.table_schema and kc.constraint_name = tc.constraint_name
where tc.constraint_type = 'PRIMARY KEY'
  and kc.ordinal_position is not null
order by tc.table_schema,
         tc.table_name,
         kc.position_in_unique_constraint;

คำค้นหานี้ไม่เพียงแสดงคีย์หลักเท่านั้น แต่ยังแสดงดัชนีเฉพาะด้วย
Michał Niklas

@ MichałNiklasมันไม่ได้
dezso

1
@DarielPratama: เงื่อนไขtc.constraint_type = 'PRIMARY KEY'จะแสดงคีย์หลักเท่านั้น อย่างไรก็ตามคีย์หลักแต่ละตัวจะได้รับการสำรองข้อมูลโดย indexe ที่ไม่ซ้ำกัน
a_horse_with_no_name

2
@a_horse_with_no_name ฉันเชื่อว่านี่ไม่ถูกต้อง position_in_unique_constraintระบุตำแหน่งสำหรับคีย์ต่างประเทศซึ่งจะเป็นโมฆะสำหรับคีย์หลักเสมอ ordinal_positionคอลัมน์ที่ถูกต้องคือ ทดสอบใน PG 9.4
greatvovan

1
@a_horse_with_no_name ฉันอนุมัติการแก้ไขที่แนะนำโดยผู้ใช้ที่ไม่ระบุชื่อ ไม่แน่ใจว่าการแก้ไขนี้จะผ่านไปหรือไม่ ในกรณีใด ๆ โปรดตรวจสอบข้อเสนอแนะและความคิดเห็นข้างต้นโดย greatvovan ฉันคิดว่ามันถูกต้องและordinal_positionควรจะใช้ position_in_unique_constraintคือไม่เป็นโมฆะเฉพาะในการใช้งาน FKs
ypercubeᵀᴹ

20

นี่คือคำตอบที่แม่นยำยิ่งขึ้น:

select tc.table_schema, tc.table_name, kc.column_name 
from  
    information_schema.table_constraints tc,  
    information_schema.key_column_usage kc  
where 
    tc.constraint_type = 'PRIMARY KEY' 
    and kc.table_name = tc.table_name and kc.table_schema = tc.table_schema
    and kc.constraint_name = tc.constraint_name
order by 1, 2;

คุณพลาดand kc.constraint_name = tc.constraint_nameส่วนหนึ่งดังนั้นจึงแสดงรายการข้อ จำกัด ทั้งหมด


2
ในขณะที่การสืบค้นของคุณใช้งานได้ความแตกต่างที่สำคัญกว่าคือand kc.position_in_unique_constraint is not nullส่วนที่ขาดหายไป และคุณควรใช้ ANSI JOIN อย่างยิ่ง (ในขณะที่หลายคนคิดว่ามันเป็นเรื่องของรสนิยม)
dezso

1

โปรดพิจารณาสิ่งนี้ด้วย สิ่งนี้จะสร้างสคริปต์เพื่อแก้ไขตารางทั้งหมด

SELECT STRING_AGG(FORMAT('ALTER TABLE %s CLUSTER ON %s;', A.table_name, A.constraint_name), E'\n') AS SCRIPT
FROM
(
    SELECT      FORMAT('%s.%s', table_schema, table_name) AS table_name, constraint_name
    FROM        information_schema.table_constraints
    WHERE       UPPER(constraint_type) = 'PRIMARY KEY'
    ORDER BY    table_name 
) AS A;

คำถามไม่ได้ถามถึงวิธีการปรับเปลี่ยนตาราง
ypercubeᵀᴹ

1
ฉันสองสิ่งที่ @ ypercubeᵀᴹsays ลบคำตอบนี้ แต่อย่าท้อแท้ - ไปทัวร์เยี่ยมชมศูนย์ช่วยเหลือและอ่านบล็อก "ช่วยให้เราช่วยคุณได้" สำหรับการตอบบางสิ่งที่ไม่ได้ถามเราได้ทำทุกครั้ง :-) ps ยินดีต้อนรับสู่ฟอรัม!
Vérace

1

ฉันคิดว่าจะได้รับคีย์หลักและคีย์ต่างประเทศควรทำเช่นนี้ kc.position_in_unique_constraint ไม่ใช่โมฆะเงื่อนไขนี้อาจได้รับกุญแจต่างประเทศเท่านั้น

select tc.table_schema, tc.table_name, kc.column_name,tc.constraint_type
from 
    information_schema.table_constraints tc
    JOIN information_schema.key_column_usage kc 
        on kc.table_name = tc.table_name and kc.table_schema = tc.table_schema 
                and kc.constraint_name = tc.constraint_name
where 
--kc.position_in_unique_constraint is not null
order by tc.table_schema,
         tc.table_name,
         kc.position_in_unique_constraint;

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