Oracle Java预准备语句插入(如果不存在)

时间:2018-10-11 14:12:41

标签: java sql spring oracle prepared-statement

我在Java PreparedStatement和Oracle方面有问题。

简而言之,我想在我的Oracle DB中使用Java创建一个批处理插入。我尝试使用以下代码:

       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 :(得分:0)

代码的“不存在的地方”版本应该可以使用。

我会再次检查您是否正在设置?值正确显示在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) {
        }
    }
}  }