Ошибка неверного имени столбца RowMapper в Java

У меня есть запрос, и он хорошо работает с базой данных. Однако, когда я попытался использовать их как объект Java с помощью RowMapper, я получаю сообщение об ошибке недопустимого имени столбца. Я все проверил, но я не понимаю, почему эта ошибка происходит.

Мой запрос:

SELECT TEMP.SUMALLTXN, SUM(TEMP.SUMCARD), SUM(TEMP.SUMERRORTXN), SUM(TEMP.SUMERRORTXNCARD)
FROM
(SELECT
SUM(COUNT(*)) OVER() AS SUMALLTXN,

COUNT(mdmtxn.BIN) OVER (PARTITION BY mdmtxn.BIN) AS SUMCARD,

SUM(case when mdmtxn.MDSTATUS NOT IN ('1','9', '60') then 1 else 0 end) AS SUMERRORTXN,

SUM(case when mdmtxn.MDSTATUS NOT IN ('1','9', '60') then 1 else 0 end) OVER (PARTITION BY mdmtxn.BIN) AS SUMERRORTXNCARD

FROM MDM59.MDMTRANSACTION2 mdmtxn WHERE
    mdmtxn.CREATEDDATE < TO_CHAR(SYSDATE - INTERVAL ':initialMinuteParameterValue' MINUTE ,'YYYYMMDD HH24:MI:SS') AND
    mdmtxn.CREATEDDATE > TO_CHAR(SYSDATE - INTERVAL ':intervalMinuteParameterValue' MINUTE ,'YYYYMMDD HH24:MI:SS')
GROUP BY mdmtxn.MDSTATUS, mdmtxn.BIN
) TEMP
GROUP BY TEMP.SUMALLTXN

Мой RowMapper:

@Component
public class TotalTransactionsReportRw implements RowMapper<TotalTransactionsReportDto> {

    @Override
    public TotalTransactionsReportDto mapRow(ResultSet rs, int rowNum) throws SQLException {
        return TotalTransactionsReportDto.builder()
                .totalNumbersOfTransactions(rs.getString("SUMALLTXN"))
                .totalNumbersOfCard(rs.getString("SUMCARD"))
                .totalNumbersOfErrorTransactions(rs.getString("SUMERRORTXN"))
                .totalNumbersOfErrorCard(rs.getString("SUMERRORTXNCARD"))
                .build();
    }

    private static class TotalTransactionsDetailRwHolder {
        private static final TotalTransactionsReportRw INSTANCE = new TotalTransactionsReportRw();
    }

    public static TotalTransactionsReportRw getInstance() {
        return TotalTransactionsReportRw.TotalTransactionsDetailRwHolder.INSTANCE;
    }
}

Мой дто:

@Value
@Builder
@Data
public class TotalTransactionsReportDto {
    private String totalNumbersOfTransactions;
    private String totalNumbersOfCard;
    private String totalNumbersOfErrorTransactions;
    private String totalNumbersOfErrorCard;
}

И в моем классе задач я создал список для получения всех данных из rowmapper:

@Slf4j
@Component
@RequiredArgsConstructor
public class NotificationTasklet implements Tasklet {

    private final PofPostOfficeServiceClient pofPostOfficeServiceClient;
    private final SequenceSysGuid sequenceSysGuid;
    private final BatchProps batchProps;
    private JdbcTemplate jdbcTemplate;
    private String notificationMailSql;
    private String totalTransactionsSql;
    private String endOfHtmlString = "</table></body></html>";
    private String endOfTableString = "</table>";
    private String jobName = "vpos-notification";
    private String tdClose = "</td>";`

    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {

        List<VposNotificationBatchDto> notificationList = getNotificationList();

        List<TotalTransactionsReportDto> totalTransactionsList = getTotalTransactionsList();

        AlertMailDto alertMailDto = createAlertMailDto(notificationList,totalTransactionsList);

        if (!(notificationList.isEmpty())) {
            sendMail(alertMailDto);
        }

        return RepeatStatus.FINISHED;
    }

    List<TotalTransactionsReportDto> getTotalTransactionsList() {
        return jdbcTemplate.query(
                totalTransactionsSql,
                new TotalTransactionsReportRw());
    }

    @Autowired
    public void     setTotalTransactionsSql(@Value("classpath:sql/vposnotification/select_total_transactions_data.sql")
                                               Resource res) {
        int intervalnext = batchProps.getJobProps()
                .get(jobName).getAlertProps().getIntervalMinuteParameterValue();
        String intervalMinutes = String.valueOf(intervalnext);

        int initialMinuteParameterValue = batchProps.getJobProps()
                .get(jobName).getAlertProps().getInitialMinuteParameterValue();
        String initialMinutes = String.valueOf(initialMinuteParameterValue);

        this.totalTransactionsSql = SqlUtils.readSql(res);
             this.totalTransactionsSql = this.totalTransactionsSql.replace(":initialMinuteParameterValue",          initialMinutes);
              this.totalTransactionsSql = this.totalTransactionsSql.replace(":intervalMinuteParameterValue",     intervalMinutes);
    }

    @Autowired
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
         this.jdbcTemplate = jdbcTemplate;
    }

SUM(X) и X не совпадают, поэтому я предполагаю, что ваша проблема здесь: .totalNumbersOfCard(rs.getString("SUMCARD")) (и другие, подобные этому). измените свой запрос на: SUM(SUMCARD) AS SUMCARD

Stultuske 10.02.2023 08:41

Пожалуйста, укажите используемую СУБД. В вашем запросе нет столбцов SUMCARD, SUMERRORTXN и SUMERRORTXNCARD, или, по крайней мере, не все столбцы псевдонимов СУБД SUM с именем суммируемого столбца, поэтому вы должны указать их псевдонимы явно, например. SUM(TEMP.SUMCARD) AS SUMCARD.

Mark Rotteveel 10.02.2023 08:42

@MarkRotteveel извините, я забыл сказать, это PLSQL

xprop 10.02.2023 08:46

Вы имеете в виду Оракула?

Mark Rotteveel 10.02.2023 08:47

@MarkRotteveel да, это оракул

xprop 10.02.2023 08:49
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что в вашем запросе на самом деле нет столбцов SUMCARD, SUMERRORTXN и SUMERRORTXNCARD. Хотя существуют СУБД, которые используют псевдонимы столбцов SUM с именем суммируемого столбца, Oracle не входит в их число. IIRC, Oracle называет его псевдонимом, например, "SUM(SUMCARD)" или, может быть, "SUM(TEMP.SUMCARD)". Однако, на мой взгляд, это деталь реализации, на которую не стоит полагаться.

Чтобы получить имя, которое вы хотите использовать, вам нужно явно указать псевдоним для ваших столбцов SUM, например. SUM(TEMP.SUMCARD) AS SUMCARD.

Итак, вы предпочитаете добавлять псевдоним «AS» в первый оператор выбора в запросе?

xprop 10.02.2023 09:06

@xprop это не имеет ничего общего с настройками. Ваш картограф ищет столбец SUMCARD в результате вашего запроса, но такого столбца нет, поэтому вам нужно убедиться, что ваш столбец имеет это имя.

Stultuske 10.02.2023 09:10

Проблема решена спасибо :)

xprop 10.02.2023 09:18

Другие вопросы по теме