Java能够在一个表中执行标识插入,而不能在另一个表中执行

时间:2016-02-22 08:44:52

标签: sql-server spring

我正在从另一个数据库的一个表中复制数据并将其插入到具有相同表的另一个数据库中。 我写了一个java代码来完成这项工作,我有两个表Container_Detail和Remote_Event2。 这两个表都包含标识列。 在java代码中,每当我要将数据插入表中时,我都会设置标识插入,然后在finally块中我将设置标识插入关闭。 相同的Java代码对于Container_Detail表工作正常,但是对于Remote_Event表我遇到以下错误:

当IDENTITY_INSERT设置为OFF时,无法在表'Remote_Event2'中为identity列插入显式值。

以下是Container_Detail表的日志(我的代码工作正常):

  

2016-02-22 13:43:11 DEBUG [http-nio-8089-exec-5] JdbcTemplate:533 -   执行SQL更新[SET IDENTITY_INSERT Container_Detail ON]   2016-02-22 13:43:11 DEBUG [http-nio-8089-exec-5] JdbcTemplate:540 -   SQL更新受影响-1行2016-02-22 13:43:11 DEBUG   [http-nio-8089-exec-5] JdbcTemplate:533 - 执行SQL更新[INSERT   INTO Container_Detail   (detail_id,CONTAINER_ID,ITEM_ID,数量,attribute_id,inventory_status,tenant_id,attribute_group,SEQNUM)   VALUES   ( '1', '00007712120036947807', 'Dummy_Item', '1', 'ATTR00000000258', 'A', 'NWC', '', '0')]   2016-02-22 13:43:12 DEBUG [http-nio-8089-exec-5] JdbcTemplate:540 -   SQL更新影响了1行2016-02-22 13:43:12 DEBUG   [http-nio-8089-exec-5] JdbcTemplate:533 - 执行SQL更新[SET   IDENTITY_INSERT Container_Detail OFF]

以下是我遇到错误的Remote_Event2表的日志:

  

2016-02-22 14:01:10 DEBUG [http-nio-8089-exec-1] JdbcTemplate:533 -   执行SQL更新[SET IDENTITY_INSERT Remote_Event2 ON] 2016-02-22   14:01:11 DEBUG [http-nio-8089-exec-1] JdbcTemplate:540 - SQL更新   受影响-1行2016-02-22 14:01:11 DEBUG [http-nio-8089-exec-1]   JdbcTemplate:533 - 执行SQL更新[INSERT INTO Remote_Event2   (event_id的,EVENT_TYPE,tenant_id,geoloc_id,event_status,RETRY_COUNT,last_updt_user,RESPONSE_CODE,response_msg,create_dte,process_start_dte,process_end_dte)   VALUES   ( '161', 'CloseDelivery', 'NWC', 'CATHO', 'PENDING', '1', '恩贾妮', '0', '成功','2015年12月21日   13:25:00.0','2015-12-21 20:18:00.0','2015-12-21 20:18:00.0')]   2016-02-22 14:01:12错误[http-nio-8089-exec-1] ExceptionUtil:14 -   发生异常:   org.springframework.dao.DataIntegrityViolationException:   StatementCallback; SQL [INSERT INTO Remote_Event2   (event_id的,EVENT_TYPE,tenant_id,geoloc_id,event_status,RETRY_COUNT,last_updt_user,RESPONSE_CODE,response_msg,create_dte,process_start_dte,process_end_dte)   VALUES   ( '161', 'CloseDelivery', 'NWC', 'CATHO', 'PENDING', '1', '恩贾妮', '0', '成功','2015年12月21日   13:25:00.0','2015-12-21 20:18:00.0','2015-12-21 20:18:00.0')];不能   在表'Remote_Event2'中为identity列插入显式值   当IDENTITY_INSERT设置为OFF时。嵌套异常是   com.microsoft.sqlserver.jdbc.SQLServerException:无法插入   表'Remote_Event2'中的标识列的显式值   IDENTITY_INSERT设置为OFF。,UUID:   7a940d15-d842-4b02-be44-8c8d66b57c65 2016-02-22 14:01:12错误   [http-nio-8089-exec-1] ExceptionUtil:15 -   org.springframework.dao.DataIntegrityViolationException:   StatementCallback; SQL [INSERT INTO Remote_Event2   (event_id的,EVENT_TYPE,tenant_id,geoloc_id,event_status,RETRY_COUNT,last_updt_user,RESPONSE_CODE,response_msg,create_dte,process_start_dte,process_end_dte)   VALUES   ( '161', 'CloseDelivery', 'NWC', 'CATHO', 'PENDING', '1', '恩贾妮', '0', '成功','2015年12月21日   13:25:00.0','2015-12-21 20:18:00.0','2015-12-21 20:18:00.0')];不能   在表'Remote_Event2'中为identity列插入显式值   当IDENTITY_INSERT设置为OFF时。嵌套异常是   com.microsoft.sqlserver.jdbc.SQLServerException:无法插入   表'Remote_Event2'中的标识列的显式值   IDENTITY_INSERT设置为OFF。 2016-02-22 14:01:14调试   [http-nio-8089-exec-1] JdbcTemplate:533 - 执行SQL更新[SET   IDENTITY_INSERT Remote_Event2 OFF] 2016-02-22 14:01:14 DEBUG   [http-nio-8089-exec-1] JdbcTemplate:540 - SQL更新受影响-1行

请注意我使用的是SQL Server和Spring JDBC。 请建议做什么以及实际问题在哪里?

编辑:

我正在使用以下SQL查询:

SET IDENTITY_INSERT @ TABLE @ ON

SET IDENTITY_INSERT @ TABLE @ OFF

我通过java代码在查询中传递表名:

@Override
public void setIdentityInsertOn(String tableName, JdbcTemplate jdbcTemplateArchiveDatabase) throws WMSLiteDAOException {
    String sqlQuery = CommonUtility.fetchSqlQuery(LookupSQLQueries.SET_IDENDTITY_INSERT_ON);
    sqlQuery = CommonUtility.generateDynamicQueryForCustomTable(sqlQuery, tableName, "", "", null);
    maintenanceDAO.updateData(sqlQuery, jdbcTemplateArchiveDatabase);
}
@Override
public void setIdentityInsertOff(String tableName, JdbcTemplate jdbcTemplateArchiveDatabase) throws WMSLiteDAOException {
    String sqlQuery = CommonUtility.fetchSqlQuery(LookupSQLQueries.SET_IDENDTITY_INSERT_OFF);
    sqlQuery = CommonUtility.generateDynamicQueryForCustomTable(sqlQuery, tableName, "", "", null);
    maintenanceDAO.updateData(sqlQuery, jdbcTemplateArchiveDatabase);
}

生成查询的代码(在调试时检查其工作正常):

public static String generateDynamicQueryForCustomTable(String sqlQuery, String tableName, String primaryKey, String values, Map<String, String> rowData){
    sqlQuery = sqlQuery.replace("@TABLE@", tableName);
    sqlQuery = sqlQuery.replace("@PRIMARYKEY@", primaryKey);
    if(values != null && !values.isEmpty()){

        values = values.replaceAll(" ", "");
        values=values.replaceAll("^|$", "'").replaceAll(",", "','"); 

        }
    sqlQuery = sqlQuery.replace("@VALUES@", values);
    if(sqlQuery.contains("@COLUMN_VALUES@")){
        StringBuilder columnNames = new StringBuilder();
        StringBuilder columnValues = new StringBuilder();
        for(String currentKey : rowData.keySet()){
            columnNames = columnNames.append(currentKey+",");
            columnValues = columnValues.append("'"+rowData.get(currentKey)+"',");
        }
        columnNames = columnNames.replace(columnNames.length() - 1, columnNames.length(), "");
        columnValues = columnValues.replace(columnValues.length() - 1, columnValues.length(), "");
        sqlQuery = sqlQuery.replace("@COLUMN_NAMES@", columnNames);
        sqlQuery = sqlQuery.replace("@COLUMN_VALUES@", columnValues);
    }
    return sqlQuery;
}

1 个答案:

答案 0 :(得分:0)

您面临的问题是交易相关。您必须没有实现事务,因为每个sql查询java执行都在单独的会话中,因此您无法为执行插入查询的会话设置标识插入。

通过以下方式进行注释来实施AOP交易:

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)

实现事务后,当前事务中只有一个会话,所有查询都将通过该会话执行。