Munkám során egy problémába ütköztem, aminek több fórumon utánnanézve sem találtam meg a megoldását. Remélem ti tudtok segíteni.
Adott egy MySQL 5.0.27 szerver melyben a következők:
Egy tábla:
CREATE TABLE `parts` (
`main_item_id` int(5) unsigned NOT NULL,
`part_item_id` int(5) unsigned NOT NULL,
) ENGINE=InnoDB
Az összekapcsolás azt határozza meg, hogy a part_item_id része a main_item_id-nak.
A probléma az, hogy ellenőriznem kell hogy egy áru ne lehessen önmaga része. Azaz ha egy gráfként képzelem el, akkor ne lehessen benne kör.
Ezt mysql function-ként szerettem volna megírni, de mindig azt a hibaüzenetet kaptam, hogy nem lehet recursive store function-t írni. Ezen teljesen kiakadva megírtam procedure-ként. Azt viszont nem lehet betenni select where részébe. Próbáltam a function atver() { call procedure;} kombinációt is, de ugyan azt a hibát kaptam.
Utánnanéztem a 'store function' definíciónak is, de hiába próbálkoztam, nem tudtam anélkül megoldani. A procedure és a function kódját bemásolom, hátha van itt valaki aki nem az első ilyet írja, és tudna segíteni benne.
Még annyit, hogy szeretném használni select * from items where iscorrectparttable(item_id,item_parent_id) = 1; formában, vagy ehhez hasonlóan. Tehát, hogy le tudjam kérdezni azokat az elemeket amik lehetnek egy elem részei anélkül hogy kör lenne a gráfban.
Remélem érthető voltam. Nagyon próbálkoztam...
Tehát a függvények:
az eredeti procedure
MAIN_BLOCK: BEGIN
DECLARE nincstalalat INT DEFAULT 0;
DECLARE itemid SMALLINT(5);
DECLARE items CURSOR FOR SELECT part_item_id FROM item_parts WHERE main_item_id=root;
DECLARE bejar CURSOR FOR SELECT item FROM bejart WHERE item = root;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET nincstalalat=1;
IF level = 0 THEN
SET max_sp_recursion_depth=15;
DROP TABLE IF EXISTS bejart;
CREATE TABLE IF NOT EXISTS bejart(
item SMALLINT(5) PRIMARY KEY
) ENGINE=HEAP;
INSERT INTO bejart VALUES(parent);
END IF;
OPEN bejar;
FETCH bejar INTO itemid;
IF nincstalalat = 1 THEN
INSERT INTO bejart VALUES (root);
ELSE
SET result = 0;
LEAVE MAIN_BLOCK;
END IF;
CLOSE bejar;
SET nincstalalat=0;
OPEN items;
fetch_loop:
LOOP
FETCH items INTO itemid;
IF nincstalalat = 1 THEN
LEAVE fetch_loop;
ELSE
CALL isCorrectPartTable(itemid,level+1,parent,result);
if result = 0 then leave main_block; end if;
END IF;
END LOOP fetch_loop;
CLOSE items;
IF level = 0 THEN DROP TABLE bejart;
IF ISNULL(result) THEN set result = 1; end if;
END IF;
END MAIN_BLOCK$$
.
.
.
.
.
.
.
azt hittem, hogy sikerül majd nem store function-t írnom, de eddig nem sikerült
.
.
MAIN_BLOCK: BEGIN
DECLARE vantalalat BOOL;
DECLARE itemid SMALLINT(5);
DECLARE temp VARCHAR(255);
DECLARE items CURSOR FOR SELECT part_item_id FROM item_parts WHERE main_item_id=item;
DECLARE bejar CURSOR FOR SELECT bejart REGEXP CONCAT('.*,',item,',.*');
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vantalalat=0;
IF level = 0 THEN
SET max_sp_recursion_depth=15;
SET bejart=CONCAT(",",parent,",");
END IF;
SET vantalalat=1;
OPEN bejar;
FETCH bejar INTO vantalalat;
IF vantalalat = 0 THEN
SET bejart = CONCAT(bejart,item,',');
ELSE
RETURN '0';
END IF;
CLOSE bejar;
SET vantalalat=1;
OPEN items;
fetch_loop:
LOOP
FETCH items INTO itemid;
IF vantalalat = 0 THEN
LEAVE fetch_loop;
ELSE
SET temp = pina(item,itemid,level+1,bejart);
IF temp = '0' THEN
RETURN '0';
ELSE
SET bejart = temp;
END IF;
END IF;
END LOOP fetch_loop;
CLOSE items;
IF level = 0 THEN
RETURN '1';
ELSE RETURN bejart;
END IF;
END MAIN_BLOCK$$
- 1122 megtekintés