PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak sprawdzić, czy istnieje unikalne ograniczenie klucza dla danych kolumn?

Możesz wysłać zapytanie do katalogów systemowych dla unikalnych ograniczeń , w szczególności pg_constraint i pg_attribute :

SELECT c.conname, pg_get_constraintdef(c.oid)
FROM   pg_constraint c
JOIN  (
   SELECT array_agg(attnum::int) AS attkey
   FROM   pg_attribute
   WHERE  attrelid = 'tb'::regclass  -- table name optionally schema-qualified
   AND    attname  = ANY('{c1,c2}') 
   ) a ON c.conkey::int[] <@ a.attkey AND c.conkey::int[] @> a.attkey
WHERE  c.contype  = 'u'
AND    c.conrelid = 'tb'::regclass;
  • typ identyfikatora obiektu regclass pomaga jednoznacznie zidentyfikować Twój stół.

  • Funkcja informacji o katalogu systemowym pg_get_constraintdef() dostarcza ładnie sformatowanych informacji, które nie są bezwzględnie konieczne dla Twojego żądania.

  • Również przy użyciu operatorów tablicowych <@ i @> aby upewnić się, że tablice są całkowicie dopasowane. (Kolejność kolumn jest nieznana.) Kolumny systemowe są smallint i smallint[] odpowiednio. Przesyłaj do liczby całkowitej aby działało z tymi operatorami.

  • W nazwach kolumn rozróżniana jest wielkość liter podczas bezpośredniego wyszukiwania ich w katalogu systemowym. Jeśli nie umieściłeś podwójnego cudzysłowu C1 i C2 w czasie tworzenia musisz użyć c1 i c2 w tym kontekście.

  • Może również istnieć wielokolumnowe ograniczenie klucza podstawowego egzekwowanie wyjątkowości. Aby uwzględnić to w zapytaniu, użyj zamiast tego:

    WHERE  c.contype IN ('u', 'p')
    

Opierając się na skrzypcach @Roman, ten pokazuje również przypadek pk:

->SQLfiddle

Unikalny indeks

Oba powyższe (ograniczenia unikalne i pk) są implementowane za pomocą unikalnego indeksu. Ponadto mogą istnieć również unikalne indeksy robiąc skutecznie to samo, co formalnie zadeklarowane ograniczenie unikatowe. Aby złapać wszystkie przeszukaj katalog systemowy pg_index zamiast tego w podobny sposób:

SELECT c.relname AS idx_name
FROM  (
   SELECT indexrelid, string_to_array(indkey::text, ' ')::int[] AS indkey
   FROM   pg_index
   WHERE  indrelid = 'tb'::regclass
   AND    indisunique                    -- contains "indisprimary"
   ) i
JOIN  (
   SELECT array_agg(attnum::int) AS attkey
   FROM   pg_attribute
   WHERE  attrelid = 'tb'::regclass
   AND    attname  = ANY('{c1,c2}')
   ) a ON i.indkey <@ a.attkey AND i.indkey @> a.attkey
JOIN   pg_class c ON c.oid = i.indexrelid;

Szczególną trudnością jest tutaj typ wewnętrzny int2vector . Zajmuję się tym, przesyłając tekst i konwertując do int[] .

Należy pamiętać, że implementacja tabel katalogu może ulec zmianie w zależności od głównych. Jest mało prawdopodobne, że te zapytania się zepsują, ale możliwe.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jaki jest odpowiednik encode(<nazwa_kolumny>, 'escape') PostgreSQL w javie?

  2. Zastosuj procedurę pojedynczego wyzwalania do wielu różnych stołów

  3. Aktualizacja Postgresql z dołącz

  4. Błąd intarray Postgresql:niezdefiniowany symbol:pfree

  5. Pobierz rekordy, które są niezerowe po przecinku w PostgreSQL