Opened 2 years ago

Closed 2 years ago

Last modified 23 months ago

#1046 closed дефект (готово)

при использовании подготовленных запросов prepare() выполняются внутри цикла

Reported by: alx Owned by: Denis_N
Priority: critical Component: БД изделий АДС
Keywords: Cc:

Description

В source:base/accept.php@88:68,84#L65 подготовка запросов выполняется внутри цикла (то есть повторяется столько же раз, сколько раз выполняется запрос). :)

Change History (9)

comment:1 by Denis_N, 2 years ago

Resolution: fixed
Status: newclosed

In 102/base:

Исправлен баг в и-е "Приемка": при использовании подготовленных запросов prepare() выполняются внутри цикла

closes #1046

comment:2 by alx, 2 years ago

Resolution: fixed
Status: closedreopened

Хм... Но ведь стало хуже!

Теперь из цикла вынесен вызов bind_param(), в результате чего в цикле выполняется один и тот же запрос (с одним и тем же серийным номером)! Если раньше код был просто неэффективным, то теперь он еще и работает неправильно!

comment:3 by san, 2 years ago

Priority: majorcritical

in reply to:  2 ; comment:4 by Denis_N, 2 years ago

Replying to alx:

Хм... Но ведь стало хуже!

Теперь из цикла вынесен вызов bind_param(), в результате чего в цикле выполняется один и тот же запрос (с одним и тем же серийным номером)! Если раньше код был просто неэффективным, то теперь он еще и работает неправильно!

Здравствуйте, Алексей. Нет, код работает. Вызов bind_param() указан перед циклом, и подставляет значение из переменной $str к подготовленному запросу, а вызов execute() выполняется внутри цикла. Если перед вызовом execute() в цикле изменяется значение $str, то в отправляемый запрос каждый раз подставляется измененное значение $str. Что, собственно говоря, и происходит. В конце цикла $str увеличивается ($str++)

Не заметил еще один цикл, в котором выполняется подготовка запросов и присваивание параметров. Исправил в r107/base

Last edited 2 years ago by Denis_N (previous) (diff)

in reply to:  4 comment:5 by alx, 2 years ago

Resolution: готово
Status: reopenedclosed

Replying to Denis_N:

Здравствуйте, Алексей. Нет, код работает. Вызов bind_param() указан перед циклом, и подставляет значение из переменной $str к подготовленному запросу, а вызов execute() выполняется внутри цикла. Если перед вызовом execute() в цикле изменяется значение $str, то в отправляемый запрос каждый раз подставляется измененное значение $str. Что, собственно говоря, и происходит. В конце цикла $str увеличивается ($str++)

А, действительно. Я упустил в описании, что bind_params привязывает ссылки на значения, а не сами значения.

comment:6 by alx, 2 years ago

Раз уж я все равно влез в эту тему, у меня вопрос. Насколько я понял, в этом интерфейсе пользователь задает диапазон серийных номеров, которые он хочет присвоить платам, сервер проверяет, свободны ли они, и если да, добавляет записи с этими номерами, а если нет, возвращает ошибку.

Вопрос: не было бы проще, удобнее и логичнее, если бы сервер просто выдавал нужное количество еще не использованных номеров? Не все ли равно пользователю, какой номер будет присвоен только что изготовленной плате? Тогда ему достаточно указать количество плат, и сразу получить на выходе их серийные номера...

comment:7 by san, 2 years ago

Тут интерфейс базы подстраивается под реальность.
Уже который год серийные номера изделий на год печатаются заранее большим тиражом(наверное так выгоднее).
Поэтому пользователю удобнее наклеить на плату номера которые у него в руке, а потом ввести их в базу, чем искать среди рулонов наклеек те которые ему назначит сервер.

comment:8 by alx, 23 months ago

Спасибо за разъяснение.

Тогда еще один вопрос по алгоритму. Насколько я вижу, сначала в цикле выполняется SELECT каждого серийного номера из products только чтобы проверить, есть он там или нет. А потом уже в другом цикле выполняется добавление записей в таблицу. Вопрос: зачем нужны эти предварительные SELECT'ы, если столбец serial объявлен UNIQUE? СУБД и так не позволит добавить запись в таблицу, если запрошенный серийный номер в ней уже есть...

comment:9 by san, 23 months ago

milestone: 1 очередь

Milestone deleted

Note: See TracTickets for help on using tickets.