У вас есть синтаксическая ошибка, замените на:
UPDATE library_students.book SET CopiesInBorrow= ?, AvailableCopies=? WHERE BookID=?
Не используйте AND
между столбцами, которые вы хотите обновить. Вы можете использовать AND
в части WHERE
, чтобы применить необходимые условия.
Если вы хотите что-то вроде этого:
UPDATE library_students.book SET CopiesInBorrow= ? WHERE AvailableCopies=? AND BookID=?
, тогда использование AND
будет допустимым.
Из вашего кода я вижу, что вы просто хотите увеличить значение столбца и уменьшить еще один. Вам не нужно сначала находить эти значения в таблице, а затем вносить изменения.
Вы можете выполнить это утверждение:
UPDATE library_students.book SET CopiesInBorrow = CopiesInBorrow + 1, AvailableCopies = AvailableCopies - 1 WHERE BookID = ?
Так что измените на это:
public void updateFields(BorrowedBook borrowedBook) throws SQLException {
PreparedStatement pstmt;
try {
Statement stmt = con.createStatement();
pstmt = con.prepareStatement("UPDATE library_students.book SET CopiesInBorrow = CopiesInBorrow + 1, AvailableCopies = AvailableCopies - 1 WHERE BookID = ?");
pstmt.setString(1, getBookID(borrowedBook));
pstmt.executeUpdate();
rs.close();
}catch (SQLException ex) {
ex.printStackTrace();
}
}
Обычно, Вы просто используете #if
для определения функции, которую Вы хотите когда в соответствии с определенным компилятором. Если встроенная библиотека не определяет strdup, нет никакой проблемы в определении его самостоятельно (кроме того, если они действительно определяют его в будущем, необходимо будет вынуть его.)
// Only define strdup for platforms that are missing it..
#if COMPILER_XYZ || COMPILER_ABC
char *strdup(const char *)
{
// ....
}
#endif
Вы могли просто использовать макрос как это, этот способ, которым можно использовать старое название, но компоновщик будет видеть другое имя;
char *my_strdup(const char *s) {
char *p = malloc(strlen(s) + 1);
if(p) { strcpy(p, s); }
return p;
}
/* this goes in whatever header defines my_strdup */
char *my_strdup(const char *s);
#define strdup(x) my_strdup(x)
К вашему сведению: я лично никогда не видел среду, которая не определила strdup ().
Необходимо также рассмотреть предотвращение создания любого идентификатора (включая функцию), который начинается с ул. [a-z]. В то время как это не резервируется, стандартный раздел (ISO/IEC 9899:1999) C 7.26.11 (будущие направления библиотеки) состояния "Имена функций, которые начинаются с ул., мадам, или wcs и строчная буква могут быть добавлены к объявлениям в заголовке".
a), Что происходит, когда я пишу свою собственную функцию с тем же именем как встроенная функция?
Вы не можете переопределить функцию, которая уже существует в заголовочном файле, который Вы включительно Это приведет к ошибке компиляции.
b), Что я могу сделать для предотвращения плохих вещей, происходящих со мной на платформах, которые не имеют strdup (), не переписывая весь мой код для не использования strdup (), который просто немного утомителен?
я рекомендовал бы создать Ваше собственное функция обертки к strdup и заменить все Ваши вызовы для использования новой функции обертки. Например:
char *StringDuplicate(const char *s1)
{
#ifdef POSIX
return strdup(s1);
#else
/* Insert your own code here */
#endif
}
Изменение всех Ваших вызовов от strdup до StringDuplicate () должно быть простым, находят и заменяют операцию, делая это выполнимым подходом. Определенная для платформы логика будет затем сохранена в единственном месте вместо того, чтобы быть рассеянной всюду по Вашей кодовой базе.
Поскольку Rob Kennedy отметил, что лучший способ состоит в том, чтобы протестировать в Ваших сценариях здания, если это функционирует, существует или нет. Я знаю, что это довольно легко с автоконфигурацией, но вероятно с другими межплатформенными инструментами сценариев здания, также.
Затем Вы просто помещаете в своем заголовочном файле:
#ifndef HAVE_STRDUP
# ifdef HAVE__STRDUP
# define strdup _strdup
# else
# define strdup my_strdup
# endif
#endif
, Если strdup уже существует на целевой платформе, libc версия используется, если не Ваша пользовательская функция my_strdup будет использоваться.
РЕДАКТИРОВАНИЕ: Я должен был добавить explination, почему это лучше.
Сначала компилятор не связан с существованием функции в libc. Например, возьмите функцию strlcpy
. Это присутствует на FreeBSD, но не на Linux (glibc), хотя оба используют gcc по умолчанию. Или что происходит, если кто-то собирается скомпилировать Ваш код с лязгом?
Если кто-то еще читает это: Не используйте strdup() платформы, даже если он доступен, и не тратьте время/усилия на autoconf/automake только для того, чтобы использовать его. Серьезно, насколько это сложно:
char* mystrdup(const char* str)
{
return strcpy(malloc( strlen(str) + 1),str);
}
Действительно ли это требует #ifdefs? Проверки компилятора? K.I.S.S.