jdbc: получить имя типа SQL из кода java.sql.Type - PullRequest
26 голосов
/ 22 июня 2011

У меня есть массив с именами полей и кодами типов jdbc. (Те int коды, которые вы можете найти в

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

Я использую драйвер уровня 4.

Я не могу понять, как запросить у драйвера соответствующие имена типов SQL (DDL). Это было бы полезно в jdbc и на родных диалектах.

у меня
(CustomerId, 1) (CustomerName, -8)

и я хочу

(customerId, INT) (идентификатор клиента, VARCHAR (200))

Где я могу найти функции, которые помогут мне с этим? Я использую jdbc в jython через zxJDBC, поэтому я могу использовать все функции API Java 2.0 и Python DB 2.0.

Ответы [ 7 ]

35 голосов
/ 06 марта 2013

Чтобы конкретно ответить «Получить имя типа SQL из кода java.sql.Type», если вы используете версию java, которая может выполнять рефлексию, вот небольшой вспомогательный метод, который в значительной степени делает то же самое:*

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;
}

Добавьте import java.lang.reflect.Field; к своим декларациям на импорт.Если у вас есть это, просто используйте его следующим образом:

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

String typeName = jdbcMappings.get(-5); // now that will return BIGINT
...
25 голосов
/ 25 мая 2015

Java 8 и более поздние версии: JDBCType & SQLType

С улучшениями в API, начиная с Java 8 и JDBC 4.2 , мы имеем JDBCType и SQLType, и в том же духе, что и некоторые другие примеры, можно просто использовать следующим образом:

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

Но, конечно, зачем использовать числовые типы дляначинается с.Создайте привычку и переключитесь с числовых на enum константы, определенные в JDBCType:

String typeName = JDBCType.BIGINT.getName();

et voilà!

Однако этого может быть недостаточно, чтобы получить что-то хорошеедостаточно для использования в DDL ... вам может понадобиться реализовать перевод для конкретного поставщика.Например, вам может потребоваться перевести VARCHAR в VARCHAR2 в случае Oracle.

12 голосов
/ 18 января 2013
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 "?";
}
7 голосов
/ 22 июня 2011

Вам нужен объект ResultSetMetaData вашего текущего ResultSet.Вы можете получить это с getMetaData().Выполните итерацию по столбцам и вызовите каждый столбец метода

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

вашего ResultSetMetaData.

i представляет номер столбца (начиная с 1).

3 голосов
/ 22 июня 2011

Вы, похоже, используете некоторые методы метаданных JDBC, которые вы не опубликовали. Я считаю, что вы видите имя столбца вместе с константой типа JDBC , из которой вы можете получить тип столбца. Взгляните на java.sql API , чтобы узнать больше о том, как получить больше метаданных.

1 голос
/ 26 августа 2015

Библиотека Apache DdlUtils имеет удобный класс для этого: https://db.apache.org/ddlutils/api/org/apache/ddlutils/model/TypeMap.html

String typeName = TypeMap.getJdbcTypeName(typeCode)

Библиотека помогает вам и в других потребностях DDL, но, похоже, не оченьвнимание в последнее время.

1 голос
/ 14 марта 2014

Spring имеет удобный помощник Enum, называемый JdbcTypesEnum, но действительно странно, что это не является частью JDBC.Однако вместо использования

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

я бы использовал

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

при получении типа столбца.Например, при проверке таблицы H2 * со специальным типом VARCHAR_IGNORECASE или UUID:

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

Но обратите внимание, что вы не можете охватить типдиапазон строки для всех баз данных, в этом случае int был бы несколько более удобным (но в конце концов это не закрытый тип Enum).

...