Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 07.11.2020, 15:24
Интересующийся
Отправить личное сообщение для andrew76 Посмотреть профиль Найти все сообщения от andrew76
 
Регистрация: 07.11.2020
Сообщений: 16

mysql multi insert
Добрый день уважаемые форумчане!

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

Моя функция для того чтоб сделать insert этого массива в db:

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();
            });
        });
     });
    }


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

Вариант я вижу один, создать дополнительную функцию, которая вернет в промисе AND нескольких селектов (true/false) и в части then уже делать insert запрос.
Ответить с цитированием
  #2 (permalink)  
Старый 07.11.2020, 15:43
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от andrew76
этого массива в db
Это как понимать, если MySQL не имеет такого типа данных? JSON пишется что-ли?
Ответить с цитированием
  #3 (permalink)  
Старый 07.11.2020, 15:50
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,004

Сообщение от laimas
Это как понимать, если MySQL не имеет такого типа данных? JSON пишется что-ли?
скорее всего, используемая библиотека просто втыкает массив на место вопросика, делая запрос с несколькими строками после VALUES, mysql так может
Ответить с цитированием
  #4 (permalink)  
Старый 07.11.2020, 15:53
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Alexandroppolus
mysql так может
Где и в чем так может, в Node? Может быть, я не знаю его и его драйверов.
Ответить с цитированием
  #5 (permalink)  
Старый 07.11.2020, 16:17
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

andrew76,
что с чем сравнивать не знаю, но зачастую отдельного запрос не требуется. Пример простой, если я правильно понял, то нужно типа такого:

"INSERT INTO table (count) SELECT N WHERE (SELECT balance FROM table LIMIT 1) > N"

где N - это вставляемое количество в поле count, balance - это поле остатка в этой же таблице. Тут используется просто поле со значением по умолчанию, для всех, поэтому и LIMIT 1. Если вставка для конкретного ID, то нужно взять для этого ID, но сама вставка при этом, это уже будет обновление. То есть остаток по идее, это уже другая таблица, откуда он и извлекается для ID. Иначе это только ON DUPLICATE KEY UPDATE.

Последний раз редактировалось laimas, 07.11.2020 в 16:22.
Ответить с цитированием
  #6 (permalink)  
Старый 07.11.2020, 20:24
Интересующийся
Отправить личное сообщение для andrew76 Посмотреть профиль Найти все сообщения от andrew76
 
Регистрация: 07.11.2020
Сообщений: 16

Сообщение от laimas Посмотреть сообщение
Это как понимать, если MySQL не имеет такого типа данных? JSON пишется что-ли?
Обмен между клиентом и сервером в формате json, дальше бэкэнд обходит принятый объект map'ом и делает массив, ничего стороннего не используется.
Ответить с цитированием
  #7 (permalink)  
Старый 07.11.2020, 20:25
Интересующийся
Отправить личное сообщение для andrew76 Посмотреть профиль Найти все сообщения от andrew76
 
Регистрация: 07.11.2020
Сообщений: 16

Сообщение от laimas Посмотреть сообщение
Где и в чем так может, в Node? Может быть, я не знаю его и его драйверов.
Вот здесь есть simple example
https://www.mysqltutorial.org/mysql-nodejs/insert/
Ответить с цитированием
  #8 (permalink)  
Старый 07.11.2020, 20:38
Интересующийся
Отправить личное сообщение для andrew76 Посмотреть профиль Найти все сообщения от andrew76
 
Регистрация: 07.11.2020
Сообщений: 16

Сообщение от laimas Посмотреть сообщение
andrew76,
что с чем сравнивать не знаю, но зачастую отдельного запрос не требуется. Пример простой, если я правильно понял, то нужно типа такого:

"INSERT INTO table (count) SELECT N WHERE (SELECT balance FROM table LIMIT 1) > N"

где N - это вставляемое количество в поле count, balance - это поле остатка в этой же таблице. Тут используется просто поле со значением по умолчанию, для всех, поэтому и LIMIT 1. Если вставка для конкретного ID, то нужно взять для этого ID, но сама вставка при этом, это уже будет обновление. То есть остаток по идее, это уже другая таблица, откуда он и извлекается для ID. Иначе это только ON DUPLICATE KEY UPDATE.
Чтобы не быть голословным, вот таблицы:
https://ibb.co/NntTBDr

https://ibb.co/tm4z09n


В функции, которую я представил выше, формируется запрос вида:
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);


Но прежде чем сделать инсерты в `sales` нужно проверить, не превышает ли доступный остаток каждый элемент из VALUES.

1. Мне кажется одним запросом это не сделать, нужно написать новую функцию, которая примет массив, сравнит quantity c balance и вернет промис. Задача довольно типовая, поэтому я и задаюсь вопросом, как это реализовать правильно.

Последний раз редактировалось andrew76, 07.11.2020 в 20:39. Причина: image
Ответить с цитированием
  #9 (permalink)  
Старый 07.11.2020, 21:07
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от andrew76
Вот здесь есть simple example
Вот это "?" называется "неименованные, или позиционные, псевдопеременные". Позиционные потому, что они должны быть указаны в той же последовательности в какой будут в запрос поступать данные. То есть, если вы записываете в базу массив [a, b, c], элементы которого должны попасть соответственно в поля a, b, c таблицы, то в запросе должно быть прописано ?, ?, ?. Где и в каком руководстве вы прочли, то передавая в запрос массив, его можно весь, скопом, привязать к одной псевдопеременной я не знаю. Сам MySQLi этого не делает, это может только драйвер, а есть ли такое в Node не в курсе. В случае если элементы массива будут иметь иной порядок, а вы этого не контролируете, то данные будут записаны не в те поля, и никакой драйвер эту ситуацию не исправит.

Другое дело PDO, в нем есть и именованные псевдопеременные. Не проблема разместить в теле запроса в любом месте :a, :b ... и передать для записи массив [a=> 12, b=> 15] (объект, в случае Node) и проблем не будет никогда. Есть ли в Node поддержка абстракций для работы с БД не в курсе.

А вообще такие запросы выгодно выполнять в случаях например множественной вставки или обновлений. В этом случае запрос подготавливается, проверяется, а затем в него вместо псевдопеременных просто подставляются новые данные.
Ответить с цитированием
  #10 (permalink)  
Старый 07.11.2020, 21:21
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от andrew76
не превышает ли доступный остаток каждый элемент из VALUES
Вдумайтесь в то, что вы написали, и это в контексте вставки в базу. Если "INSERT INTO `sales` (`id`" и при этом его значение указывается null, значит это новая запись, для поля id с автоинкрементом. Так? А если так, у кого нужно проверить значение, если записи как таковой в базе еще не существует?

Можно предполагать, например, это заказ/продажа пишется в таблицу А, то есть информация о неком продукте. Сами продукты описаны в таблице В. Тогда в одном запросе можно обратиться к таблице В, сравнив его остаток со вставляемым значением в таблицу А. Делается это так как я показывал.

Ваше же пояснение ни о чем не говорит, что с чем, откуда это все, не понять.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
textContent,innerHTML \r\n в MySql . Как вывести з Mysql текс з абзацами в Js xxxAsterothxxx jQuery 4 26.11.2019 18:56
nodeJS и mysql vmetnev@mail.ru Node.JS 1 06.09.2019 23:37
MySQL запрос INSERT INTO allonemoon Серверные языки и технологии 1 02.05.2017 05:30
Node.js + mysql mazahist Node.JS 4 17.11.2016 19:07
Как записать JSON объект в mysql таблицу. user71 Node.JS 6 31.07.2016 13:01