私はしばらくの間 Google で検索してきましたが、問題は、MySQL の CURSOR がどのように機能するかを明確に理解していないことだと確信しています。
問題の簡単な説明: 私はそのような関数を書いています (簡略化):
CREATE DEFINER=`me`@`localhost` FUNCTION `product_move`(prID INT, tr_type VARCHAR(2), clID INT, am INT, dnID INT, usrID INT, price FLOAT(10,2), ti DATETIME, barc TINYTEXT, cmt TINYTEXT, lnID INT)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE cur_id INT;
DECLARE net_pr FLOAT(10,2);
DECLARE cur_r INT;
DECLARE remaind INT DEFAULT 0;
DECLARE avg_price FLOAT(10,2) DEFAULT 0;
DECLARE curs CURSOR FOR SELECT `products_transactionsID`,
`price`,
`remains`
FROM `products_transactions`
WHERE `productID`=prID AND `remains`>0 AND `type`='V'
ORDER BY `products_transactionsID` ASC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN curs;
SET remaind=am;
read_loop:LOOP
FETCH curs INTO cur_id,net_pr,cur_r;
IF done THEN
LEAVE read_loop;
END IF;
IF (cur_r>=remaind) THEN
SET avg_price = avg_price + (net_pr * remaind);
UPDATE `products_transactions` SET `remains`=`remains`-remaind WHERE products_transactionsID=cur_id;
LEAVE read_loop;
ELSE
SET avg_price = avg_price + (net_pr * cur_r);
SET remaind=remaind-cur_r;
UPDATE `products_transactions` SET `remains`=0 WHERE products_transactionsID=cur_id;
END IF;
END LOOP;
CLOSE curs;
SET avg_price=avg_price/am;
INSERT INTO products_transactions
(`products_transactionsID`,`clientID`,`date_created`,`delivery_notesID`,`type`,`productID`,`amountIN`,`amountOUT`,`barcodes`,`in_stock`,`out_stock`,`out_repair`,`out_loss`,`booked`,`ordered`,`userID`,`price`,`comments`,`fifo_buy_price`)
SELECT NULL, clID, ti, dnID , tr_type, prID, 0, am, barc, products_transactions.in_stock-am, products_transactions.out_stock,
products_transactions.out_repair, products_transactions.out_loss, products_transactions.booked, products_transactions.ordered,usrID,price,cmt,avg_price
FROM
products_transactions WHERE productID=prID ORDER BY products_transactionsID DESC LIMIT 1;
そのため、以前に選択した行からのいくつかの計算に基づいて、このテーブルに新しい行を挿入し、その間にこれらの行を更新します。
問題は変数にあり、カーソルからフェッチさavg_price
れた変数に基づいて計算する必要があります。しかし、どういうわけか、変数はnet_pr
SELECT から FETCH されるのではなく、関数の入力パラメーターの値を取ります! そんなことがあるものか?net_pr
price
私の推測はこれまでのところ:
変数名の競合?コードを検索しましたが、見つかりません。
LOOP 内でテーブルを更新すると、CURSOR の位置が失われる可能性がありますか? それは理にかなっていますが、それはこれにもなりません...
どんなアイデアでも大歓迎です。