Можно ли одним запросом вставить данные в несколько таблиц в PostgreSQL?
У меня есть три таблицы: users, roles и users_roles. Я так понимаю, что нужно вначале вставить данные в самую первую таблицу (users), вернуть ключ записи, и вставить остальные данные с этим ключом. И так же нужно как-то узнавать ключ role и вставить его ключ при добавлении в таблицу users_roles (в этой таблице реализовано отношение многие-ко-многим). Как это можно сделать? Можно ли как-то несколько запросов на добавление поместить в один запрос и в одном методе? (Схему БД прикладываю)
Пока что пробовала реализовать вот так, но так не вышло:
public int insert(String login, String password, String name, int age, String role, int usersid, int rolesid) {
String sqlInsert = "INSERT INTO users (login, password, name, age) VALUES (?, ?, ?, ?)";
try {
Class.forName("org.postgresql.Driver");
try (Connection conn = DriverManager.getConnection(urlDB, usernameDB, passwordDB)) {
try (PreparedStatement preparedStatement = conn.prepareStatement(sqlInsert)) {
preparedStatement.setString(1, login);
preparedStatement.setString(2, password);
preparedStatement.setString(3, name);
preparedStatement.setInt(4, age);
preparedStatement.setString(5, role);
insertUserRole(usersid, rolesid);
return preparedStatement.executeUpdate();
}
}
} catch (Exception ex) {
System.out.println("Connection Failed : " + ex.getMessage());
}
return 0;
}
public int insertUserRole(int usersid, int rolesid) {
String sqlInsert = "INSERT INTO users_roles(usersid, rolesid) VALUES (?, ?)";
try {
Class.forName("org.postgresql.Driver");
try (Connection conn = DriverManager.getConnection(urlDB, usernameDB, passwordDB)) {
try (PreparedStatement preparedStatement = conn.prepareStatement(sqlInsert)) {
preparedStatement.setInt(1, usersid);
preparedStatement.setInt(2, rolesid);
return preparedStatement.executeUpdate();
}
}
} catch (Exception ex) {
System.out.println("Connection Failed : " + ex.getMessage());
}
return 0;
}
Маленький пример вставки в две таблицы одним запросом.
Связанные таблицы:
CREATE TABLE main (id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
val INT);
CREATE TABLE slave (id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
val INT,
main_id INT REFERENCES main (id));
Вставим связанные записи - присвоим val значения 11 и 111 в одной паре связанных записей и 22/222 в другой паре:
WITH cte AS ( INSERT INTO main (val)
VALUES (11), (22)
RETURNING id, val )
INSERT INTO slave (val, main_id)
SELECT CASE val WHEN 11 THEN 111
WHEN 22 THEN 222
END,
id
FROM cte;
DEMO
В CTE выполняется вставка в основную таблицу. Возвращаем оттуда присвоенное значение id
(чтобы заполнить поле связи) и val
(чтобы правильно связать записи). Возвращённые значения используем для правильного связывания.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Подскажите, пожалуйста, для решения задачи из темы подойдет мой код, указанный ниже? Интересует, как решается подобная задача в продакшене
Ошибку получаю при вызове метода, который обращается к БД через SimpleJdbcCall
Всем доброго дня, с Android разработкой только знакомлюсь, прошу не кидать камниРешил в свое приложение интегрировать AppsFlyer SDK для дальнейшего...
Насколько я понял, в объекте a будут доступны только те переменные и методы, которые есть в классе A, но запускаться они будут из класса BНо вот...