#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 , 22 months ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
follow-up: 4 comment:2 by , 22 months ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
Хм... Но ведь стало хуже!
Теперь из цикла вынесен вызов bind_param()
, в результате чего в цикле выполняется один и тот же запрос (с одним и тем же серийным номером)! Если раньше код был просто неэффективным, то теперь он еще и работает неправильно!
comment:3 by , 22 months ago
Priority: | major → critical |
---|
follow-up: 5 comment:4 by , 22 months ago
Replying to alx:
Хм... Но ведь стало хуже!
Теперь из цикла вынесен вызов
bind_param()
, в результате чего в цикле выполняется один и тот же запрос (с одним и тем же серийным номером)! Если раньше код был просто неэффективным, то теперь он еще и работает неправильно!
Здравствуйте, Алексей. Нет, код работает. Вызов bind_param() указан перед циклом, и подставляет значение из переменной $str к подготовленному запросу, а вызов execute() выполняется внутри цикла. Если перед вызовом execute() в цикле изменяется значение $str, то в отправляемый запрос каждый раз подставляется измененное значение $str. Что, собственно говоря, и происходит. В конце цикла $str увеличивается ($str++)
Не заметил еще один цикл, в котором выполняется подготовка запросов и присваивание параметров. Исправил в r107/base
comment:5 by , 22 months ago
Resolution: | → готово |
---|---|
Status: | reopened → closed |
Replying to Denis_N:
Здравствуйте, Алексей. Нет, код работает. Вызов bind_param() указан перед циклом, и подставляет значение из переменной $str к подготовленному запросу, а вызов execute() выполняется внутри цикла. Если перед вызовом execute() в цикле изменяется значение $str, то в отправляемый запрос каждый раз подставляется измененное значение $str. Что, собственно говоря, и происходит. В конце цикла $str увеличивается ($str++)
А, действительно. Я упустил в описании, что bind_params
привязывает ссылки на значения, а не сами значения.
comment:6 by , 22 months ago
Раз уж я все равно влез в эту тему, у меня вопрос. Насколько я понял, в этом интерфейсе пользователь задает диапазон серийных номеров, которые он хочет присвоить платам, сервер проверяет, свободны ли они, и если да, добавляет записи с этими номерами, а если нет, возвращает ошибку.
Вопрос: не было бы проще, удобнее и логичнее, если бы сервер просто выдавал нужное количество еще не использованных номеров? Не все ли равно пользователю, какой номер будет присвоен только что изготовленной плате? Тогда ему достаточно указать количество плат, и сразу получить на выходе их серийные номера...
comment:7 by , 22 months ago
Тут интерфейс базы подстраивается под реальность.
Уже который год серийные номера изделий на год печатаются заранее большим тиражом(наверное так выгоднее).
Поэтому пользователю удобнее наклеить на плату номера которые у него в руке, а потом ввести их в базу, чем искать среди рулонов наклеек те которые ему назначит сервер.
comment:8 by , 22 months ago
Спасибо за разъяснение.
Тогда еще один вопрос по алгоритму. Насколько я вижу, сначала в цикле выполняется SELECT каждого серийного номера из products
только чтобы проверить, есть он там или нет. А потом уже в другом цикле выполняется добавление записей в таблицу. Вопрос: зачем нужны эти предварительные SELECT'ы, если столбец serial
объявлен UNIQUE? СУБД и так не позволит добавить запись в таблицу, если запрошенный серийный номер в ней уже есть...
In 102/base: