Как мне добиться результата вызова check_shipments;

Здравствуйте, я хочу добиться результата вызова check_shipments;

Как мне добиться результата вызова check_shipments;

Определения таблицы:

Как мне добиться результата вызова check_shipments;

Как мне выполнить указанную хранимую процедуру с помощью курсоров, используя этот код: Подскажите, пожалуйста, что мне изменить в коде?

DELIMITER $$

CREATE PROCEDURE check_shipments()
BEGIN
DECLARE no_more_products int DEFAULT 0;
DECLARE p_id int DEFAULT 0;
DECLARE ship_times int DEFAULT 0;
DECLARE cur_shipments CURSOR FOR
    SELECT prod_id FROM shipments;
DECLARE CONTINUE HANDLER FOR NOT FOUND
    SET no_more_products = 1;
CREATE table IF NOT EXISTS products_Info(prod_id int, prod_shipments int);
OPEN cur_shipments;
FETCH cur_shipments INTO p_id;
REPEAT
    SELECT count(prod_id) INTO ship_times FROM shipments where prod_id = p_id;
    IF ship_times > 0 THEN
        INSERT INTO products_Info VALUES(p_id, ship_times);
    END IF;
    FETCH cur_shipments INTO p_id;
UNTIL no_more_products = 1 END REPEAT;
CLOSE cur_shipments;
SELECT * FROM products_Info;
drop table products_Info;
END $$

DELIMITER ;

Но результат моей хранимой процедуры таков:

Как мне добиться результата вызова check_shipments;

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

опубликуйте определения таблиц и образцы данных, а также требуемый вывод КАК ТЕКСТ

Kendle 23.03.2022 08:10

Мы не работаем с фотографиями. meta.stackoverflow.com/questions/333952/…

Akina 23.03.2022 08:11

@Kendle Я добавил определения таблиц

Giniatsu 23.03.2022 08:17

Вы снова добавляете фотографии. Вы хотите, чтобы мы распознали кодовый текст? Опубликуйте все это как хорошо отформатированный текстовый код SQL и таблицы. Определение таблицы должно быть предоставлено как CREATE TABLE, пример данных как INSERT INTO.

Akina 23.03.2022 08:19

Не используйте REPEAT в SP - неудобно. Используйте оператор LOOP и IF [flag | condition] THEN LEAVE LOOP. Это позволяет вам иметь много точек выхода с различными используемыми условиями выхода (например, обнаруженными разными обработчиками или явными условными операторами). В вашем случае это также позволяет иметь только один оператор FETCH.

Akina 23.03.2022 08:24
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
5
36
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Для этого не нужна процедура. Запрос с count() и предложением group by даст вам то, что вы хотите:

SELECT prod_id, count(prod_id) as prod_shipments 
  FROM shipments 
  group by prod_id 
  order by prod_id;

Результат:

prod_idprod_shipments
13
22

Что мне нужно, так это хранимая процедура и курсоры, потому что я все еще учусь, можете ли вы тогда проверить мою хранимую процедуру?

Giniatsu 23.03.2022 08:16
Ответ принят как подходящий

Мы хотим подсчитать количество строк с каждым идентификатором, поэтому мы используем

 INSERT INTO products_Info VALUES(p_id, 1)
>                ON DUPLICATE KEY UPDATE 
>                prod_shipments = prod_shipments + 1;
DELIMITER $$ 

CREATE PROCEDURE check_shipments()
BEGIN
DECLARE no_more_products int DEFAULT 0;
DECLARE p_id int DEFAULT 0;
DECLARE ship_times int DEFAULT 0;
DECLARE cur_shipments CURSOR FOR
    SELECT prod_id FROM shipments;
DECLARE CONTINUE HANDLER FOR NOT FOUND
    SET no_more_products = 1;
CREATE table IF NOT EXISTS products_Info(
       prod_id int primary key, 
       prod_shipments int);
OPEN cur_shipments;
FETCH cur_shipments INTO p_id;
REPEAT
    SELECT count(prod_id) INTO ship_times FROM shipments where prod_id = p_id;
    IF ship_times > 0 THEN
        INSERT INTO products_Info VALUES(p_id, 1)
           ON DUPLICATE KEY UPDATE 
           prod_shipments = prod_shipments + 1;
    END IF;
    FETCH cur_shipments INTO p_id;
UNTIL no_more_products = 1 END REPEAT;
CLOSE cur_shipments;
SELECT * FROM products_Info;
drop table products_Info;
END $$

DELIMITER ;
call check_shipments
prod_id | prod_shipments
------: | -------------:
      1 |              3
      2 |              2

дб <> рабочий пример здесь

ОБЪЯВИТЬ cur_shipments КУРСОР ДЛЯ ВЫБЕРИТЕ prod_id ИЗ отправлений;

загружает 5 строк в курсор, вы выполняете цикл 4 раза, но вставляете 5 раз, потому что первая выборка находится вне цикла и поскольку в pid нет первичного/уникального ключа, вставляются 5 строк.

Вы могли

ОБЪЯВИТЬ cur_shipments КУРСОР ДЛЯ ВЫБЕРИТЕ ОТЛИЧНЫЕ prod_id ОТ отгрузок;

поэтому курсор содержит только 2 строки

или

добавить первичный ключ к отгрузке продуктов, удалить оператор select (count)... и изменить вставку на вставку в дублирующем ключе

 REPEAT
    
                INSERT INTO products_Info(prod_id ,prod_shipments) VALUES(p_id, 1)
    ON DUPLICATE key update prod_shipments = prod_shipments + 1;
    
        FETCH cur_shipments INTO p_id;
    UNTIL no_more_products = 1 END REPEAT;

я попробую этот

Giniatsu 23.03.2022 09:26

Другие вопросы по теме