Я пытаюсь добавить хранимую процедуру для моего проекта Java, которая взаимодействует с базой данных MYSQL.
Когда я пытаюсь отредактировать запись отдела в своей базе данных, я получаю код ошибки 1062, в котором говорится, что существует повторяющаяся запись.
После некоторого поиска становится ясно, что ошибка связана с тем, что DepartmentName является уникальным полем.
Не знаю, как решить эту проблему, так как онлайн-решения мне не помогли.
До сих пор я отключал режим сохранения и пытался добавить оператор IGNORE между UPDATE и отделом, но это просто неправильно заставляло бы новую запись в позиции 1 таблицы (перезаписывая все, что там было).
Предположим, что моя база данных содержит следующие данные:
DID - departmentName
3 - Basketball
1 - CS
2 - English
Если в таблице отделов я хочу изменить имя отдела в DID 1 на Math. Это даст мне это сообщение об ошибке, если я использую новую хранимую процедуру, которую я создал. Тем не менее, это прекрасно работает с моим ручным вызовом базы данных из Java.
(Код ошибки)
07:50:09 вызов piercecollege.updateDepartment(1, «Математика») Код ошибки: 1062. Дублирующаяся запись «Математика» для ключа «departmentName_UNIQUE» 0,062 сек.
(MYSQL workbench procedure)
CREATE DEFINER=`autofakt5`@`%` PROCEDURE `updateDepartment`(
IN dID int,
IN dName varchar(45)
)
BEGIN
UPDATE department
SET
departmentName = dName
WHERE DID = dID;
END
CREATE TABLE `department` (
`DID` int(11) NOT NULL,
`departmentName` varchar(45) NOT NULL,
PRIMARY KEY (`DID`),
UNIQUE KEY `DID_UNIQUE` (`DID`),
UNIQUE KEY `departmentName_UNIQUE` (`departmentName`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Это моя хранимая процедура
(Stored Procedure call in JAVA)
public void updateDepartmentMYSQL(Department temp) {
Connection conn = null;
try {
conn = getConnection();
} catch (SQLException e2) {
System.out.println("ERROR: Could not connect to the database");
e2.printStackTrace();
return;
}
CallableStatement statement = null;
try {
int dID = temp.getDID();
String dName = temp.getDepartmentName();
statement = (CallableStatement) conn.prepareCall("{call
updateDepartment("
+String.valueOf(dID) +",'" + dName +"')}");
System.out.println(statement);
statement.execute();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Который заменил собой этот рабочий ручной вызов базы данных.
public void updateDepartmentMYSQLREPLACED(Department editedDepartment) { //replaced with procedure
Connection conn = null;
try {
conn = getConnection();
} catch (SQLException e2) {
System.out.println("ERROR: Could not connect to the database");
e2.printStackTrace();
return;
}
Statement stmt = null;
try {
stmt = conn.createStatement();
} catch (SQLException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
}
String sqlStatement = "UPDATE department " + "SET departmentName = '" + editedDepartment.getDepartmentName()
+ "' " + "WHERE DID = " + String.valueOf(editedDepartment.getDID()) + ";";
System.out.println(sqlStatement);
int rows = 0;
try {
rows = stmt.executeUpdate(sqlStatement);
} catch (SQLException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
System.out.println(rows + " row(s) added to the table.");
try {
conn.close();
} catch (SQLException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
}
Пожалуйста, добавьте определение таблицы в виде текста к вопросу.
Я добавил оператор Create Table. Это тоже считается определением?
Я не понимаю, в чем проблема, ошибка возникает, как и ожидалось - возможно, для идентификатора, отличного от 1, вы пытаетесь выделить математику из другого идентификатора для id = 1?
Моя программа studentManagement позволяет пользователю вводить название школьного отдела. Как только это будет завершено, эта конкретная процедура должна отредактировать существующую запись отдела, разрешив изменение поля имени отдела (departmentName) в конкретном DID (идентификаторе отдела).
Это бесполезное сообщение об ошибке — не давайте параметрам то же имя, что и столбцам. измените dID на in_dID и измените предложение where на
ГДЕ ДЕЛАЛ = in_dID;
MariaDB [sandbox]> DROP PROCEDURE IF EXISTS P;
Query OK, 0 rows affected (0.174 sec)
MariaDB [sandbox]> DELIMITER $$
MariaDB [sandbox]> CREATE PROCEDURE `P`(
-> IN indID int,
-> IN dName varchar(45)
-> )
-> BEGIN
-> UPDATE t
-> SET Name = dName
-> WHERE DID = indID;
-> end $$
Query OK, 0 rows affected (0.101 sec)
MariaDB [sandbox]> DELIMITER ;
MariaDB [sandbox]>
MariaDB [sandbox]> SELECT * FROM T;
+------+-------------+
| did | name |
+------+-------------+
| 1 | MATHEMATICS |
| 2 | science |
+------+-------------+
2 rows in set (0.001 sec)
MariaDB [sandbox]> CALL P(1,'MATH');
Query OK, 1 row affected (0.025 sec)
MariaDB [sandbox]> SELECT * FROM T;
+------+---------+
| did | name |
+------+---------+
| 1 | MATH |
| 2 | science |
+------+---------+
2 rows in set (0.001 sec)
Да, это исправлено. Большое спасибо. Обычно я никогда не делаю этого с именами переменных, но подумал, что на этот раз я был в безопасности с учетом регистра.
'С модификатором IGNORE оператор обновления не прерывается, даже если во время обновления возникают ошибки. Строки, для которых возникают конфликты дубликатов ключа по уникальному значению ключа, не обновляются».