GetColumName(i) возвращает значение при использовании UNION (Jaybird)

Я немного запутался с моим новым SQL-запросом, использующим объединение.

Я запрашиваю свою базу данных firebird в java-приложении, используя jaybird 2.2.8. Обычно я анализирую свой ResultSet, используя метаданные

ResultSetMetaData metaData = resultSet.getMetaData();

и цикл по столбцам

for (int i = 1; i <= metaData.getColumnCount(); i++) {
            columnName = metaData.getColumnName(i);
            int columnType = metaData.getColumnType(i);
            switch (columnType) { ...

Это работало довольно хорошо, пока я не начал использовать Union в своем SQL-запросе. Теперь метод

metaData.getColumnName(i)

возвращает пустую строку вместо имени столбца — тип столбца допустим.

Когда я использую SQL-запрос без Union, все работает так, как ожидалось, и когда я тестирую свой запрос в IBExpert, все столбцы имеют допустимое имя.

Есть идеи, что не так? У кого-нибудь есть обходной путь?

Кстати. ResultSet выглядит довольно хорошо в отладчике eclipse


person Maick    schedule 20.08.2015    source источник
comment
Попробуйте getColumnLabel(i). В качестве обходного пути вы можете попробовать явные метки столбцов: ... AS col1, ... AS col2.   -  person Joop Eggen    schedule 20.08.2015
comment
@JoopEggen Псевдоним не сопоставляется с columnName, только с columnLabel   -  person Mark Rotteveel    schedule 20.08.2015
comment
@MarkRotteveel хорошее разъяснение.   -  person Joop Eggen    schedule 20.08.2015


Ответы (1)


Вместо getColumnName вам нужно использовать getColumnLabel. Имя столбца имеет значение только в том случае, если значение гарантированно исходит из одного столбца в одной таблице, чего нельзя сказать о UNION. В случае UNION Firebird обрабатывает имена столбцов (или псевдонимы, если они указаны) в первом выборе только как псевдонимы (метки); он не сохраняет имя столбца как имя столбца, которое может быть возвращено getColumnName.

Если вам действительно нужно использовать getColumnName (например, из соображений совместимости), вы можете использовать свойство соединения Jaybird columnLabelForName=true, но это не рекомендуется, поскольку оно несовместимо с JDBC. Почти во всех случаях вместо этого следует использовать getColumnLabel.

Различие между именем столбца и меткой столбца тонкое и не было четко выражено в старой спецификации JDBC. В основном имя столбца — это имя столбца в исходной таблице, а метка столбца — это «имя» (или, правильнее: метка) столбца в результирующем наборе. Меткой является либо псевдоним, указанный с помощью AS, либо, если псевдоним не указан, исходное имя столбца, возвращенное с помощью getColumnName.

Смотрите также:

Раскрытие информации: я один из разработчиков Jaybird

person Mark Rotteveel    schedule 20.08.2015
comment
Но, с моей точки зрения, это не так ясно из имени столбца возврата java doc в getColumnName по сравнению с возвратом предлагаемого заголовка столбца в getColumnLabel. В частности, с документом из getColumnLabel Если SQL-код›AS‹/code› не указан, значение, возвращаемое из * ‹code›getColumnLabel‹/code›, будет таким же, как значение, возвращаемое * ‹code›getColumnName ‹/код› метод. - person Maick; 20.08.2015
comment
@Maick Вещь columnName ‹› columnLabel, к сожалению, является одной из вещей в JDBC, которая не ясна на 100% (хотя она улучшилась по сравнению с тем, что было указано в JDBC 2.0 iirc). То, что здесь не передается имя столбца, является деталью реализации Firebird; вполне могут быть базы данных, в которых в этом случае заполняется имя столбца, однако вам почти всегда нужно использовать columnLabel в любом случае (например, извлечение значений из набора результатов выполняется либо по индексу столбца, либо по метке столбца), поэтому я бы не стал останавливаться на нем слишком много. - person Mark Rotteveel; 20.08.2015