У меня есть запрос, и он хорошо работает с базой данных. Однако, когда я попытался использовать их как объект 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;
}
Пожалуйста, укажите используемую СУБД. В вашем запросе нет столбцов SUMCARD
, SUMERRORTXN
и SUMERRORTXNCARD
, или, по крайней мере, не все столбцы псевдонимов СУБД SUM
с именем суммируемого столбца, поэтому вы должны указать их псевдонимы явно, например. SUM(TEMP.SUMCARD) AS SUMCARD
.
@MarkRotteveel извините, я забыл сказать, это PLSQL
Вы имеете в виду Оракула?
@MarkRotteveel да, это оракул
Проблема в том, что в вашем запросе на самом деле нет столбцов SUMCARD
, SUMERRORTXN
и SUMERRORTXNCARD
. Хотя существуют СУБД, которые используют псевдонимы столбцов SUM
с именем суммируемого столбца, Oracle не входит в их число. IIRC, Oracle называет его псевдонимом, например, "SUM(SUMCARD)"
или, может быть, "SUM(TEMP.SUMCARD)"
. Однако, на мой взгляд, это деталь реализации, на которую не стоит полагаться.
Чтобы получить имя, которое вы хотите использовать, вам нужно явно указать псевдоним для ваших столбцов SUM
, например. SUM(TEMP.SUMCARD) AS SUMCARD
.
Итак, вы предпочитаете добавлять псевдоним «AS» в первый оператор выбора в запросе?
@xprop это не имеет ничего общего с настройками. Ваш картограф ищет столбец SUMCARD в результате вашего запроса, но такого столбца нет, поэтому вам нужно убедиться, что ваш столбец имеет это имя.
Проблема решена спасибо :)
SUM(X) и X не совпадают, поэтому я предполагаю, что ваша проблема здесь: .totalNumbersOfCard(rs.getString("SUMCARD")) (и другие, подобные этому). измените свой запрос на: SUM(SUMCARD) AS SUMCARD