Java 应用程序中索引::5、jdbc 和 oracle 处缺少 IN 或 OUT 参数

问题描述 投票:0回答:1

虽然我只有 4 个占位符,但我收到错误 在索引:: 5 处缺少 IN 或 OUT 参数下面是 jpql 和我正在使用 setParameters 的方法。

私有静态最终字符串 TIMESTAMP_FORMAT = "'ddmmyyyy hh24:mi:ss'";

JPQL

private static final String SQL_GET_EOD_LIST = "SELECT tr.*, txn.accounting_code, txn.accounting_explanation, txn.is_financial, "
        + "txn.send_to_statement, txn.affected_limit, txn.FINANCIAL_EFFECT "
        + "FROM (SELECT   app_id, ch_id, NVL(str_id, 'MAIN') AS str_id, trn_desc, trn_type, bal_code, "
        + "                 SUM (dedicated_money) AS balance, NVL(SUM(str_fee), 0) AS fee "
        + "            FROM WALLET.shopping_trn "
        + "           WHERE create_date BETWEEN TO_DATE (?, " + TIMESTAMP_FORMAT + ") "
        + "                                 AND TO_DATE (?, " + TIMESTAMP_FORMAT + ") "
        + "        GROUP BY app_id, ch_id, str_id, trn_desc, trn_type, bal_code) tr, "
        + "       WALLET.txn_def_lookup trn_lookup, "
        + "       WALLET.txn_def txn "
        + " WHERE tr.trn_desc = trn_lookup.trn_desc "
        + "   AND tr.bal_code = trn_lookup.bal_code "
        + "   AND trn_lookup.txn_def_id = txn.ID "
        + "   AND tr.balance > 0  "
        + "UNION ALL "
        + "SELECT tr.*, txn.accounting_code, txn.accounting_explanation, txn.is_financial, "
        + "       txn.send_to_statement, txn.affected_limit, txn.FINANCIAL_EFFECT "
        + "FROM (SELECT   app_id, ch_id, NVL(str_id, 'MAIN') AS str_id, trn_desc, trn_type, bal_code, "
        + "                 SUM (main_money) AS balance, NVL(SUM(str_fee), 0) AS fee "
        + "            FROM WALLET.shopping_trn "
        + "           WHERE create_date BETWEEN TO_DATE (?, " + TIMESTAMP_FORMAT + ") "
        + "                                 AND TO_DATE (?, " + TIMESTAMP_FORMAT + ") "
        + "        GROUP BY app_id, ch_id, str_id, trn_desc, trn_type, bal_code) tr, "
        + "       WALLET.txn_def_lookup trn_lookup, "
        + "       WALLET.txn_def txn "
        + " WHERE tr.trn_desc = trn_lookup.trn_desc "
        + "   AND tr.bal_code = trn_lookup.bal_code "
        + "   AND trn_lookup.txn_def_id = txn.ID "
        + "   AND tr.balance > 0  ";

方法

@Override
public List<EodView> fetchEodData(final String targetDate, String logInfo) {
    List<EodView> results;
    final String startDate = targetDate + " 00:00:00";
    final String endDate = targetDate + " 23:59:59";
    String query = obtainEodDataQuery();
    
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("fetchEodData SQL: {}",
                EMoneyCorpUtil.sqlBindReplace4Log(LOGGER.isDebugEnabled(),
                        query, startDate, endDate));
    }
    
    results = getJdbcTemplate().query(query, ps -> {
        ps.setString(1, startDate);
        ps.setString(2, endDate);
        ps.setString(3, startDate);
        ps.setString(4, endDate);
    }, new EodRowMapper());
    
    return results;
}

我尝试间隔占位符,更改sql查询的语法,我读过很多问题,但没有一个回答我的问题。

谢谢你。

java oracle jdbc jpql
1个回答
0
投票
  1. 在:

    if (LOGGER.isDebugEnabled()) {
         LOGGER.debug("fetchEodData SQL: {}",
                 EMoneyCorpUtil.sqlBindReplace4Log(LOGGER.isDebugEnabled(),
                         query, startDate, endDate));
    }
    

    当查询中有四个占位符需要绑定值时,您可以将两个绑定参数传递到查询中。这可能是错误的原因。

  2. 您可以传递

    LocalDateTime
    值而不是字符串:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyy HH:mm:ss");
    results = getJdbcTemplate().query(query, ps -> {
         ps.setObject(1, LocalDateTime.parse(startDate, formatter));
         ps.setObject(2, LocalDateTime.parse(endDate, formatter));
     }, new EodRowMapper());
    
  3. 您的查询会在您一起

    UNION
    几乎相同的子查询中重复出现。您可以使用一个查询并
    UNPIVOT
    (未经测试,因为我没有您的表格或数据):

    SELECT tr.app_id,
           tr.ch_id,
           tr.str_id,
           tr.trn_desc,
           tr.trn_type,
           tr.bal_code,
           tr.balance,
           tr.fee,
           txn.accounting_code,
           txn.accounting_explanation,
           txn.is_financial,
           txn.send_to_statement,
           txn.affected_limit,
           txn.FINANCIAL_EFFECT
    FROM   (
             SELECT app_id,
                    ch_id,
                    COALESCE(str_id, 'MAIN') AS str_id,
                    trn_desc,
                    trn_type,
                    bal_code,
                    COALESCE(SUM(dedicated_money), 0) AS dedicated_money,
                    COALESCE(SUM(main_money), 0) AS main_money
                    COALESCE(SUM(str_fee), 0) AS fee
             FROM   WALLET.shopping_trn
             WHERE  create_date BETWEEN ? AND ?
             GROUP BY
                    app_id,
                    ch_id,
                    str_id,
                    trn_desc,
                    trn_type,
                    bal_code
           )
           UNPIVOT (
             balance FOR balance_type IN (dedicated_money, main_money)
           ) tr
           INNER JOIN WALLET.txn_def_lookup trn_lookup
           ON     tr.trn_desc = trn_lookup.trn_desc
              AND tr.bal_code = trn_lookup.bal_code
           INNER JOIN WALLET.txn_def txn
           ON trn_lookup.txn_def_id = txn.ID
    WHERE  tr.balance > 0
    

    那么你只需要读一次表,并且只有两个绑定参数。

© www.soinside.com 2019 - 2024. All rights reserved.