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