У меня есть таблица с четырьмя столбцами, вот как она выглядит. Я бы назвал это T_BPR_KPI_MONTHLY_VALUESOracle SQL Merge не будет выполняться над Statement
KPI_NAME_SHORT_S | MONTH_N | YEAR_N | VALUE_N
-----------------------------------------------
MY_KPI_1 | 1 | 2015 | 99.87
MY_KPI_2 | 1 | 2015 | 97.62
... | 1 | 2015 | ...
MY_KPI_1 | 2 | 2015 | ...
... | ... | 2015 | ...
Каждый КПЭ представляет собой измерение, и каждый из них имеет ежедневные значения, которые сохраняются в другой таблице под названием T_BPR_KPI_DY. Моя цель - рассчитать и сохранить ежемесячные значения каждого KPI.
Возможно, что в определенный день суточные значения для некоторых kpis все еще отсутствуют, и для того, чтобы точно рассчитать месячные значения, я должен быть в состоянии заменить существующие ценности в базе данных, а также вставлять новые трии в будущие месяцы и годы.
Я старался, чтобы операция слияния оракула была хорошим выбором для этой задачи. Идея состоит в том, чтобы проверить, существует ли запись, и если да, чем обновить ее значение, а если не вставить новую.
Это, как запрос выглядит
MERGE INTO T_BPR_KPI_MONTHLY_VALUE A
USING(SELECT 'MY_KPI_1' AS KPI_NAME_SHORT_S, 1 AS MONTH_N, 2014 AS YEAR_N FROM DUAL) B
ON (A.KPI_NAME_SHORT_S = B.KPI_NAME_SHORT_S)
WHEN MATCHED THEN
UPDATE SET VALUE_N = (select AVG(MY_KPI_1) from T_BPR_KPI_DY where DAY_D between '01.01.2014' AND '31.01.2014')
WHEN NOT MATCHED THEN
INSERT (KPI_NAME_SHORT_S, MONTH_N, YEAR_N, VALUE_N) VALUES ('MY_KPI_1', 1, 2014, (select AVG(MY_KPI_1) from T_BPR_KPI_DY where DAY_D between '01.01.2014' AND '31.01.2014'))
Я учил, что вычисление Avg месячных значений на лету не плохая идея, так как вы можете видеть, у меня есть еще один запрос на выборку, который только вычисляет Avg Monthy значение для конкретного kpi. Я не уверен, что это лучшее практическое решение, но оно отлично работает, когда я выполняю этот запрос в инструменте разработчика oracle sql. однако, когда я пытаюсь выполнить его из приложения, он не работает.
Это как метод выглядит
public static void storeValuesToDb(ArrayList<String> kpiNames) throws SQLException {
Connection conn = getOracleJDBCConnection_DASH();
int currentYear = cal.get(Calendar.YEAR);
int startYear = cal.get(Calendar.YEAR) - 1;
for (String kpiName : kpiNames) {
for (int i = startYear; i <= currentYear; i++) {
for (int j = 0; j < 12; j++) {
try {
String myMergeSQL = ""
+ "MERGE INTO T_BPR_KPI_MONTHLY_VALUE A "
+ "USING(SELECT '" + kpiName + "' AS KPI_NAME_SHORT_S, " + (j + 1) + " AS MONTH_N, " + i + " AS YEAR_N FROM DUAL) B ON (A.KPI_NAME_SHORT_S = B.KPI_NAME_SHORT_S) "
+ "WHEN MATCHED THEN "
+ "UPDATE SET VALUE_N = (select AVG(" + kpiName + ") from T_BPR_KPI_DY where DAY_D between '" + getFirstDateOfMonth(j, i) + "' AND '" + getLastDateOfMonth(j, i) + "') "
+ "WHEN NOT MATCHED THEN "
+ "INSERT (KPI_NAME_SHORT_S, MONTH_N, YEAR_N, VALUE_N) VALUES ('" + kpiName + "', " + (j + 1) + ", " + i + ", (select AVG(" + kpiName + ") from T_BPR_KPI_DY where DAY_D between '" + getFirstDateOfMonth(j, i) + "' AND '" + getLastDateOfMonth(j, i) + "'))";
System.out.println(myMergeSQL);
Statement stmt_dash = conn.createStatement();
stmt_dash.executeUpdate(myMergeSQL);
conn.commit();
stmt_dash.close();
} catch (SQLException ex) {
conn.close();
}
}
}
}
conn.close();
}
В терминал печатает только первый слияния SQL. Он не завершает операцию и не генерирует исключение. Он блокирует как-то и в дБ тоже ничего не происходит. Возможно, мой запрос слияния неверен или невозможно выполнить этот вид операции с помощью объекта-оператора. Если кто-то может узнать, в каких случаях эта проблема, пожалуйста, помогите.
Thx заранее
Ваш улов (SQLException ex) просто закрывает соединение. Распечатайте сообщение об исключении на консоли, оно будет содержать ошибку. – LonWolf
Привет, thx для повтора. Я пробовал, как вы предложили с помощью ex.printStackTrace() ', а также с' System.err.println (ex.getMessage()), но ничего не случилось. Я также удалил 'conn.close()' из блока catch, но это не помогло. однако при выполнении простой вставки sql с этим кодом он отлично работает. Это говорит вам что-то? – amsalk
Как долго выберете AVG (MY_KPI_1) из T_BPR_KPI_DY, где DAY_D между '01 .01.2014 'AND '31 .01.2014'' выполнить? –