2009-11-04 4 views
8

Sto cercando di trovare i vincoli univoci di una tabella utilizzando Java (su un database Oracle, ma ciò non dovrebbe fare alcuna differenza).Trova un vincolo univoco nella tabella database

Ho trovato un modo per scoprire le chiavi primarie di una tabella, grazie a getPrimaryKeys di DatabaseMetaData (....); Tuttavia non sono stato in grado di trovare le uniche sezioni delle tabelle e Internet non è stato in grado di aiutarmi, quindi sto finendo qui ponendo la mia domanda :)

C'è un modo pulito per trovare i vincoli univoci (o, piuttosto, il nome delle colonne che devono essere univoche per un tavolo .. Beh, capisci? hehe) di un tavolo? i migliori saluti,

Nils

+0

Quindi ho capito che preferiresti non avere una soluzione specifica per Oracle? – DCookie

risposta

20

è possibile interrogare il dizionario dati:

SQL> SELECT cc.* 
    2 FROM all_constraints c 
    3 JOIN all_cons_columns cc ON (c.owner = cc.owner 
    4        AND c.constraint_name = cc.constraint_name) 
    5 WHERE c.constraint_type = 'U' 
    6  AND c.table_name = 'T'; 

OWNER  CONSTRAINT_NAME TABLE_NAME  COLUMN_NAME  POSITION 
---------- ----------------- -------------- ------------- ---------- 
VNZ  UNIQUE_COL  T    COLUMN1    1 
VNZ  UNIQUE_COL  T    COLUMN2    2 
VNZ  UNIQUE_COL2  T    COLUMN2    1 
+1

Grazie Vincent, questo è ESATTAMENTE quello che stavo cercando !! Grazie mille ! – Nils

0

Se Oracle crea indici per vincoli univoci (non so se lo fa, è necessario controllare) rispetto è possibile conoscere i propri vincoli tramite getIndexInfo()

+0

Sì, Oracle crea un indice univoco su qualsiasi colonna identificata in un vincolo UNIQUE: è così che applica l'unicità. – DCookie

+0

Tuttavia, gli indici univoci possono essere completamente centrati su Oracle. Se è necessaria una soluzione generica, questo potrebbe non essere vero in tutti i casi. – DCookie

+0

E, penso che Oracle possa utilizzare anche un indice non univoco per imporre un vincolo univoco. – erikkallen

0

I vincoli univoci sono generalmente applicati da un indice. È possibile utilizzare DatabaseMetaData.getIndexInfo() per trovare gli indici in cui il non univoco è falso?

0

Poiché la maggior parte dei database memorizza questi vincoli come indice, è possibile utilizzare DatabaseMetaData.getIndexInfo() come indicato in precedenza. Ciò ha funzionato bene per me quando si utilizza Postgresql.

E 'solo importante chiamare getIndexInfo() con il 4 ° parametro come true come il documenation dice:

unique - quando vero, restituirà solo gli indici per i valori univoci; quando falso, indici di ritorno, indipendentemente dal fatto unico o no

Con il seguente codice:

// Class to combine all columns for the same index into one object 
public static class UniqueConstraint { 
    public String table; 
    public String name; 
    public List<String> columns = new ArrayList<>(); 
    public String toString() { 
     return String.format("[%s] %s: %s", table, name, columns); 
    } 
} 

public static List<UniqueConstraint> getUniqueConstraints(Connection conn, String schema, String table) throws SQLException { 
    Map<String, UniqueConstraint> constraints = new HashMap<>(); 

    DatabaseMetaData dm = conn.getMetaData(); 
    ResultSet rs = dm.getIndexInfo(null, schema, table, true, true); 
    while(rs.next()) { 
     String indexName = rs.getString("index_name"); 
     String columnName = rs.getString("column_name"); 

     UniqueConstraint constraint = new UniqueConstraint(); 
     constraint.table = table; 
     constraint.name = indexName; 
     constraint.columns.add(columnName); 

     constraints.compute(indexName, (key, value) -> { 
      if (value == null) { return constraint; } 
      value.columns.add(columnName); 
      return value; 
     }); 
    } 

    return new ArrayList<>(constraints.values()); 
} 

è possibile chiamare:

getUniqueConstraints(conn, "public", tableName); 

e tornare un elenco di tutti i unico vincoli per una data tabella. I vincoli sono raggruppati per indice poiché un indice può coprire più colonne se sono uniche in combinazione.