powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Проблема с хранимыми процедурами и параметрами
1 сообщений из 1, страница 1 из 1
Проблема с хранимыми процедурами и параметрами
    #38838752
Zvor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток, форумчане!

Такая ситуация - есть ERP-программа для кафе и Mysql-база. В базе есть таблицы, в которых хранятся данные о продажах, позициях меню и расходных материалах, а также о том, сколько нужно какого расходного материала для каждой позиции меню.

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

Хочется чтобы при вызове исключения в процессе работы хранимки откатывались все изменения, сделанные в процессе работы алгоритма.

Собственно проблема: для отлова исключительной ситуации во второй хранимке используется переменная-флаг и если она принимает значение TRUE первая хранимка должна все откатить, но при выполнении почему-то переменная TRUE не принимает.

Первая хранимка

Код: sql
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.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
CREATE DEFINER = 'root'@'%'
PROCEDURE cafedb.Proc_Client_Sell(IN ParamLogin VARCHAR(255), IN ParamShop VARCHAR(255), IN ParamSumm FLOAT, IN ParamPlace INT)
  COMMENT 'Процедура проведения продажи'
BEGIN

  DECLARE VarCheckNo,
          VarItemID,
          VarMenuID,
          VarItemAmount,
          VarItemBonus,
          VarOrderBonus,
          VarSupplyAmount
          int(11);

  DECLARE VarItemPrice,
          VarItemCost,
          VarItemSumm, 
          VarOrderSumm,
          VarOrderCost 
          float;

  DECLARE done, VarErrorSupply INT DEFAULT FALSE;

  DECLARE CheckCursor CURSOR FOR 
     SELECT MenuID, Amount, Summ, Price, Cost FROM sales_stat WHERE SaleID = VarCheckNo; 

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 

  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    ROLLBACK;
    CALL Proc_Log_Update('Error', ParamLogin, CONCAT('Ошибка при продаже на сумму ', ParamSumm, ' чек #', VarCheckNo), ParamShop);
    SELECT
      'Error!';
  END;

    DECLARE EXIT HANDLER FOR SQLSTATE '45000'
  BEGIN
    ROLLBACK;
    CALL Proc_Log_Update('Error', ParamLogin, CONCAT('Ошибка при продаже на сумму ', ParamSumm, ' чек #', VarCheckNo), ParamShop);
    SELECT
      'Error!';
  END;

  SET @RecordNo = 0;
  SET @VarErrorSupply = FALSE;
  
  SET VarOrderCost = 0;
  SET VarOrderBonus = 0;

  START TRANSACTION;

    /* берем номер открытого чека */
  SELECT IndexNo
    FROM sales
   WHERE (Status = 'Открыт')
     AND (sales.Place = ParamPlace)
     AND (DAYOFMONTH(Time) = DAYOFMONTH(CURDATE()))
    INTO VarCheckNo;

  /* Обработка ВСЕХ финансовых параметров */
  OPEN CheckCursor;

  read_loop: LOOP
    /* берем значения переменных */
    FETCH CheckCursor INTO VarMenuID, VarItemAmount, VarItemSumm, VarItemPrice, VarItemCost; 

    /*Выход из курсора*/
    IF done THEN
      LEAVE read_loop;
    END IF;

    CALL Proc_server_Sell_Supply_Count(VarMenuID, VarItemAmount, ParamShop);

    SELECT VarMenuID, VarItemAmount, VarItemSumm, VarItemPrice, VarItemCost, @VarErrorSupply;

    /* если произошла ошибка - откатываемся */
    IF @VarErrorSupply = TRUE THEN SIGNAL SQLSTATE '45000'; END IF;

    SELECT Bonus FROM menu WHERE ItemNo = VarMenuID INTO VarItemBonus;
    
    /* обновляем значения прибыли и кол-ва позиций */
    UPDATE menu
       SET menu.Amount = menu.Amount + VarItemAmount,
           menu.Profit = menu.Profit + (VarItemPrice - VarItemCost) * VarItemAmount
     WHERE ItemNo = VarMenuID;

    /* вычисление значений бонусов и себестоимости заказа */
    SET VarOrderCost = VarItemCost * VarItemAmount + VarOrderCost;
    SET VarOrderBonus = VarItemBonus * VarItemAmount + VarOrderBonus;

  END LOOP;
  CLOSE CheckCursor;

  UPDATE shops
    SET Profit = shops.Profit + ParamSumm - VarOrderCost
    WHERE ShopName = ParamShop; -- обновляем прибыль магазина

 UPDATE sales -- записываем в таблицу продаж
    SET Status = 'Открыт',       -- заменить
        User = ParamLogin,
        Summ = ParamSumm,
        Cost = VarOrderCost,
        Profit = Summ - VarOrderCost,
  --      Client = ClientPhone,
        Shop = Shop,
        Place = ParamPlace
  WHERE IndexNo = VarCheckNo;

    /* запись в лог */
    CALL Proc_Log_Update('Sell', ParamLogin, CONCAT('Закрыт счет #',VarCheckNo, ' на сумму ', ParamSumm,' ', ParamPlace), ParamShop);

  COMMIT;
END



Вторая, вызывается внутри первой
Код: sql
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.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
CREATE DEFINER = 'root'@'%'
PROCEDURE cafedb.Proc_Server_Sell_Supply_Count(IN ParamMenuID INTEGER, IN ParamItemAmount INTEGER, IN ParamShopName VARCHAR(255))
BEGIN

  DECLARE done int DEFAULT FALSE;

  DECLARE VarSupplyAmount,
          VarSupplyID,
          VarCount
          int(11);

  DECLARE Command,
          VarSupplyName
          text;

  DECLARE SuppliesCursor CURSOR FOR
      SELECT Supply, Amount, SupplyID
      FROM table_item_supplies
      WHERE ItemID = ParamMenuID;

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    ROLLBACK;
    SET @VarErrorSupply = TRUE;
    SELECT @VarErrorSupply;
  END;

  DECLARE EXIT HANDLER FOR SQLSTATE '45000'
    BEGIN
      ROLLBACK;
      SET @VarErrorSupply = TRUE;
      SELECT @VarErrorSupply;
    END;

  /* начало процедуры */
  START TRANSACTION;

  OPEN SuppliesCursor;

read_loop:
  LOOP
    /* берем значения переменных */
    FETCH SuppliesCursor INTO VarSupplyName, VarSupplyAmount, VarSupplyID;

    /*Выход из курсора*/
    IF done THEN
      LEAVE read_loop;
    END IF;

    /* Расчет расходки */

    /* Изменение кол-ва расходников на торговых точках */
    SET @Command = CONCAT('UPDATE supplies SET ', ParamShopName, ' = ', ParamShopName, ' - ', VarSupplyAmount * ParamItemAmount, ' WHERE IndexNo=', VarSupplyID);
    PREPARE Up FROM @Command;
    EXECUTE Up;
    DEALLOCATE PREPARE Up;

    /* Поиск записи расходки на дату */
    SELECT COUNT(*)
        FROM consumption
        WHERE Time = CURDATE()
        AND SupplyID = VarSupplyID
        AND Shop = ParamShopName
    INTO VarCount;

    IF VarCount = 0
    THEN
      INSERT INTO consumption (Time, SupplyID, Supply, Amount, Shop) 				/* если записи о расходе нет - добавить ее */
           VALUES (CURDATE(), VarSupplyID, VarSupplyName, VarSupplyAmount * ParamItemAmount, ParamShopName);
    ELSE
      UPDATE consumption 																/* если запись есть - обновлем */
      SET Amount = consumption.Amount + VarSupplyAmount * ParamItemAmount
      WHERE Time = CURDATE()
      AND SupplyID = VarSupplyID
      AND Shop = ParamShopName;
    END IF;

  -- пример вызова исключения
  IF ParamItemAmount = 3 THEN  SIGNAL SQLSTATE '45000'; END IF;
 
  END LOOP;
  CLOSE SuppliesCursor;

   SELECT @VarErrorSupply;

  COMMIT;

END



Извиняюсь за длиннопост, но как наглядней объяснить по-другому не знаю.
Подскажите что я забыл, из-за каких тонкостей алгоритм не работает и как это должно быть сделано.
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Проблема с хранимыми процедурами и параметрами
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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