jdbc: получить имя типа SQL из кода java.sql.Type

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

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) (customerId, VARCHAR (200))

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

Ответ 1

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

Ответ 2

Чтобы конкретно ответить "Получить имя типа 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
...

Ответ 3

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

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

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

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

String typeName = JDBCType.BIGINT.getName();

и вуаля!

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

Ответ 4

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

Ответ 5

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

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

вашей ResultSetMetaData.

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

Ответ 6

У 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).

Ответ 7

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

String typeName = TypeMap.getJdbcTypeName(typeCode)

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