Witam.
Mam do zrealizowania następujący problem:
wyciągnąć cenę kategorii z drzewa. Jeżeli kategoria ma przypisaną cenę - zwracamy ją, jeżeli nie ma (NULL), a ma przypisanego rodzica (NOT NULL), ściągamy cenę z rodzica. Jeżeli ten nie ma, pyta dziadka, itd, dopóki trafimy na cenę lub kategorię, która nie ma już rodzica.
Struktura danych:
CREATE TABLE `cms_announcements_categories` (
`category_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`category_title` text NOT NULL,
`category_parent` int(11) UNSIGNED DEFAULT NULL,
`category_data_price` float(6,2) DEFAULT NULL,
PRIMARY KEY (`category_id`),
KEY `category_parent` (`category_parent`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
ALTER TABLE `cms_announcements_categories`
ADD CONSTRAINT `cms_announcements_categories_ibfk_1` FOREIGN KEY (`category_parent`) REFERENCES `cms_announcements_categories` (`category_id`) ON DELETE CASCADE;
Próbowałem rozwiązać to w następujący sposób:
DROP FUNCTION IF EXISTS AnnouncementsCategoriesGetPrice;
DELIMITER //
CREATE FUNCTION AnnouncementsCategoriesGetPrice(iCategoryId INT(11)) RETURNS float(6,2)
BEGIN
DECLARE iResult float(6,2);
SELECT (
CASE
WHEN category_data_price IS NOT NULL THEN category_data_price
ELSE(
CASE
WHEN category_parent IS NOT NULL THEN AnnouncementsCategoriesGetPrice(category_parent)
ELSE NULL
END)
END
) INTO iResult FROM cms_announcements_categories WHERE category_id = iCategoryId;
RETURN iResult;
END//
DELIMITER ;
SELECT AnnouncementsCategoriesGetPrice(10);
Niestety, funkcje nie mogą być rekurencyjne.
Ugryzłem to od strony procedur, ale nie potrafię sobie z tym poradzić:
DROP PROCEDURE IF EXISTS AnnouncementsCategoriesGetPrice;
DELIMITER //
CREATE PROCEDURE AnnouncementsCategoriesGetPrice(IN iCategoryId INT(11), OUT iResult float(6,2))
BEGIN
DECLARE iResult float(6,2);
SELECT category_data_price INTO iResult FROM cms_announcements_categories WHERE category_id = iCategoryId;
IF (iResult IS NULL AND category_parent) THEN
CALL AnnouncementsCategoriesGetPrice(category_parent, iResult);
END IF;
END//
DELIMITER ;
CALL AnnouncementsCategoriesGetPrice(10, @result);
SELECT @result;
Jakby ktoś zechciał mi pomóc i pochylić się nad problemem, byłbym wdzięczny.
Pozdrawiam serdecznie,
Athlan.
EDIT: zrobiłem:
CREATE FUNCTION AnnouncementsCategoriesGetPrice(iCategoryId int(11)) RETURNS float(6,2)
BEGIN
DECLARE iResult FLOAT(6,2);
DECLARE iPointer INT(11);
SET iPointer = iCategoryId;
SET iResult = NULL;
WHILE (iPointer IS NOT NULL AND iPointer IS NOT NULL) DO
SET iResult = (SELECT category_data_price FROM cms_announcements_categories WHERE category_id = iPointer);
SET iPointer = (SELECT category_parent FROM cms_announcements_categories WHERE category_id = iPointer);
END WHILE;
RETURN iResult;
END