sql >> Databáze >  >> RDS >> PostgreSQL

Jak zjistit, zda pro dané sloupce existuje omezení jedinečného klíče

Můžete se dotazovat na systémové katalogy pro jedinečná omezení , konkrétně pg_constraint a 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 identifikátoru objektu regclass pomáhá jednoznačně identifikovat vaši tabulku.

  • Informační funkce systémového katalogu pg_get_constraintdef() vám poskytne pěkně formátované informace, které nejsou nezbytně nutné pro váš požadavek.

  • Také pomocí operátorů pole <@ a @> abyste se ujistili, že se pole zcela shodují. (Pořadí sloupců není známo.) Systémové sloupce jsou smallint a smallint[] respektive. Přenášet na integer aby to s těmi operátory fungovalo.

  • V názvech sloupců se rozlišují velká a malá písmena při jejich přímém vyhledávání v systémovém katalogu. Pokud jste C1 neuvedli do dvojitých uvozovek a C2 při vytváření musíte použít c1 a c2 v tomto kontextu.

  • Může také existovat vícesloupcové omezení primárního klíče prosazení jedinečnosti. Chcete-li to pokrýt v dotazu, použijte místo toho:

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

V návaznosti na housle @Roman, tento také demonstruje případ pk:

->SQLfiddle

Unikátní index

Obě výše uvedená omezení (unikátní &pk omezení) jsou implementována prostřednictvím jedinečného indexu. Kromě toho mohou existovat také unikátní indexy dělat efektivně totéž, co formálně deklarované jedinečné omezení. Chcete-li chytit všechny dotaz na systémový katalog pg_index místo toho podobným způsobem:

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;

Zvláštní obtíž je zde vnitřní typ int2vector . Řeším to přetypováním textu a převodem na int[] .

Uvědomte si, že implementace katalogových tabulek se může v hlavních oblastech změnit. Je nepravděpodobné, že tyto dotazy přestanou fungovat, ale je to možné.



  1. Použití rámce entity s MySQL DB a návrhářem modelu nesbírá uložené parametry procesu

  2. Postgres - Funkce pro návrat průsečíku 2 POLE?

  3. Proč moje databáze Postgres nějakou dobu funguje a potom po restartu nelze spustit server?

  4. Je možné použít IF(cond1 AND cond2,result,otherse result) v MySQL?