我必須通過java代碼將資料一一插入到department和employee這兩個表中。每個表都有一個公共列dept_id,它是部門表的主鍵和雇員表的外鍵,從部門表的dept_id列參考。在部門表中的dept_id 上定義了一個序列dept_sequence。
現在,我目前將資料插入這兩個表的方法如下,
我分別對 dept_id 列使用 dept_sequence.nextval 和 dept_sequence.currval 將資料插入到這兩個表中。
Map<String, Object> deptData = ImmutableMap.builder()
.put("DEPT_NAME", "TEXTILE")
.put("LOCATION", "PARIS")
.build();
String insertToDeptSql = "INSERT INTO DEPARTMENT(DEPT_ID, DEPT_NAME, LOCATION)
VALUES(dept_sequence.nextval, :DEPT_NAME, :LOCATION)";
namedParameterJdbcTemplate.update(insertToDeptSql , deptData);
Map<String, Object> empData = ImmutableMap.builder()
.put("EMP_NAME", "John")
.put("AGE", 15)
.build();
String insertToEmpSql = "INSERT INTO EMPLOYEE(EMP_ID, DEPT_ID, EMP_NAME, AGE)
VALUES(emp_sequence.nextval, dept_sequence.currval, :EMP_NAME, :AGE)";
namedParameterJdbcTemplate.update(insertToEmpSql, empData);
當一次只有一個事務時,它作業得非常好。兩個表都有正確的dept_id值,但它在多事務環境中中斷。雇員表沒有收到插入到部門表中的一個事務的 dept_sequence 的相同值。在將記錄插入到雇員表之前,dept_sequence 值被一個不同的事務增加(新記錄插入到部門表中),這可能發生在不同的系統中,雇員表接收到一些增加的序列值。
我們如何以這樣一種方式來實作這一點,即同一事務的兩個表中的 dept_id 值保持相同。
注意:實際資料模型不同,員工和部門僅用于示例目的,因此不要建議對模型和主鍵、外鍵約束進行任何更改,因為我不允許對實際模型做任何事情。
uj5u.com熱心網友回復:
String insertToDeptSql = "INSERT INTO DEPARTMENT(DEPT_ID, EMP_ID, EMP_NAME, DEPT_NAME, LOCATION)
VALUES(dept_sequence.nextval, emp_sequence.currval, :EMP_NAME, :DEPT_NAME, :LOCATION)"
如果您的主鍵約束是 on (dept_id, emp_id),那么理論上,您可以運行單獨的 SQL 查詢來獲取dept_sequence.nextval,然后將相同的值傳遞到每個插入中。但這是對序列的非常...非常規的使用,我認為有更簡單的方法。
我建議重新評估資料模型。
你的department桌子不是存盤部門。它存盤員工與部門的關系。如果員工 A 和員工 B 在同一部門,則您沒有 2 個部門。
我建議您做的是dept_id在employee桌子上放一列,然后在department桌子上洗掉與員工相關的列。
你最終會得到這樣的結果:
Map<String, Object> deptData = ImmutableMap.builder()
.put("DEPT_NAME", "MECH")
.put("LOCATION", "PARIS")
.build();
String insertToDeptSql = "INSERT INTO DEPARTMENT(DEPT_ID, DEPT_NAME, LOCATION)
VALUES(dept_sequence.nextval, :DEPT_NAME, :LOCATION)";
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection
.prepareStatement(INSERT_MESSAGE_SQL);
ps.setString(1, message);
return ps;
}, keyHolder);
}
long departmentId = keyHolder.getKey().longValue();
Map<String, Object> empData = ImmutableMap.builder()
.put("EMP_NAME", "John")
.put("AGE", 15)
.put("DEPARTMENT", departmentId)
.build();
String insertToEmpSql = "INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, AGE, DEPARTMENT)
VALUES(emp_sequence.nextval, :EMP_NAME, :AGE, :DEPARTMENT)";
jdbcTemplate.update(insertToEmpSql, empData);
您可以為部門的每個員工重復最后一部分并重復使用departmentId.
uj5u.com熱心網友回復:
正如 Brandon 所說,您的資料模型不是很好。但要回答您實際問的問題,基本上是“我如何捕獲剛剛插入的 id 值?” 您在RETURNING INTO第一次插入時使用該子句:
INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, AGE)
VALUES(emp_sequence.nextval, :EMP_NAME, :AGE)
RETURNING EMP_ID INTO :x
在 PL/SQL 中,這是非常簡單的。要通過 JDBC 完成,捕獲的方式略有不同,盡管 getGeneratedKeys()。請參閱Oracle 在 Java 中的 RETURNING INTO 用法(JDBC、Prepared Statement)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/373533.html
