web-dev-qa-db-fra.com

jdbc: obtenir le nom du type SQL à partir du code Java.sql.Type

J'ai un tableau avec les noms de champs et les codes de type jdbc. (Ces codes int que vous pouvez trouver dans

http://download.Oracle.com/javase/1.4.2/docs/api/constant-values.html#Java.sql.Types.BIT

J'utilise un pilote de niveau 4.

Je ne peux pas comprendre comment demander au pilote les noms de type SQL (DDL) correspondants. Il serait utile en jdbc et dans les dialectes natifs.

J'ai
(CustomerId, 1) (CustomerName, -8)

et je veux

(customerId, INT) (customerId, VARCHAR (200))

Où puis-je trouver des fonctions qui m'aident à cela? J'utilise jdbc en jython via zxJDBC, donc je peux utiliser toutes les fonctionnalités Java et python DB API 2.0).

31
AndreasT

Vous semblez utiliser certaines méthodes de métadonnées JDBC que vous n'avez pas publiées. Je crois que ce que vous voyez est le nom de la colonne avec le JDBC type constant à partir duquel vous pouvez dériver le type de colonne. Jetez un œil à Java.sql API pour en savoir plus sur la façon d'obtenir plus de métadonnées.

2
joostschouten

Pour répondre spécifiquement "Obtenir le nom du type SQL à partir du code Java.sql.Type", si vous utilisez une version de Java qui peut faire de la réflexion, voici une petite méthode utilitaire qui le fait à peu près la même chose:

public Map<Integer, String> getAllJdbcTypeNames() {

    Map<Integer, String> result = new HashMap<Integer, String>();

    for (Field field : Types.class.getFields()) {
        result.put((Integer)field.get(null), field.getName());
    }

    return result;
}

Ajouter import Java.lang.reflect.Field; à vos déclarations d'importation. Une fois que vous avez cela en place, utilisez-le simplement comme suit:

...
Map<Integer, String> jdbcMappings = getAllJdbcTypeNames();

String typeName = jdbcMappings.get(-5); // now that will return BIGINT
...
35

Java 8 et versions ultérieures: JDBCType & SQLType

Avec des améliorations dans les API, à partir de Java 8 et JDBC 4.2 , nous avons JDBCType et SQLType , et dans le même esprit que certains des autres exemples peuvent être simplement utilisés comme suit:

String typeName = JDBCType.valueOf(-5).getName();

Mais bien sûr, pourquoi utiliser les types numériques pour commencer. Prenez l'habitude et passez du numérique aux constantes enum définies dans JDBCType:

String typeName = JDBCType.BIGINT.getName();

et voilà!

Cependant, cela pourrait ne pas être suffisant pour avoir quelque chose d'assez bon à utiliser dans un DDL ... vous devrez peut-être implémenter une traduction spécifique au fournisseur. Par exemple, vous devrez peut-être envisager de traduire VARCHAR en VARCHAR2 dans le cas d'Oracle.

28
YoYo
public static String getSqlTypeName(int type) {
    switch (type) {
    case Types.BIT:
        return "BIT";
    case Types.TINYINT:
        return "TINYINT";
    case Types.SMALLINT:
        return "SMALLINT";
    case Types.INTEGER:
        return "INTEGER";
    case Types.BIGINT:
        return "BIGINT";
    case Types.FLOAT:
        return "FLOAT";
    case Types.REAL:
        return "REAL";
    case Types.DOUBLE:
        return "DOUBLE";
    case Types.NUMERIC:
        return "NUMERIC";
    case Types.DECIMAL:
        return "DECIMAL";
    case Types.CHAR:
        return "CHAR";
    case Types.VARCHAR:
        return "VARCHAR";
    case Types.LONGVARCHAR:
        return "LONGVARCHAR";
    case Types.DATE:
        return "DATE";
    case Types.TIME:
        return "TIME";
    case Types.TIMESTAMP:
        return "TIMESTAMP";
    case Types.BINARY:
        return "BINARY";
    case Types.VARBINARY:
        return "VARBINARY";
    case Types.LONGVARBINARY:
        return "LONGVARBINARY";
    case Types.NULL:
        return "NULL";
    case Types.OTHER:
        return "OTHER";
    case Types.Java_OBJECT:
        return "Java_OBJECT";
    case Types.DISTINCT:
        return "DISTINCT";
    case Types.STRUCT:
        return "STRUCT";
    case Types.ARRAY:
        return "ARRAY";
    case Types.BLOB:
        return "BLOB";
    case Types.CLOB:
        return "CLOB";
    case Types.REF:
        return "REF";
    case Types.DATALINK:
        return "DATALINK";
    case Types.BOOLEAN:
        return "BOOLEAN";
    case Types.ROWID:
        return "ROWID";
    case Types.NCHAR:
        return "NCHAR";
    case Types.NVARCHAR:
        return "NVARCHAR";
    case Types.LONGNVARCHAR:
        return "LONGNVARCHAR";
    case Types.NCLOB:
        return "NCLOB";
    case Types.SQLXML:
        return "SQLXML";
    }

    return "?";
}
12
Gill

Vous avez besoin de l'objet ResultSetMetaData de votre ResultSet actuel. Vous pouvez l'obtenir avec getMetaData(). Itérer sur les colonnes et appeler pour chaque colonne la méthode

  1. getColumnType(i)
  2. getColumnClassName(i)
  3. getColumnTypeName(i)

de votre ResultSetMetaData.

i représente le numéro de colonne (commençant par 1).

8
alexvetter

Apache DdlUtils Library a une classe de commodité pour cela: https://db.Apache.org/ddlutils/api/org/Apache/ddlutils/model/TypeMap.html

String typeName = TypeMap.getJdbcTypeName(typeCode)

La bibliothèque vous aide également avec d'autres besoins DDL, mais ne semble pas attirer beaucoup d'attention ces derniers temps.

1
konfusius

Spring a une aide pratique Enum appelée JdbcTypesEnum , mais il est en effet assez étrange que cela ne fasse pas partie de JDBC proprement dit. Cependant, au lieu d'utiliser

rs = connection.getMetaData().getColumns();
...
int dataType = rs.getInt("DATA_TYPE");

J'utiliserais

String typeName = rs.getString("TYPE_NAME");

lors de la récupération du type de colonne. Par exemple, lors de l'inspection d'une table base de données H2 avec une table spéciale VARCHAR_IGNORECASE ou UUID tapez:

                    dataType   vs. typeName
UUID:               -2=BINARY  vs. "UUID"
VARCHAR_IGNORECASE: 12=VARCHAR vs. "VARCHAR_IGNORECASE"

Mais notez que vous ne pouvez pas couvrir la plage de types de la chaîne pour toutes les bases de données, dans ce cas, l'int serait un peu plus pratique (mais ce n'est après tout pas un type Enum fermé).

1
eckes