Oracle Java Prepared Statement Insert, если не существует - PullRequest
0 голосов
/ 11 октября 2018

У меня проблема с Java PreparedStatement и Oracle.

Короче говоря, я хочу создать пакетную вставку с использованием Java в моей базе данных Oracle.Я пытаюсь сделать это с помощью этого кода:

       PreparedStatement preparedStmt = connection.prepareStatement(
                "INSERT INTO EFM_BAS_DATA_CLEAN_NUM (date_measured, time_measured, value_reported, data_point_id) " +
                " VALUES(?,?,?,?)");

       PreparedStatement preparedStmt = connection.prepareStatement(query);
       for (EfmBasDataCleanNum measure : measuresToInsert) {

            preparedStmt.setString(1, new java.sql.Date(measure.getDateMeasured().getTime()));
            preparedStmt.setString(2, measure.getTimeMeasured());
            preparedStmt.setDouble(3, measure.getValueReported());
            preparedStmt.setInt(4, measure.getDataPointId());
            preparedStmt.addBatch();
        }

        try {
            preparedStmt.executeBatch();
        }catch (SQLException e){ ...

Однако, когда некоторые записи уже существуют в таблице, у меня есть эта ошибка:

ORA-00001: ограничение уникальности (AFM.UNIQUE_EFM_CLEAN_NUM) нарушен

, потому что у меня есть ограничения на эти поля.

Итак, глядя на линию, я нашел много решений.

Я пытался с этим запросом:

String query = "INSERT INTO EFM_BAS_DATA_CLEAN_NUM (date_measured, time_measured, value_reported, data_point_id) "+ 
                "   SELECT TO_DATE(?,'DD/MM/YYYY HH24:MI:SS'),TO_DATE(?,'DD/MM/YYYY HH24:MI:SS'),?,? FROM DUAL "+
                "   MINUS "+
                "   SELECT date_measured, time_measured, value_reported, data_point_id FROM efm_bas_data_clean_num";

или с:

String query = " INSERT INTO EFM_BAS_DATA_CLEAN_NUM ( date_measured, time_measured, value_reported, data_point_id ) "
            +" SELECT TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS'), TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS'),?,? FROM DUAL "
            +" WHERE not exists("
            +"     SELECT * FROM EFM_BAS_DATA_CLEAN_NUM  "
            +"     WHERE DATE_MEASURED=TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS') "
            +"     AND TIME_MEASURED=TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS') "
            +"     AND VALUE_REPORTED=? "
            +"     AND DATA_POINT_ID=? )";

и, наконец, с:

String query = "MERGE INTO EFM_BAS_DATA_CLEAN_NUM bd1 USING ("
                +"    SELECT TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS') as DATE_MEASURED, "
                +"    TO_DATE(?, 'DD/MM/YYYY HH24:MI:SS') as TIME_MEASURED,"
                +"    ? as VALUE_REPORTED,"
                +"    ? as DATA_POINT_ID FROM DUAL "
                +" ) bd2 on (bd1.DATE_MEASURED=bd2.DATE_MEASURED AND"
                +"      bd1.TIME_MEASURED=bd2.TIME_MEASURED AND"
                +"      bd1.VALUE_REPORTED=bd2.VALUE_REPORTED AND"
                +"      bd1.DATA_POINT_ID=bd2.DATA_POINT_ID)"
                +" WHEN NOT MATCHED THEN "
                +"    INSERT (date_measured, time_measured, value_reported, data_point_id)  "
                +"    VALUES(bd2.DATE_MEASURED,bd2.TIME_MEASURED,bd2.VALUE_REPORTED,bd2.DATA_POINT_ID)";

Но пока выполняетсязапроса в AquaData Studio когда-либо работает (точнее, когда это новая запись, она вставлена, и когда запись уже существует, она не вставлена, без ошибок), при запуске приложения у меня по-прежнему та же ошибка:

ORA-00001: уникальное ограничение (AFM.UNIQUE_EFM_CLEAN_NUM) нарушено

возможно я ошибаюсь?Спасибо!

1 Ответ

0 голосов
/ 11 октября 2018

Должна сработать версия вашего кода "где не существует".

Я бы дважды проверил, что вы устанавливаете?значения в вашем коде Java правильно, так что ваши значения вставки совпадают с вашими значениями «где не существует».

Я попробовал ваш код с моими собственными таблицами, и это сработало.Я использовал select 'X' вместо *, но это не должно иметь значения.Мой sorydct_cert_key - это уникальный ключ.

private void testInsert() throws SQLException {

    String first = "8ADA";
    Integer second = 8;
    String third = "ADA Failed";
    String fourth = "EXC";
    String sql = "INSERT INTO SORYDCT(SORYDCT_CERT_KEY," +
            " SORYDCT_CERT_CODE," +
            " SORYDCT_CERT_DESC," +
            " SORYDCT_PROGRAM," +
            " SORYDCT_COUNT_CODE)" +
            " SELECT ?,?,?,?, NULL" +
            " FROM DUAL" +
            " WHERE NOT EXISTS ( SELECT 'X'" +
            " FROM SORYDCT" +
            " WHERE SORYDCT_CERT_KEY = ?)";
    PreparedStatement insertStatement = null;
    try {
        insertStatement = conn.prepareStatement(sql);
        insertStatement.setNString(1, first);
        insertStatement.setInt(2, second);
        insertStatement.setString(3, third);
        insertStatement.setString(4, fourth);
        insertStatement.setString(5, first);
        insertStatement.executeUpdate();
        conn.commit();
    } catch (SQLException e) {
        System.out.println(ERROR_STRING);
        System.out.println("Failure while inserting records - 1");
        onException(e);
    } finally {
        try {
            insertStatement.close();
        } catch (SQLException e) {
        }
    }
    first = "TEST";
    second = 0;
    third = "Test";
    fourth = "EXC";
    System.out.println(sql);
    insertStatement = null;
    try {
        insertStatement = conn.prepareStatement(sql);
        insertStatement.setNString(1, first);
        insertStatement.setInt(2, second);
        insertStatement.setString(3, third);
        insertStatement.setString(4, fourth);
        insertStatement.setString(5, first);
        insertStatement.executeUpdate();
        conn.commit();
    } catch (SQLException e) {
        System.out.println(ERROR_STRING);
        System.out.println("Failure while inserting records - 2 ");
        onException(e);
    } finally {
        try {
            insertStatement.close();
        } catch (SQLException e) {
        }
    }
}  }        
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...