powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / multi insert and where select nodejs
25 сообщений из 34, страница 1 из 2
multi insert and where select nodejs
    #40016196
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день уважаемые форумчане!

Входные данные: Клиент передает на сервер json oбъект который содержит в себе массив вида (id, quantity, price)

Моя функция для того чтоб сделать insert этого массива в db:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
    static addSale(products){

        //WHERE (SELECT stock FROM prais_informations WHERE code = ) > 20;
        let quer = 'INSERT INTO `sales` (`id`, `code`, `quantity`, `price`, `sum`, `idCheck`) VALUES ?;';            

        return new Promise((resolve, reject) => {
           
        pool.getConnection((err, connection) => {
            if (err)reject(err);
            
            connection.query(quer, [products.map(item => [null, item.id, item.quantity, item.price, item.sum, 3])], (err, rows) => {
                 if (err) {
                    reject(err);
                }

                resolve(rows);
                connection.release();
            });
        });
     });
    }



Вопрос в следующем, прежде чем сделать инсерт всех строк, нужно проверить не превышает ли количество в запросе, остаток в бд, если хотя бы одна строка не удовлетворяет условию, запрос не должен быть сделан.

Я вижу три способа:

1. Доделать запрос до вида:
Код: sql
1.
INSERT INTO `sales` (`id`, `code`, `quantity`, `price`, `sum`, `idCheck`) VALUES ? WHERE (SELECT stock FROM prais_informations WHERE code = ? ) >= ?; 


2. Создать еще одну функцию, в которую передать входящий массив и вернуть true/false (т.е. разделить запрос на две части)

3. Написать процедуру в самой БД которая и будет обрабатывать входящий массив и возвращать ответ.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016198
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
it_crb29
Код: sql
1.
VALUES ? WHERE

Так не бывает. Бывает INSERT ... SELECT ...
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016199
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я за то, чтобы делать одним запросом. В противном случае возможны трудноуловимые глюки из-за конкурентных сессий.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016200
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,
что о вроде этого:
Код: sql
1.
2.
3.
insert into orders (product_id, qty)
select 2, 20
where (SELECT qty_on_hand FROM products WHERE id = 2) > 20;
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016201
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
it_crb29,

Да, что-то вроде этого.
Только я бы еще предложил все вставляемые записи в один запрос поместить.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016202
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

так они и так ведь упаковываются в один запрос, т.е. получается что то вроде:

Код: sql
1.
2.
3.
4.
5.
INSERT into orders (product_id, qty)
VALUES (2, 10, 100), ..., (id, qty, price)
WHERE (SELECT qty_on_hand FROM products WHERE id = 2) > 20 
AND (SELECT qty_on_hand FROM products WHERE id = 3) > 30 
AND (SELECT qty_on_hand FROM products WHERE id = 4) > 40;
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016203
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
it_crb29
так они и так ведь упаковываются в один запрос
Возможно, не спорю. Просто показанный код мне понятен только в SQL-части.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016204
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

Буду думать как к каждому фрагменту insert приделать условие
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016205
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
it_crb29
miksoft,

Буду думать как к каждому фрагменту insert приделать условие
Зачем? Вам же нужно "если хотя бы одна строка не удовлетворяет условию, запрос не должен быть сделан". Это у вас уже есть.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016206
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

вот это пример с mysqltutorial:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
// insert statment
let stmt = `INSERT INTO sales(`id`, `code`, `quantity`, `price`, `sum`, `idCheck`)  VALUES ?  `;

let todos = [
  [null, id, quantity, price, sum],
  [null, id1, quantity1, price1, sum1],
  [null, id2, quantity2, price2, sum2],
];

// execute the insert statment
connection.query(stmt, [todos], (err, results, fields) => {
  if (err) {
    return console.error(err.message);
  }
  // get inserted rows
  console.log('Row inserted:' + results.affectedRows);
});



Если бы это быа строка, тогда все ясно, но здесь массив.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016247
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
it_crb29,

Если у вас уже есть массив записей (т.е. таблица), вам осталось преобразовать его в тип recordset* и обращаться с ним как с SQL таблицей, с которой вы уже знакомы.

Я плохо знаком с MySQL, в Оракл это преобразование выглядело бы так: TABLE(todos).

После этого работают SQL команды: "select * from TABLE(todos) where..."

В вашем примере, в котором я понял вы хотите оформить заказ продаж на товары в наличии (верно?)
В передаваемом массиве содержится один заказ на все товары, что желает покупатель.
Когда товаров много, все понятно.

Что должно случиться, когда товара не хватает по одной позиции? Наверное, один из трех:
1) весь заказ отменяется
2) заказ выполняется по другим позициям, отменяется часть по дефициту
3) заказ выполняется максимально, с уменьшенными количествами по дефициту
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016249
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL,

да, все верно. В моем случае, заказ не должен быть выполнен, запрос не должен быть выполнен.

Я полагаю, учитывая, к сожалению, мой скромные познания в sql, что дополнить надлежащим образом нижеследующий запрос невозможно и для решения проблемы нужно или

1 . Писать еще одну функцию, которая сравнит передаваемое количество с остатком для каждого поля заказа и вернет промис.
2 . Сделать все это в процедуре.

Код: sql
1.
2.
3.
4.
5.
6.
7.
1
INSERT INTO `sales` (`id`, `code`, `quantity`, `price`, `sum`, `idCheck`)
VALUES
(null, item.id, item.quantity, item.price, item.sum, 3),
(null, item.id, item.quantity, item.price, item.sum, 3)
, ... ,
(null, item.id, item.quantity, item.price, item.sum, 3);
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016250
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
it_crb29,

используя синтакс TABLE(todos), я бы написал что-то такое:

Код: sql
1.
2.
3.
4.
5.
6.
7.
select count(*) into n 
  from TABLE(todos) d
  join products p on d.product_id = p.id
 group by d.product_id
having sum(d.qty) > p.qty_on_hand;

  if n > 0 ... отмена заказа



Вы умеете читать/писать SQL джойны? Они тут нужны, чтобы связать запрос с таблицей товаров, где находится их количество.
"group" я добавил на тот случай, если в JSON объекте есть повторения товаров, например клиент-филолог заказал четыре кочерги, а потом еще две в отдельной строчке.

Это простая часть - проверка на достаточное наличие товара.
Учтите, что в многопользовательском режиме два заказа могут появиться одновременно, и каждый выполним,
но на оба заказа товара не хватит. Если сначала проверить на присутствие товара, а потом вычитать из инвентаря, можно уйти в минус.

Чтобы такого не случилось, нужно или применить логику резерваций (одновременно с проверкой на наличие вычитается товар из инвентаря), или применить строгую очередность заказов, где следующий заказ не может появиться пока не закончился предыдущий.

Для максимальной скорости исполнения заказов, первый подход лучше. Я предпочитаю второй подход для моих неторопливых задач, т.к. первый сложнее в исполнении, и требует бОльшего опыта для безошибочной реализации, чем сейчас у меня есть.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016253
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL,

LEFT JOIN умею, завтра займусь, спасибо за ответы.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016312
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Если у вас уже есть массив записей (т.е. таблица), вам осталось преобразовать его в тип recordset* и обращаться с ним как с SQL таблицей, с которой вы уже знакомы.

Я плохо знаком с MySQL, в Оракл это преобразование выглядело бы так: TABLE(todos).
В MySQL нет ни массивов, ни конструкций вида TABLE(todos).
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016504
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

Не придумал ничего умнее чем в цикле создать запрос вида

Код: sql
1.
2.
3.
SELECT true WHERE (SELECT prais_informations.stock FROM prais_informations WHERE prais_informations.code = 1 LIMIT 1) > 7 
UNION
SELECT true WHERE (SELECT prais_informations.stock FROM prais_informations WHERE prais_informations.code = 2 LIMIT 1) > 3



вернуть промис и на основе ответа делать/не делать запрос insert.

П.С. Выглядит убого.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016513
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
it_crb29,

П.С, пошел смотреть продвинутый курс по mysql, бех этих знаний не обойтись.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016537
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
it_crb29 , что-то Вы явно не то делаете. Теоретически нужно просто передать объект на MySQL как есть, а там его распарсить и разложить по клеточкам.

it_crb29
Входные данные: Клиент передает на сервер json oбъект который содержит в себе массив вида (id, quantity, price)

it_crb29
сделать insert этого массива в db

Выложите:
1. Пример JSON-объекта в том виде, в каком он поступает от клиента (3-4 записи достаточно).
2. CREATE TABLE таблицы-приёмника, в которую нужно поместить эти данные, и, если в зависимости от данных в JSON могут потребоваться как INSERT, так и UPDATE, дополнительно INSERT INTO 2-3 уже имеющихся записей.
3. Итоговый результат, который требуется получить (таблицей).
4. Точную версию MySQL.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016552
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

1. C клиента приходит:
Код: javascript
1.
2.
3.
4.
sales:  [
  { id: 2, quantity: 5, price: 123, sum: 615 },
  { id: 1, quantity: 9, price: 97, sum: 873 }
]



2. sales : таблица в которую просто идет запись(тот самый мульти инсерт, c этой таблицей ничего сравнивать не нужно, в неё только запись)

table sales

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE TABLE `sales` (
  `id` int UNSIGNED NOT NULL,
  `code` int UNSIGNED NOT NULL,
  `quantity` mediumint UNSIGNED NOT NULL,
  `price` decimal(7,2) NOT NULL,
  `sum` decimal(8,2) NOT NULL,
  `idCheck` int UNSIGNED NOT NULL,
  `data` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;




3. prais_information AS pi : таблица в которой лежат остатки

Соответственно pi.code === id and pi.stock >= quantity

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE TABLE `prais_informations` (
  `id` mediumint UNSIGNED NOT NULL,
  `code` mediumint UNSIGNED NOT NULL,
  `stock` mediumint UNSIGNED NOT NULL,
  `price` decimal(7,2) NOT NULL,
  `trade_price` decimal(7,2) NOT NULL,
  `group_in_tree` smallint UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



pi

4. mysql: mysql Ver 8.0.22 for Linux on x86_64 (MySQL Community Server - GPL)

5. В итоге записи в sales делаются только тогда когда товара достаточно т.е. pi.stock >= quantity , если хотя бы одного товара не достаточно, ничего не записывается.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016558
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С точки зрения MySQL такой JSON - невалидный.

Надеюсь, преобразовать ЭТО в формат
Код: sql
1.
2.
3.
4.
[
  { "id": 2, "quantity": 5, "price": 123, "sum": 615 },
  { "id": 1, "quantity": 9, "price": 97, "sum": 873 }
]

не составит проблемы?
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016562
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Код: javascript
1.
2.
3.
4.
sales:  [
  { id: 2, quantity: 5, price: 123, sum: 615 },
  { id: 1, quantity: 9, price: 97, sum: 873 }
]



Эти данные у меня приходят на сервер nodejs. C nodejs я преобразую и отправлю на сервер mysql так, как это необходимо.
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016564
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В таблице sales имеются поля code и idCheck , которые NOT NULL и не имеют DEFAULT. В JSON их нет.

Откуда берутся их значения?
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016567
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

id === code, idCheck - на данный момент это пока константа(любое число)

Для удобства, входящие данные можем заменить на:

Код: javascript
1.
2.
3.
4.
[
  { "code": 2, "quantity": 5, "price": 123, "sum": 615 },
  { "code": 1, "quantity": 9, "price": 97, "sum": 873 }
]
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016572
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, любуйтесь и разбирайтесь: fiddle .
...
Рейтинг: 0 / 0
multi insert and where select nodejs
    #40016577
it_crb29
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Ваши sql запросы, как всегда, неотразимы, передавать на mysql server json массив и там его парсить, я даже не знал, что так можно...
Спасибо за пример, я обязательно разберу и буду передавать из nodejs в mysql json, а не готовый мульти запрос.

Однако мой вопрос по сути сводился к следующему: я не могу сделать ни один insert пока не проверю что в pi есть достаточное количество quantity, т.е.
pi.quantuty >= $.quantity

Проще говоря, если на складе чего то не хватает, то заказ не принимается.
...
Рейтинг: 0 / 0
25 сообщений из 34, страница 1 из 2
Форумы / MySQL [игнор отключен] [закрыт для гостей] / multi insert and where select nodejs
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]