我在java db,Alumnus和Certificate中有两个表,它们之间有多对多的关系。所以我介绍了第三个表ALUMNUS_HAS_CERTIFICATE来维护两个表和新的第三个表之间的一对多关系。第三个复合键由原始表的主键组成。我的问题是 我无法使用预准备语句将带有一个重复键的数据插入到第三个表中。 注意:第三个表有一个复合键。
下面的是表的SQL代码。
CREATE TABLE ALUMNUS (
ALUMNUS_ID INT NOT NULL PRIMARY KEY
GENERATED ALWAYS AS IDENTITY
(START WITH 1 , INCREMENT BY 1),
ALUMNUS_NO INT UNIQUE,
FIRST_NAME VARCHAR (45) ,
LAST_NAME VARCHAR (45) ,
OTHER_NAME VARCHAR (100),
RESIDENTIAL_ADDRESS VARCHAR (300),
MAILING_ADDRESS VARCHAR (300),
EMAIL VARCHAR (120) ,
TELEPHONE VARCHAR (25),
EMPLOYEED BOOLEAN NOT NULL DEFAULT FALSE,
JOB_TITLE VARCHAR (200),
EMPLOYER_NAME VARCHAR(120),
EMPLOYER_ADDRESS VARCHAR (300)
);
CREATE TABLE CERTIFICATE (
CERT_ID INT NOT NULL PRIMARY KEY
GENERATED ALWAYS AS IDENTITY (START WITH 1 , INCREMENT BY 1),
CERTIFICATE VARCHAR (300) UNIQUE NOT NULL
);
CREATE TABLE ALUMNUS_HAS_CERT (
ALUMNUS_CK INT NOT NULL,
CERT_CK INT NOT NULL,
YEAR_GRADUATED SMALLINT
);
--CONSTRAINTS
ALTER TABLE ALUMNUS_HAS_CERT ADD CONSTRAINT Alumnus_Has_Cert_Compound_Key PRIMARY KEY
(ALUMNUS_CK,CERT_CK);
ALTER TABLE APP.ALUMNUS_HAS_CERT
ADD FOREIGN KEY (ALUMNUS_CK)
REFERENCES APP.ALUMNUS(ALUMNUS_ID) ON DELETE CASCADE;
ALTER TABLE APP.ALUMNUS_HAS_CERT
ADD FOREIGN KEY (CERT_CK)
REFERENCES APP.CERTIFICATE(CERT_ID) ON DELETE CASCADE;
sql string
String alumnusHasCert = "INSERT INTO APP.ALUMNUS_HAS_CERT "
+ "(ALUMNUS_CK , CERT_CK ,YEAR_GRADUATED ) "
+ "VALUES ( ? , ? , ?)";
准备好的陈述的代码片段
try (PreparedStatement stmAlumnusCert = con.prepareStatement(certUpdate) {
stmAlumnusCert.setInt(1, alumnusID);
stmAlumnusCert.setInt(2, certID);
stmAlumnusCert.setInt(3,year_graduated );
stmAlumnusCert.executeUpdate();
}
来自netbeans IDE的错误消息如下所示:
IntegrityConstraintViolationException: The statement was aborted because it would have caused a
duplicate key value in a unique or primary key constraint or unique index identified by
'ALUMNUS_HAS_CERT_COMPOUND_KEY' defined on 'ALUMNUS_HAS_CERT'.
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source) at
org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeLargeUpdate(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(Unknown Source)
at wa_poly.UpdateData.update(UpdateData.java:192)
at wa_poly.MyJFrame.update(MyJFrame.java:1067)
at wa_poly.MyJFrame.updateButtonActionPerformed(MyJFrame.java:762)
at wa_poly.MyJFrame.access$1300(MyJFrame.java:65)
at wa_poly.MyJFrame$14.actionPerformed(MyJFrame.java:528)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6527)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6292)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4883)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
at java.awt.Container.dispatchEventImpl(Container.java:2278)
at java.awt.Window.dispatchEventImpl(Window.java:2739)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:719)
at java.awt.EventQueue$4.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Suppressed: java.sql.SQLException: Cannot close a connection while a transaction is still active.
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.newSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.checkForTransactionInProgress(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.close(Unknown Source)
at wa_poly.UpdateData.update(UpdateData.java:212)
... 40 more
Caused by: java.sql.SQLException: Cannot close a connection while a transaction is still
active.
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown
Source)
... 48 more
Caused by: java.sql.SQLException: The statement was aborted because it would have caused a
duplicate key value in a unique or primary key constraint or unique index identified by
'ALUMNUS_HAS_CERT_COMPOUND_KEY' defined on 'ALUMNUS_HAS_CERT'.
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
... 51 more
Caused by: ERROR 23505: The statement was aborted because it would have caused a duplicate key
value in a unique or primary key constraint or unique index identified by
'ALUMNUS_HAS_CERT_COMPOUND_KEY' defined on 'ALUMNUS_HAS_CERT'.
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
at org.apache.derby.impl.sql.execute.IndexChanger.insertAndCheckDups(Unknown Source)
at org.apache.derby.impl.sql.execute.IndexChanger.doInsert(Unknown Source)
at org.apache.derby.impl.sql.execute.IndexChanger.insert(Unknown Source)
at org.apache.derby.impl.sql.execute.IndexSetChanger.insert(Unknown Source)
at org.apache.derby.impl.sql.execute.RowChangerImpl.insertRow(Unknown Source)
at org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(Unknown Source)
at org.apache.derby.impl.sql.execute.InsertResultSet.open(Unknown Source)
at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(Unknown Source)
at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source)
... 45 more
答案 0 :(得分:0)
预准备语句中的参数顺序应与SQL语句中的顺序相同:
String certUpdate = "UPDATE APP.ALUMNUS_HAS_CERT "
+ "SET YEAR_GRADUATED = ? " //1
+ "WHERE ALUMNUS_CK = ? AND CERT_CK = ? "; //2 and 3
try (PreparedStatement stmAlumnusCert = con.prepareStatement(certUpdate) {
stmAlumnusCert.setInt(1,year_graduated);
stmAlumnusCert.setInt(2, certID);
stmAlumnusCert.setInt(3, alumnusID); stmAlumnusCert.executeUpdate();
}
错误的订单可能会在您的表格中创建一个重复的复合键。
PS:问题已更新,此答案不适用。