powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / java code --> sql procedure/function
45 сообщений из 45, показаны все 2 страниц
java code --> sql procedure/function
    #38836088
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.

Структура таблицы:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
    -- Структура таблицы `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=6 ;
     
    -- Структура таблицы `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=4 ;







Поле type_tool принимает 0 или 1 (запчасть из tool / продукт из product).
Поле code_tool код запчасти / продукта.
Поле size_tool количество.

Достаточно ли запчастей для сборки самолета ? т.е. необходимо обойти дерево.



Имею такой код на java, пытаюсь сделать то же самое на sql.

Код: 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");
   
                compoundDetails.setInt(1, itemId);  
                try (ResultSet rs = compoundDetails.executeQuery()) {
                        while (rs.next())
                            itemsToCheck.add(new CompoundItemRequest(rs.getInt("code_tool"), rs.getInt("size_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;
                        
                    }
                }     
                
            
            return true;
        }

Возможно ли сделать рекурсивно/нерекурсивно  ?
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836101
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В MySQL нет рекурсии. Посему придётся разворачивать дерево из таблицы product в рамках, например, хранимой процедуры, накапливая итоги во временной таблице. После завершения к ней привязываете к полученной таблице таблицу tool и получаете конечный результат.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836131
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Благодарю, результаты выложу.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836367
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что то подобное, но необходимо переделать на с sql-е курсоры и циклы.

Код: 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.
DROP TEMPORARY TABLE IF EXISTS `b`;
DROP TEMPORARY TABLE IF EXISTS `c`;
DROP TEMPORARY TABLE IF EXISTS `d`;
DROP TEMPORARY TABLE IF EXISTS `e`;

/*В b храним все узлы дерева , т.е. все записи где type_tool = 1 */
CREATE TEMPORARY TABLE `b` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*с всегда содержит единственную запись*/
CREATE TEMPORARY TABLE `c` (`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*В d хранятся результаты запроса с использованием данных из с */
CREATE TEMPORARY TABLE `d` (`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*В е хранятся подузлы каждого узла,чтоб добавить их в b */
CREATE TEMPORARY TABLE `e` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);


b =  INSERT INTO `b` (id,code,size_tool) VALUE (0,id_search,1);


   while(b != null){

    c = select min(`code`),`size_tool` from b group by `id`;
    "delet from `b` where `code` = min(`code`) group by `id`;"

    d = select 1 from product join tool on product.type_tool = 0 and product.code_tool = tool.id where product.code = c.code and product.type_tool = 0 and product.size_tool * c.size_tool > too.size;
    if(d != 0)return 0;

e = select `id`, `code_tool`,`size_tool` from product where `code` = c.code and type_tool = 1;

 while(e != null)b+=e.next();

}
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836378
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.
DROP TEMPORARY TABLE IF EXISTS `b`;
DROP TEMPORARY TABLE IF EXISTS `c`;
DROP TEMPORARY TABLE IF EXISTS `d`;


/*В b храним все узлы дерева , т.е. все записи где type_tool = 1 */
CREATE TEMPORARY TABLE `b` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*в с всегда будет только одна запись*/
CREATE TEMPORARY TABLE `c` (`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*В d хранятся результаты запроса с использованием данных из с */
CREATE TEMPORARY TABLE `d` (`code` int(11) NOT NULL);

 INSERT INTO `b` (id,code,size_tool) VALUE (0,id_search,1);

   while(b != null){

    "insert into c (`code`, `size_tool`) select min(`code`),`size_tool` from b group by `id`;"
    "delet from `b` where `code` = min(`code`) group by `id`;"

    "insert into d (`code`) select 1 from product join tool on product.type_tool = 0 and product.code_tool = tool.id where product.code = c.code and product.type_tool = 0 and product.size_tool * c.size_tool > too.size;"
    if(d != 0)return 0;

    "insert into b (`id`,`code_tool`,`size_tool`)select `id`, `code_tool`,`size_tool` from product where `code` = c.code and type_tool = 1;"

}
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836629
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.
DROP TEMPORARY TABLE IF EXISTS `b`;
DROP TEMPORARY TABLE IF EXISTS `c`;
DROP TEMPORARY TABLE IF EXISTS `d`;


/*В b храним все узлы дерева , т.е. все записи где type_tool = 1 */
CREATE TEMPORARY TABLE `b` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*в с всегда будет только одна запись*/
CREATE TEMPORARY TABLE `c` (`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*В d хранятся результаты запроса с использованием данных из с */
CREATE TEMPORARY TABLE `d` (`code` int(11) NOT NULL);

 INSERT INTO `b` (id,code,size_tool) VALUE (0,id_search,1);

   while(b != null){

    "insert into c (`code`, `size_tool`) select min(`code`),`size_tool` from b group by `code`;"

    "delet from `b` order by `code` limit 1;

    "insert into d (`code`) select 1 from product join tool on product.type_tool = 0 and product.code_tool = tool.id where product.code = c.code and product.type_tool = 0 and product.size_tool * c.size_tool > too.size;"
    if(d != 0)return 0;

    "insert into b (`id`,`code_tool`,`size_tool`)select `id`, `code_tool`,`size_tool` from product where `code` = c.code and type_tool = 1;"

}
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836639
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.
36.
DROP TEMPORARY TABLE IF EXISTS `b`;
DROP TEMPORARY TABLE IF EXISTS `c`;
DROP TEMPORARY TABLE IF EXISTS `d`;

DECLARE @tmpb,@tmpd INT DEFAULT 1;

/*В b храним все узлы дерева , т.е. все записи где type_tool = 1 */
CREATE TEMPORARY TABLE `b` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*в с всегда будет только одна запись*/
CREATE TEMPORARY TABLE `c` (`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*В d хранятся результаты запроса с использованием данных из с */
CREATE TEMPORARY TABLE `d` (`code` int(11) NOT NULL);

 INSERT INTO `b` (id,code,size_tool) VALUE (0,id_search,1);

   while(tmpb != 0){
     
     SET @tmpb := (SELECT COUNT(*) FROM `b`);
     SELECT @tmpb;

    "insert into c (`code`, `size_tool`) select min(`code`),`size_tool` from b group by `code`;"

    "delet from `b` order by `code` limit 1;

    "insert into d (`code`) select 1 from product join tool on product.type_tool = 0 and product.code_tool = tool.id where product.code = c.code and product.type_tool = 0 and product.size_tool * c.size_tool > too.size;"
     
     SET @tmpd := (SELECT COUNT(*) FROM `d`);
     SELECT @tmpd;

    if(tmpd != 0)return false;

    "insert into b (`id`,`code_tool`,`size_tool`)select `id`, `code_tool`,`size_tool` from product where `code` = c.code and type_tool = 1;"

}

return true;
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836650
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Но данный код не рабочий.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836827
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну надо как минимум приводить копию кода, а не вольные раасуждения на тему. Что там за кавычки лишние?
Что вообще за логика реализуется кодом - я, например, в этой каше разобраться не могу...
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836833
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Копию кода я приложил. это и есть внутренность процедуры которую я хочу написать.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836834
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
т.е. я попробовал реализовать тот же алгоритм что и на ява в 1-ом посте.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836858
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scofielcl
Код: plsql
1.
select min(`code`),`size_tool` from b group by `code`

шта?
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836865
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaЧто вообще за логика реализуется кодомятакду, получить состав изделия, т.е. найти всех потомков определённой записи (потомков записи с заданным кодом и type_tool=1)
scofielcl, сюда загляните 13675569
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836874
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglir , я тожтакду... но реализация...
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836879
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglirscofielcl
Код: plsql
1.
select min(`code`),`size_tool` from b group by `code`

шта?

грубый набросок, не имеющий ничего общего с действительностью.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836892
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.
DROP TEMPORARY TABLE IF EXISTS `b`;
DROP TEMPORARY TABLE IF EXISTS `c`;

DECLARE @tmpb,@tmpd INT DEFAULT 1;

/*В b храним все узлы дерева , т.е. все записи где type_tool = 1 */
CREATE TEMPORARY TABLE `b` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*в с всегда будет только одна запись*/
CREATE TEMPORARY TABLE `c` (`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);

 INSERT INTO `b` (id,code,size_tool) VALUE (0,id_search,1);

   while(tmpb != 0){
     
     SET @tmpb := (SELECT COUNT(*) FROM `b`);
     SELECT @tmpb;

    "insert into c (`code`, `size_tool`) select min(`code`),`size_tool` from b order by `code`;"

    "delet from `b` order by `code` limit 1;

    SET @tmpd := select 1 from product join tool on product.type_tool = 0 and product.code_tool = tool.id where product.code = c.code and product.type_tool = 0 and product.size_tool * c.size_tool > too.size;
     
    if(tmpd != 0)return false;

    "insert into b (`id`,`code_tool`,`size_tool`)select `id`, `code_tool`,`size_tool` from product where `code` = c.code and type_tool = 1;"

}

return true;
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836915
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забаная подсветка - ажно шесть строк красным - не наталкивает ни на какие мысли, да?
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836920
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну синтаксис и логика довольно разные понятие, на верность синтаксиса я и не расчитываю.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836923
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока синтаксис неверен - логику проверить невозможно. Да и бессмысленно - всё равно код будет изменён.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836932
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.
DROP TEMPORARY TABLE IF EXISTS `b`;
DROP TEMPORARY TABLE IF EXISTS `c`;

DECLARE @tmpb,@tmpd INT DEFAULT 1;

/*В b храним все узлы дерева , т.е. все записи где type_tool = 1 */
CREATE TEMPORARY TABLE `b` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);
/*в с всегда будет только одна запись*/
CREATE TEMPORARY TABLE `c` (`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);

 INSERT INTO `b` (id,code,size_tool) VALUE (0,id_search,1);

   while(tmpb != 0){
     
     SET @tmpb := (SELECT COUNT(*) FROM `b`);
     SELECT @tmpb;

    insert into c (`code`, `size_tool`) select min(`code`),`size_tool` from b order by `code`;

    delet from `b` order by `code` limit 1;

    SET @tmpd := select 1 from product join tool on product.type_tool = 0 and product.code_tool = tool.id where product.code = c.code and product.type_tool = 0 and product.size_tool * c.size_tool > too.size;
     
    if(tmpd != 0)return false;

    insert into b (`id`,`code_tool`,`size_tool`)select `id`, `code_tool`,`size_tool` from product where `code` = c.code and type_tool = 1;

}

return true;
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836942
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.
DROP TEMPORARY TABLE IF EXISTS `b`;

DECLARE @tmpb,@tmpd INT DEFAULT 1;
DECLARE @code,@size_tool INT DEFAULT 1;

/*В b храним все узлы дерева , т.е. все записи где type_tool = 1 */
CREATE TEMPORARY TABLE `b` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int(11) NOT NULL,`size_tool` int(11) NOT NULL);

 INSERT INTO `b` (id,code,size_tool) VALUE (0,id_search,1);

   while(tmpb != 0){
     
    SET @tmpb := (SELECT COUNT(*) FROM `b`);

    SET @code := select `code` from b order by `code` limit 1;
    SET @size_tool := select `size_tool` from b order by `code` limit 1;

    Delet from `b` order by `code` limit 1;

    SET @tmpd := select 1 from product join tool on product.type_tool = 0 and product.code_tool = tool.id where product.code = @code and product.type_tool = 0 and product.size_tool * @size_tool > tool.size;
     
    if(tmpd != 0)return false;

    Insert into b (`id`,`code_tool`,`size_tool`)select `id`, `code_tool`,`size_tool` from product where `code` = @code and type_tool = 1;

}

return true;
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38836970
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
scofielcl,
максимальная глубина дерева ограничена ?
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38837032
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это вообще на каком языке написано? фигурные скобки и прочие неизвестные серверу MySQL конструкции...
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38837042
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А алгоритм можно сделать таким.

Создаём таблицу для накопления запчастей. Поле ID объявляем уникальным (можно первичным ключом).
Кладём с неё начальную запись.
Организуем цикл.
Получаем и сохраняем в переменной количество записей таблицы.
Вставляем в таблицу записи из исходных данных, связав их соотв. образом с временной и игнорируя дубликаты.
Снова сохраняем в переменной количество записей таблицы.
Продолжаем цикл, пока количества не совпадают. Количество циклюв получится на 1 больше макс. уровня вложенности.
Теперь осталось связать таблицу со второй исходной и вывести результат.
...
Рейтинг: 0 / 0
java code --> sql procedure/function
    #38837067
scofielcl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сейчас буду пробовать. Глубина ограничена.
...
Рейтинг: 0 / 0
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
45 сообщений из 45, показаны все 2 страниц
Форумы / MySQL [игнор отключен] [закрыт для гостей] / java code --> sql procedure/function
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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