powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / java code --> sql procedure/function
20 сообщений из 45, страница 2 из 2
java code --> sql procedure/function
    #38837101
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
scofielcl,
если глубина менее 255, - установить системную переменную max_sp_recursion_depth и попробовать рекурсивную функцию
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
delimiter $

create function not_enough(p_code int, p_amount int) /* product code, required amount */
returns int /* 0: enough, 1: not enough */
comment 'recursive'
begin
  declare v_no_more int default 0;
  declare v_result int default 0;
  declare v_code int;
  declare v_amount int;
  
  declare c_compound cursor for 
    select p.code_tool, p.size_tool from product p
    where p.code = p_code and p.type_tool = 1;
    
  declare continue handler for not found set v_no_more = 1;
  
  /* check simple tools */
  if exists (
    select 'x' from product p, tool p
    where p.code = p_code and
        p.type_tool = 0 and 
        t.id = p.code_tool and
        t.size < p.size_tool * p_amount
  ) then 
    return 1; 
  end if;

  /* check compound tools */
  open c_compound;
  loop
    fetch c_compound into v_code, v_amount;
    if v_no_more then leave; end if;
    
    set v_result = not_enough(v_code, v_amount);
    if v_result then leave; end if;
  end loop;
  close c_compound;
  
  return v_result;
  
end$

delimiter ;

...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38837184
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkinaА алгоритм можно сделать таким.

Создаём таблицу для накопления запчастей. Поле ID объявляем уникальным (можно первичным ключом).
Кладём с неё начальную запись.
Организуем цикл.
Получаем и сохраняем в переменной количество записей таблицы.
Вставляем в таблицу записи из исходных данных, связав их соотв. образом с временной и игнорируя дубликаты.
Снова сохраняем в переменной количество записей таблицы.
Продолжаем цикл, пока количества не совпадают. Количество циклюв получится на 1 больше макс. уровня вложенности.
Теперь осталось связать таблицу со второй исходной и вывести результат.

А сколько у вас должно получится циклов всего ?
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38837220
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И что то я не понимаю , почему логику алгоритма из первого поста нельзя реализовать на sql.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38837543
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scofielcl, в мускле нет рекурсивных запросов. Приходится делать процедурами.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38837841
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
но в коде из первого поста нет рекурсии.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38838075
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
scofielclно в коде из первого поста нет рекурсии.Без рекурсии. Почти как в коде из первого поста.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
create function has(item_id int)
returns int
begin
  declare v_result int default 1;
  declare v_no_more int default 0;
  declare v_code int;
  declare v_size int;  
  
  declare queue cursor for
    select item_id code_tool, 1 size_tool from dual
    union all
    select code_tool, size_tool from product
    where code = item_id and type_tool = 1;
    
  declare continue handler for not found set v_no_more = 1;

  
  open queue;
  loop
    fetch queue into v_code, v_size;
    if v_no_more then leave; end if;
    
    if exists (
      select 'x' from product p, tool t
      where p.code = v_code and p.type_tool = 0 and t.id = p.code_tool and 
        p.size_tool * v_size > t.size
    ) then 
      set v_result = 0;
      leave;
    end if;
  end loop;
  close queue;

  return v_result;
end

...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38838291
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Благодарю. сейчас разберу.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841413
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброе утро.

Посмотрел ваш код.

Для такого варианта, он работать не будет. т.к. в запросе queue происходит выборка только узлов второго порядка.

вот дампы

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
--
-- Структура таблицы `product`
--

CREATE TABLE IF NOT EXISTS `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `code` int(11) NOT NULL,
  `type_tool` tinyint(1) NOT NULL,
  `code_tool` int(11) NOT NULL,
  `size_tool` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;

--
-- Дамп данных таблицы `product`
--

INSERT INTO `product` (`id`, `code`, `type_tool`, `code_tool`, `size_tool`) VALUES
(1, 1, 0, 1, 2),
(2, 1, 1, 2, 2),
(4, 2, 0, 2, 1),
(5, 2, 0, 3, 4),
(6, 3, 0, 4, 2),
(7, 2, 1, 3, 1);



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
--
-- Структура таблицы `tool`
--

CREATE TABLE IF NOT EXISTS `tool` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` text NOT NULL,
  `size` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;

--
-- Дамп данных таблицы `tool`
--

INSERT INTO `tool` (`id`, `name`, `size`) VALUES
(1, 'Крылья', 0),
(2, 'Поршневая', 2),
(3, 'Цилиндры', 8),
(4, 'Фильтр для турбины', 5);



т.е. как такового обхода дерева нет.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841552
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> scofielcl:
> Доброе утро.
> Посмотрел ваш код.
> Для такого варианта, он работать не будет. т.к. в запросе queue происходит выборка только узлов второго порядка.
> {skipped}

Согласен.
Но вы же хотели "алгоритма из первого поста". Насколько знаю Жаву, код из первого поста также не обработает узлы "второго порядка". Поправьте, если ошибаюсь.

ЗЫ: 17017347 смотрели ?
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841562
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Алгоритм из 1 поста полноценно обходит дерево.
В первом цикле достается узел и для каждого проверяется наличие комплектующих.
В внутреннем цикле эти самые узлы ложатся в очередь.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841571
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я недосмотрел, правильный алгоритм из первого поста приведен ниже:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
        public boolean has(int itemId) throws SQLException {
            final Queue<CompoundItemRequest> itemsToCheck = new LinkedList<>();
            itemsToCheck.add(new CompoundItemRequest(itemId, 1));

            Connection conn = DriverManager.getConnection(url, properties);
            PreparedStatement insufficientDetails = conn.prepareStatement(
                    "select 1 from product join tool "
                    + " on product.type_tool = 0 and product.code_tool = tool.id "
                    + " where product.code = ? and product.type_tool = 0 and product.size_tool * ? > tool.size");
            PreparedStatement compoundDetails = conn.prepareStatement(
                    "select code_tool, size_tool from product "
                    + " where code = ? and type_tool = 1");
            {
                while (!itemsToCheck.isEmpty()) {
                    final CompoundItemRequest item = itemsToCheck.remove();

                    insufficientDetails.setInt(1, item.itemId);
                    insufficientDetails.setInt(2, item.numberOfItems);
                    try (ResultSet rs = insufficientDetails.executeQuery()) {
                        if (rs.next()) {
                            return false;
                        }
                    }
                    compoundDetails.setInt(1, item.itemId);
                    try (ResultSet rs = compoundDetails.executeQuery()) {
                        while (rs.next()) {
                            itemsToCheck.add(new CompoundItemRequest(rs.getInt("code_tool"), rs.getInt("size_tool") * item.numberOfItems));
                        }
                    }
                }
            }
        
            return true;
        }
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841604
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> scofielcl:
> Я недосмотрел, правильный алгоритм из первого поста приведен ниже:
> {skipped}

Этот алгоритм реализован в 17017347 .
Есть баг(?): не учитывается, что одна простая деталь может входить в состав более чем одной составной.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841611
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
скукотища
Этот алгоритм реализован в 17017347 .
Есть баг(?): не учитывается, что одна простая деталь может входить в состав более чем одной составной.

Тогда необходимо работать в временной таблицей содержащей данные из tool.
И уменьшать соответств. значения. Но я не думаю что тогда возможно будет применить рекурсию.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841618
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> scofielcl:
> Тогда необходимо работать в временной таблицей содержащей данные из tool.
> И уменьшать соответств. значения. Но я не думаю что тогда возможно будет применить рекурсию.

У Вашего кода 17045113 тот же баг(?).
"Багфикс"
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
create function enough(p_code int, p_amount int, p_root int) /* product code, amount, 'root flag' must be 1 */
returns int /* 0: insufficient fonds, 1: enough fonds */
comment 'recursive, creates temporary table `needs`'
begin
  declare v_no_more int default 0;
  declare v_dummy int;
  declare v_code int;
  declare v_amount int;
  
  declare c_compound cursor for 
    select p.code_tool, p.size_tool from product p
    where p.code = p_code and p.type_tool = 1;
    
  declare continue handler for not found set v_no_more = 1;
  
  /* accumulator */
  if p_root then
    drop temporary table if exists needs;
    create temporary table needs(code int, size int) engine=MEMORY;
  end if;
  
  /* process simple tools */
  insert into needs(code, size)
  select p.code_tool, p.size_tool * p_amount
  from product p
  where p.code = p_code and p.type_tool = 0;
  
  /* process compound tools */
  open c_compound;
  loop
    fetch c_compound into v_code, v_amount;
    if v_no_more then leave; end if;
    
    set v_dummy = enough( v_code, v_amount, 0 );
  end loop;
  close c_compound;
  
  /* check tools amount */
  if p_root then
    alter table need add key IDX_CODE(code);
    
    if exists (
      select 'x' 
      from (select code, sum(size) need from needs group by 1) n, tools t
      where t.id = n.code and t.size < n.need
    ) then
      return 0;
    end if;
    
  end if;
   
  return 1;
end

...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841634
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В 17045413 неправильно объявлен курсор. Надо
Код: sql
1.
2.
3.
declare c_compound cursor for 
    select p.code_tool, p.size_tool * p_amount from product p
    where p.code = p_code and p.type_tool = 1;
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841639
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, там тот же баг.

Код: plsql
1.
alter table need add key IDX_CODE(code);



А что такое ?
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841657
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
scofielclДа, там тот же баг.

Код: plsql
1.
alter table need add key IDX_CODE(code);



А что такое ?
ALTER TABLE в документации.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841659
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
needs а не need ?
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841670
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
scofielcl,
сорри, очепятка. Должно быть
Код: plsql
1.
alter table needs add key IDX_CODE(code);

Добавляем индекс в таблицу-накопитель.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38841677
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Благодарю.
...
Рейтинг: 0 / 0
20 сообщений из 45, страница 2 из 2
Форумы / MySQL [игнор отключен] [закрыт для гостей] / java code --> sql procedure/function
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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